目录html
1 准备工做... 5node
1.1 相关网址... 6mysql
1.1 下载安装... 6git
1.1.1 下载:... 6sql
1.1.2 安装:... 7mongodb
1.2 其余工具... 17shell
1.2.1 robomongo. 17数据库
1.2.2 示例代码... 19windows
2 基础知识... 20数组
2.1 数据库... 20
2.2 集合... 20
2.2.1 固定集合:... 20
2.3 文档... 21
3 mongo Shell 22
4 CRUD操做... 26
4.1 插入并保存... 26
4.1.1 id 字段... 26
4.1.2 插入操做... 26
4.2 查询... 29
4.2.1 常规查询... 29
4.2.2 内嵌文档查询... 31
4.2.3 数组的查询... 32
4.3 更新... 34
4.4 删除... 34
5 索引... 34
5.1 执行计划:... 35
5.2 单索引... 37
5.3 复合索引... 38
5.4 $操做符如何使用索引... 39
5.4.1 低效率的操做符... 39
5.4.2 索引对象和数组... 39
5.4.3 索引基数... 40
5.5 什么时候不该该使用索引... 40
5.6 索引类型... 41
5.6.1 惟一索引... 41
5.6.2 稀疏索引... 41
5.6.3 全文索引... 42
6 聚合... 45
6.1 聚合框架... 45
6.1.1 $project操做... 46
6.1.2 $match. 47
6.1.3 $group. 47
6.1.4 $sort. 48
6.1.5 综合应用... 48
6.1.6 $unwind. 49
6.2 聚合命令... 50
6.2.1 count. 50
6.2.2 distinct. 50
7 GirdFS. 51
8 用户管理... 55
9 建立副本集... 55
9.1 MongoDB Atlas. 56
10 复制集(replication)... 63
10.1 搭建复制集... 63
10.1.1 直接命令启动... 63
10.1.2 配置文件启动... 76
10.1.3 配置复制集:... 88
10.1.4 安装为windows 服务 的集群... 99
10.2 复制集的验证... 113
10.2.1 数据同步... 113
10.2.2 主从故障切换... 119
10.3 复制集群工做原理... 125
11 分片(Sharding)... 126
11.1 什么是分片集群... 126
11.2 何时分片... 127
11.3 分片集群的组件... 127
11.4 分片集群中的数据分散方式... 130
11.4.1 数据库分片... 132
11.4.2 集合分片... 133
11.5 搭建分片集群... 135
11.5.1 启动 mongod 和 configserver. 135
11.5.2 配置复制集:... 140
11.5.3 启动 mongos. 152
11.5.4 配置分片集群... 154
11.5.5 对数据库和集合进行分片... 158
11.6 分片集群的查询和索引... 185
12 其它... 185
资源网址、下载安装、辅助工具
官网:
https://www.mongodb.com/
下载:
https://www.mongodb.com/download-center
驱动:
https://docs.mongodb.com/ecosystem/drivers/csharp/
中文社区:
http://www.mongoing.com/
1.1
https://www.mongodb.com/download-center
https://www.mongodb.com/download-center/community
下载总是让你注册帐号,有没登陆界面,点击左侧栏跳转到因此版本下载地址,以下图所示:
跳转到以下地址,选择要安装的版本:
https://www.mongodb.org/dl/win32/x86_64-2008plus-ssl?_ga=2.86137437.439937506.1541555987-1693515396.1540462101
安装文档:
https://docs.mongodb.com/manual/installation/
https://docs.mongodb.com/manual/tutorial/install-mongodb-enterprise-on-windows/
这里咱们选择使用 msi 安装,而且选择 安装为windows服务方式启动。
安装完成后,默认端口是27017
配置文件:
运行 mongod -remove 会删除名为“MongoDb”的windows服务,其它名字的MongoDb 的windows服务不会被删除
若是不当心 运行了 mongod --remove 删除了该windows 服务
可运行以下命名,从新安装
mongod --config "C:\Program Files\MongoDB\Server\4.0\bin\mongod.cfg" --install --serviceName "MongodDb" --serviceDisplayName "MongodDb Service" --serviceDescription "MongodDb Data Service"
删除 具体的 windows 服务 仍是在 cmd 界面中使用以下命令进行删除:
sc delete 服务名称
下载二进制文件:
https://www.mongodb.org/dl/win32/x86_64-2008plus-ssl?_ga=2.254700552.1864371647.1543196577-1693515396.1540462101
选择一个版本下载,好比:
win32/mongodb-win32-x86_64-2008plus-ssl-v4.0-latest.zip
解压到一个文件夹,这里是:
F:\mongodb\mongo-windowsserver\bin
在bin文件文件夹中添加配置文件:mongod.cfg,内容以下:
# mongod.conf
# for documentation of all options, see:
# http://docs.mongodb.org/manual/reference/configuration-options/
# Where and how to store data.
storage:
dbPath: F:\mongodb\mongo-windowsserver\data
journal:
enabled: true
# engine:
# mmapv1:
# wiredTiger:
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: F:\mongodb\mongo-windowsserver\log\mongod.log
# network interfaces
net:
port: 27050
bindIp: 127.0.0.1
#processManagement:
#security:
#authorization:enabled
#operationProfiling:
#replication:
#sharding:
## Enterprise-Only Options:
#auditLog:
#snmp:
打开cmd界面,
输入以下命令,以根据配置文件,将MongoDb安装为windows服务
mongod --config F:\mongodb\mongo-windowsserver\bin\mongod.cfg --install --serviceName "MongoDb-Service-27050" --serviceDisplayName "MongoDb-27050"
参数说明可经过输入 mongod -h 查看:
查看MongoDb window服务:
将其启动并设置启动方式为“自动”
查看日志文件:
下载地址:https://robomongo.org/download
链接MongoDb
git clone https://keasy5.visualstudio.com/MongoDb.JumpStart/_git/MongoDb.JumpStart
默认有三个数据库名的数据库:
集合就是一组文档,能够看做是一个拥有动态模式的表
建立一个固定集合,
db.createCollection("cappedColl", {"capped":true, "size":1024, max:5})
for(i=0; i<10; i++){
db. cappedColl.insert(
{
"i":i,
"username": "user" + i,
"age":Math.floor(Math.random() * 120),
"created":new Date()
}
);
}
db.getCollection('cappedColl').find({})
文档是MongoDB中数据的基本单元, 相似于关系型数据库中的行。
mongo shell 是MongoDB的客户端管理工具,能够在shell中使用命令与MongoDB的实例进行交互,对数据库的管理操做(CRUD,集群配置,状态查看等)。
设置系统环境变量:
PATH 环境变量追加:
C:\Program Files\MongoDB\Server\4.0\bin
mongo
简单使用经常使用命名:
l help
l 显示数据库: show dbs
l 切换为当前数据库:use testDb
l 显示当前数据库:db
l 显示数据库操做命令:db.help()
l 显示数据库集合:show collections
l 查询集合:
db.getCollection('User').find({})
db.getCollection('User').find()
db.User.find()
db. User.find({"Name":{"$all":["Kevin"]}}).pretty();
l 插入数据:
插入一条:db.User.insertOne({"Name": "Test1"})
db.User.insertOne({"Name": "Test2", "Age": 10})
插入多条:
db.User.insertMany([{"Name": "Test3"},{"Name":"Test4"}, {"Name":"Test5","Age":25}])
l 查找:
插入一条: db.User.find({"Name":"Test01"})
l 更新
db.collection.updateOne(<filter>, <update>, <options>)
db.collection.updateMany(<filter>, <update>, <options>)
db.collection.replaceOne(<filter>, <update>, <options>)
更新一条
db.User.updateOne({"Name":"Test2"},{$set:{Name:"Test2-2"});
更新多条:
db.User.insertOne({"Name": "Test6", "Age": 28})
db.User.find({Age: {$gte:25}}).pretty()
更新多条而且知足年龄大于20:
db.User.updateMany({"Age":{$gte:25}}, {$set:{"Age":29}})
db.User.find ({"Age":{$gte:29}})
db.User.updateOne({"Age":{$gte:29}}, {$set:{"Age":30}})
l 删除
db.collection.deleteMany()
db.collection.deleteOne()
db.User.deleteOne ({"Age":{$gte:29}})
db.User.deleteMany ({"Age":{$gte:29}})
db.collection.insertOne()
db.collection.insertMany()
db.collection.insert()
在MongoDB中,存储于集合中的每个文档都须要一个惟一的 _id 字段做为 primary_key。若是一个插入文档操做遗漏了``_id`` 字段,MongoDB驱动会自动为``_id``字段生成一个 ObjectId。
db.users.insertOne(
{
name: "sue",
age: 19,
status: "P"
}
)
db.users.insertMany(
[
{ name: "bob", age: 42, status: "A", },
{ name: "ahn", age: 22, status: "A", },
{ name: "xi", age: 34, status: "D", }
]
)
db.users.insert(
{
name: "sue2",
age: 19,
status: "P"
})
db.users.insertMany(
[
{ name: "bob2", age: 42, status: "A", },
{ name: "ahn2", age: 22, status: "A", },
{ name: "xi2", age: 34, status: "D", }
]
)
示例演示:
数据:
db.inventory.insertMany([
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }
]);
查询说明 |
Mongo shell命令 |
C# |
查询全部
|
db.inventory.find( {} )
|
|
查询status="D"
|
db.inventory.find( { status: "D" } )
|
var filter = Builders<BsonDocument>.Filter.Eq("status", "D"); var result = collection.Find(filter).ToList();
|
查询status="A" or status="D"
|
db.inventory.find( { status: { $in: [ "A", "D" ] } } ) |
var filter = Builders<BsonDocument>.Filter.In("status", new[] { "A", "D" }); var result = collection.Find(filter).ToList(); |
status = "A" AND qty < 30
|
db.inventory.find( { status:"A", qty:{$lt:30} } ) |
var builder = Builders<BsonDocument>.Filter; var filter = builder.And(builder.Eq("status", "A"), builder.Lt("qty", 30)); var result = collection.Find(filter).ToList(); |
status = "A" OR qty < 30
|
db.inventory.find( { $or:[ {status:"A"}, {qty:{$lt:30}} ] })
|
var builder = Builders<BsonDocument>.Filter; var filter = builder.Or(builder.Eq("status", "A"), builder.Lt("qty", 30)); var result = collection.Find(filter).ToList(); |
status = "A" AND ( qty < 30 OR item LIKE "p%")
|
db.inventory.find( { status:"A", $or:[ {qty:{$lt:30}}, {item: /^p/} ] } ) |
var builder = Builders<BsonDocument>.Filter; var filter = builder.And( builder.Eq("status", "A"), builder.Or(builder.Lt("qty", 30), builder.Regex("item", new BsonRegularExpression("^p")))); var result = collection.Find(filter).ToList(); |
|
|
|
注意:
操做符:
https://docs.mongodb.com/manual/reference/operator/query/
查询说明 |
Mongo shell命令 |
C# |
内嵌对象精确查询 |
db.inventory.find( { size: { h: 14, w: 21, uom: "cm" } } ) |
var filter = Builders<BsonDocument>.Filter.Eq("size", new BsonDocument { { "h", 14 }, { "w", 21 }, { "uom", "cm" } }); var result = collection.Find(filter).ToList(); |
查询 |
db.inventory.find({ "size.uom":"in" })
|
var filter = Builders<BsonDocument>.Filter.Eq("size.uom", "in"); var result = collection.Find(filter).ToList(); |
size.h < 5
|
db.inventory.find( { "size.h":{$lt:15} } ) |
var filter = Builders<BsonDocument>.Filter.Lt("size.h", 15); var result = collection.Find(filter).ToList(); |
the nested field h is less than 15, the nested field uom equals "in", and the status field equals "D" |
db.inventory.find( { "size.h":{$lt:15}, "size.uom":"in", "status":"D" } ) |
var builder = Builders<BsonDocument>.Filter; var filter = builder.And(builder.Lt("size.h", 15), builder.Eq("size.uom", "in"), builder.Eq("status", "D")); var result = collection.Find(filter).ToList(); |
|
|
|
|
|
|
|
|
|
演示数据
db.inventory.insertMany([
{ item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] },
{ item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] },
{ item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] },
{ item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] },
{ item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] }
]);
查询说明 |
Mongo shell命令 |
C# |
where the field tags value is an array with exactly two elements, "red" and "blank", in the specified order:
等于
|
db.getCollection('inventory').find( {tags:["red", "blank"]} ) |
var filter = Builders<BsonDocument>.Filter.Eq("tags", new[] { "red", "blank" }); var result = collection.Find(filter).ToList(); |
find an array that contains both the elements "red" and "blank"
都包含
|
db.getCollection('inventory').find( {tags: {$all: ["red", "blank"]}} )
等同于
db.articles.find( { $and: [ { tags: [ "ssl", "security" ] } ] } )
|
var filter = Builders<BsonDocument>.Filter.All("tags", new[] { "red", "blank" }); var result = collection.Find(filter).ToList(); |
数组中 存在 15<dim_cm <20 的数组元素 排除了元素:
|
db.inventory.find( { dim_cm: { $gt: 15, $lt: 20 } } ) |
var builder = Builders<BsonDocument>.Filter; var filter = builder.And(builder.Gt("dim_cm", 15), builder.Lt("dim_cm", 20)); var result = collection.Find(filter).ToList();
|
|
|
|
|
|
|
|
|
|
|
|
|
for(i=0; i<1000; i++){
db.users.insert(
{
"i":i,
"username": "user" + i,
"age":Math.floor(Math.random() * 120),
"created":new Date()
}
);
}
https://blog.csdn.net/u012702547/article/details/80606614
http://www.mongoing.com/eshu_explain1
http://blog.51cto.com/1937519/2301699?source=dra
执行计划分析:
执行计划的三种模式:
queryPlanner :默认
executionStats :会返回最佳执行计划的一些统计信息
allPlansExecution :用来获取全部执行计划
queryPlanner返回值说明:
参数 |
含义 |
plannerVersion |
查询计划版本 |
namespace |
要查询的集合 |
indexFilterSet |
是否使用索引 |
parsedQuery |
查询条件, |
winningPlan |
最佳执行计划 |
stage |
查询方式,常见的有COLLSCAN/全表扫描、IXSCAN/索引扫描、FETCH/根据索引去检索文档、SHARD_MERGE/合并分片结果、IDHACK/针对_id进行查询 |
filter |
过滤条件 |
direction |
搜索方向 |
rejectedPlans |
拒绝的执行计划 |
serverInfo |
MongoDB服务器信息 |
executionStats 返回值说明:
参数 |
含义 |
plannerVersion |
查询计划版本 |
namespace |
要查询的集合 |
indexFilterSet |
是否使用索引 |
parsedQuery |
查询条件, |
winningPlan |
最佳执行计划 |
stage |
查询方式,常见的有COLLSCAN/全表扫描、IXSCAN/索引扫描、FETCH/根据索引去检索文档、SHARD_MERGE/合并分片结果、IDHACK/针对_id进行查询 |
filter |
过滤条件 |
direction |
搜索方向 |
rejectedPlans |
拒绝的执行计划 |
serverInfo |
MongoDB服务器信息 |
executionStats参数,含义以下:
参数 |
含义 |
executionSuccess |
是否执行成功 |
nReturned |
返回的结果数 |
executionTimeMillis |
执行耗时 |
totalKeysExamined |
索引扫描次数 |
totalDocsExamined |
文档扫描次数 |
executionStages |
这个分类下描述执行的状态 |
stage |
扫描方式,具体可选值与上文的相同 |
nReturned |
查询结果数量 |
executionTimeMillisEstimate |
预估耗时 |
works |
工做单元数,一个查询会分解成小的工做单元 |
advanced |
优先返回的结果数 |
docsExamined |
文档检查数目,与totalDocsExamined一致 |
建立索引:
db.users.createIndex({username:1})
db.getCollection('users').find({username:"user2500000"}).hint({$natural: 1}).explain()
db.getCollection('users').find({username:"user2500000"}).explain("queryPlanner")
db.getCollection('users').find({username:"user2500000"}).explain("executionStats")
db.getCollection('users').find({username:"user2500000"}).explain("allPlansExecution")
db.getCollection('users').find({username:"user2500000"}).sort({"username":-1}).explain("executionStats")
db.users.createIndex({"age":1,"username":1})
db.users.find({"age":{"$gte":21, "$lte":30}}).sort({"username":1}).limit(10000).explain("executionStats")
db.getCollection('users').find({"age":{"$gte":100}}).count(100)
db.getCollection('users').find({"age":{"$gte":100}}).limit(100).explain("executionStats")
db.getCollection('users').find({"age":{"$gte":100}}).skip(10000000).limit(20).explain("executionStats")
db.getCollection('users').find({"age":{"$gte":100}}).sort({"created":-1}).skip(10000000).limit(20).explain("executionStats")
相互反转(在每一个方向都乘以 -1)的索引都等价的:
{"age":1 , "username": -1} 等价于 {"age":-1 , "username": 1}
索引{"age":1 , "username": 1}能够当作索引{"age":1}使用
{"indexKey ":{"$exists":true}}
$ne
$not
$nin 老是使用全表扫描
2. 范围
3. OR 查询
其实是执行两次查询,而后结果集合并, 能同时使用两个索引,
db.users.find({"$or":[{"age":100}, {"$gt":"user5", "$lt":"user8"}]}).explain("executionStats")
db.collection.createIndex("a.b": 1)
起做用:
db.collection.find({"a":{"b":xx}})
不起做用:
db.collection.find("a.b":"xxx")
db.collection.createIndex("a.arrData": 1)
3. 多建索引
对于某个索引的键,若是这个键在某个文档中是一个数组,那么这个索引就会标记为多键索引。
被标记为多键索引,就没法变成非多键索引。非法删除这个字段为数组的全部文档而且重建索引
多键索引可能会比非多键索引满,而且多个索引条目指向同一个文档,返回结果必须去重操做
集合中某个字段拥有不一样值的数量。
一个字段的基数越高,这个键的索引就越有用
在基数高的键上创建索引。
把基数高的键放在复合索引的前面
结果集在原集合中所占的比例越大,索引的速度就越慢。
由于使用索引须要进行两次查找:一次是查找索引条目,一次是根据索引指针去查找相应的文档。
通常来讲, 若是查询返回的集合内30%的文档(或者更多),那就应该对索引和全表扫描的速度进行比较
好比比较熟悉的“_id”索引。
该索引建重复,插入会抛出异常
db.user2.createIndex({"username":1},{"unique":true})
惟一索引把null看作值,没法将多个缺乏惟一索引中的键的文档插入集合。
稀疏索引,惟一索引知对包含相应的键的文档生效。当一个字段存在时,它必须是惟一的。
惟一稀疏索引:
db.user2.createIndex("{"age":1}",{"unique":true, "sparse":true})
非惟一稀疏索引
db.user2.createIndex("{"age":1}",{ "sparse":true})
若是某个文档不包含 age字段,使用稀疏索引不会返回该文档
https://docs.mongodb.com/manual/tutorial/text-search-in-aggregation/
如同内置了多语言分词机制
在一个操做频繁的集合上建立全文本检索可能回到致使MongoDB过载,应该是离线状态下建立全文检索。
建立全文检索可能会致使内存不够用。
测试数据:
db.textIndexTest.insert({author:"杜甫",title:"绝句",article:"两个黄鹂鸣翠柳, 一行白鹭上青天。窗含西岭千秋雪,门泊东吴万里船。"})
db.textIndexTest.insert({author:"李白",title:"静夜思",article:"床前明月光,疑是地上霜。 举头望明月,低头思故乡。"})
db.textIndexTest.insert({author:"张 王",title:"你好",article:"测试数据"})
db.textIndexTest.insert({author:"李贺",title:"李凭箜篌引",article:"吴丝蜀桐张高秋,空山凝云颓不流。 江娥啼竹素女愁,李凭中国弹箜篌。 昆山玉碎凤凰叫,芙蓉泣露香兰笑。 十二门前融冷光,二十三丝动紫皇。 女娲炼石补天处,石破天惊逗秋雨。 梦入神山教神妪,老鱼跳波瘦蛟舞。 吴质不眠倚桂树,露脚斜飞湿寒兔。"})
建立全文检索:
db.textIndexTest.createIndex( { author: "text", description: "text" } )
db.textIndexTest.find({$text:{$search:"杜甫"}})
db.textIndexTest.find({$text:{"$search":"空山凝云颓不流"}})
db.textIndexTest.dropIndex("author_text_description_text");
db.textIndexTest.createIndex( { author: "text", article: "text" } )
db.textIndexTest.find({$text:{"$search":"空山凝云颓"}}) #无结果
db.textIndexTest.find({$text:{"$search":"空山凝云颓不流"}})
db.textIndexTest.find({$text:{$search:"王"}})
MongoDB中文全文索引创建方式与英文的简历几乎相同 是根据词(英文单词)的方式创建的。
若是一个值里面有多个值 则须要按空格方式隔开,”张 王” 系统则认为是两个词。
感受MongodB的中文全文索引沒有想象中的强大。想要实现中文模糊搜素
能够用elasticsearch或者Sphinx,或者lucene
设置语言:
https://docs.mongodb.com/manual/reference/text-search-languages/#text-search-languages
db.articles.find(
{ $text: { $search: "leche", $language: "es" } }
)
一个集合只能建立一个全文索引
db.articles.createIndex( { subject: "text" } )
db.articles.insert(
[
{ _id: 1, subject: "coffee", author: "xyz", views: 50 },
{ _id: 2, subject: "Coffee Shopping", author: "efg", views: 5 },
{ _id: 3, subject: "Baking a cake", author: "abc", views: 90 },
{ _id: 4, subject: "baking", author: "xyz", views: 100 },
{ _id: 5, subject: "Café Con Leche", author: "abc", views: 200 },
{ _id: 6, subject: "Сырники", author: "jkl", views: 80 },
{ _id: 7, subject: "coffee and cream", author: "efg", views: 10 },
{ _id: 8, subject: "Cafe con Leche", author: "xyz", views: 10 }
]
)
db.articles.find( { $text: { $search: "coffee" } } )
# the phrase coffee shop
db.articles.find( { $text: { $search: "\"coffee shop\"" } } )
#contain the words coffee but do not contain the term shop
db.articles.find( { $text: { $search: "coffee -shop" } } )
db.articles.find( { $text: { $search: "coffee" } } ).explain("executionStats")
db.articles.createIndex({author:"text"})
db.articles.dropIndex("subject_text")
db.articles.createIndex({author:"text"})
db.articles.find( { $text: { $search: "coffee" } } )
db.articles.find( { $text: { $search: "xyz" } } )
for(i=0; i<1000; i++){
db.users2.insert(
{
"i":i,
"username": "user" + i,
"age":Math.floor(Math.random() * 120),
"created":new Date()
}
);
}
利用$project 实现投影操做,至关于SQL中的 Select 子句
db.users2.aggregate([
{"$project":{
"username":1
}
}
])
db.users2.aggregate([
{"$project":{
"_id":0,
"username":1
}
}
])
db.users2.aggregate([
{"$project":{
"username":1,
"age":1 ,
"是否大于93": {"$gt":["$age",93]}
}
}
])
db.users2.aggregate([
{"$match":{"age": {"$gt":93} }
}
])
分组操做, 至关于SQL 中的 Group By 子句
db.users2.aggregate([{
"$group":{
"_id":"$age",
"age_count":{"$sum":1}
}
}
]) .explain("executionStats")
排序操做
db.users2.aggregate([
{"$project":{
"username":1,
"age":1 }
}, {
"$sort":{"age" : -1, "username":1}
}
])
db.users2.aggregate([
{"$match":{"age":{"$gte":93, "$lte":115}}},
{"$project":{
"username":1,
"age":1
}
},
{"$group":{
"_id":"$age",
"age_count":{"$sum":1},
"usersData":{"$push":"$username"}
}
},
{
"$sort":{"age_count" : -1}
},
{"$skip":10},
{"$limit":10}
])
将数组中的每个值拆分为单独的文档
db.depts.insert({"name":"移动产品部", "bussiness":["研发", "开发", "维护"]})
db.depts.insert({"name":"财务部", "bussiness":["发工资", "财务预算"]})
db.depts.find({})
db.depts.aggregate([
{"$unwind":"$bussiness"}
])
db.depts.aggregate([
{"$unwind":"$bussiness"},
{"$match":{"bussiness": "发工资"}}
])
db.users.count()
db.users.count({"age":100})
db.runCommand({
"distinct":"users2",
"key":"age"
})
MongoDB里面支持大数据的存储,例如:图片,音乐,二进制数据,须要用户本身处理:
使用 mongofiles , 有三个基本操做;
put :将文件上传到GridFS
list: 列出GridFS中的文件
get:下载
命名
exit -- 退出mongo命名
mongofiles --help
在文件所在的文件夹中执行:
mongofiles put moon.png
上传
mongofiles put
查询
use test
show collections
db.fs.files.find().pretty()
文档分片存储
db.fs.chunks.find({}, {"_id":1, "n":1,"files_id":1}).pretty()
下载:
mongofiles get moon.png
删除
mongofiles delete moon.png
mongofiles list
https://docs.mongodb.com/manual/reference/built-in-roles/#built-in-roles
使用复制,将数据副本保存到多台服务器上。
副本集是一组服务器,其中有一个主服务器(Primary),用于处理 客户端请求,
多个备份服务器(secondary),用于保存主服务器的数据副本
主服务器崩溃,备份服务器会自动将其中一个成员升级为新的主服务器
https://docs.mongodb.com/manual/replication/
配置文件:
https://docs.mongodb.com/manual/reference/configuration-file-settings-command-line-options-mapping/#conf-file-command-line-mapping
https://blog.csdn.net/yamadeee/article/details/79746154
注册
登陆
https://docs.atlas.mongodb.com/
正在建立集群
参考:
https://blog.csdn.net/huanyuminhao/article/details/82052107
mongod --replSet mg-cluster0 --dbpath F:\mongodb\cluster0\node1 --port 27100
mongod --replSet mg-cluster0 --dbpath F:\mongodb\cluster0\node2 --port 27101
mongod --replSet mg-cluster0 --dbpath F:\mongodb\cluster0\node3 --port 27102
集群名称:mg-cluster0
新打开一个cmd界面,输入
mongo --port 27100
rs.initiate()
查看配置
rs.conf()
向主节点添加从节点和仲裁节点
rs.add("localhost:27101")
rs.addArb("localhost:27102")
查看主节点状态(详细信息)
rs.status()
获取复制集的简要信息:
db.isMaster()
配置文件说明;
https://docs.mongodb.com/manual/reference/configuration-options/
replication Options:
https://docs.mongodb.com/manual/reference/configuration-options/#replication-options
示例集群:mg-cluster1
建立3个数据库文件
在F:\mongodb\cluster1\node1 添加配置文件 mongod.cfg :
# mongod.conf
# for documentation of all options, see:
# http://docs.mongodb.org/manual/reference/configuration-options/
# Where and how to store data.
storage:
dbPath: F:\mongodb\cluster1\data\node1
journal:
enabled: true
# engine:
# mmapv1:
# wiredTiger:
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: F:\mongodb\cluster1\log\node1.log
# network interfaces
net:
port: 27201
bindIp: 127.0.0.1
#processManagement:
#security:
#authorization:enabled
#operationProfiling:
replication:
#oplogSizeMB: <int>
replSetName: mg-cluster1
#secondaryIndexPrefetch: <string>
#enableMajorityReadConcern: <boolean>
#sharding:
## Enterprise-Only Options:
#auditLog:
#snmp:logappend=true
在F:\mongodb\cluster1\node2 添加配置文件 mongod.cfg :
# mongod.conf
# for documentation of all options, see:
# http://docs.mongodb.org/manual/reference/configuration-options/
# Where and how to store data.
storage:
dbPath: F:\mongodb\cluster1\data\node1
journal:
enabled: true
# engine:
# mmapv1:
# wiredTiger:
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: F:\mongodb\cluster1\log\node1.log
# network interfaces
net:
port: 27201
bindIp: 127.0.0.1
#processManagement:
#security:
#authorization:enabled
#operationProfiling:
replication:
#oplogSizeMB: <int>
replSetName: mg-cluster1
#secondaryIndexPrefetch: <string>
#enableMajorityReadConcern: <boolean>
#sharding:
## Enterprise-Only Options:
#auditLog:
#snmp:
在F:\mongodb\cluster1\node3 添加配置文件 mongod.cfg :
# mongod.conf
# for documentation of all options, see:
# http://docs.mongodb.org/manual/reference/configuration-options/
# Where and how to store data.
storage:
dbPath: F:\mongodb\cluster1\data\node1
journal:
enabled: true
# engine:
# mmapv1:
# wiredTiger:
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: F:\mongodb\cluster1\log\node1.log
# network interfaces
net:
port: 27201
bindIp: 127.0.0.1
#processManagement:
#security:
#authorization:enabled
#operationProfiling:
replication:
#oplogSizeMB: <int>
replSetName: mg-cluster1
#secondaryIndexPrefetch: <string>
#enableMajorityReadConcern: <boolean>
#sharding:
## Enterprise-Only Options:
#auditLog:
#snmp:
分别启动:
mongod --config F:\mongodb\cluster1\node1\bin\mongod.cfg
mongod --config F:\mongodb\cluster1\node2\bin\mongod.cfg
mongod --config F:\mongodb\cluster1\node3\bin\mongod.cfg
测试是否连接成功:
mongo --port 27201
特别注意:
以下图启动服务失败,是由于没有建立相应的文件夹(配置文件中的数据文件夹和日志文件),
请手动建立以下文件夹:
data
data\node1 、data\node2 data\node3
log
启动成功后,数据文件和日志文件建立成功
新打开一个cmd 界面:
链接到27201 节点
mongo --port 27201
rs.status()
rs.initiate()
再此查看状态:
rs.status()
查看配置
rs.conf()
向主节点添加从节点
rs.add("localhost:27202")
向主节点添加仲裁节点
rs.addArb("localhost:27203")
再此查看状态:
rs.status()
具体如何手动安装为windows 服务 参见章节:手动安装安装为Windows Service
mongod --config "F:\mongodb\cluster-service\node1\bin\mongod.cfg" --install --serviceName "MongoDbService-Cluster-01" --serviceDisplayName "MongoDb-Cluster-01"
mongod --config "F:\mongodb\cluster-service\node2\bin\mongod.cfg" --install --serviceName "MongoDbService-Cluster-02" --serviceDisplayName "MongoDb-Cluster-02"
mongod --config "F:\mongodb\cluster-service\node3\bin\mongod.cfg" --install --serviceName "MongoDbService-Cluster-03" --serviceDisplayName "MongoDb-Cluster-03"
安装完成,日志以下:
2018-11-28T10:02:16.147+0800 I CONTROL [main] Trying to install Windows service 'MongoDbService-Cluster-01'
2018-11-28T10:02:16.621+0800 I CONTROL [main] Service 'MongoDbService-Cluster-01' (MongoDb-Cluster-01) installed with command line 'F:\mongodb\cluster-service\node1\bin\mongod.exe --config F:\mongodb\cluster-service\node1\bin\mongod.cfg --service'
2018-11-28T10:02:16.621+0800 I CONTROL [main] Service can be started from the command line with 'net start MongoDbService-Cluster-01'
生成数据相关文件:
分别手动启动这个三个windows 服务
复制集 的配置 如上章节: 配置复制集:
打开 cmd
mongo "127.0.0.1:27301"
查看状态 rs.status()
初始化集群
rs.initiate()
再此查看状态:
rs.status()
查看配置
rs.conf()
向主节点添加从节点
rs.add("127.0.0.1:27302")
向主节点添加仲裁节点
rs.addArb("127.0.0.1:27303")
再此查看状态:
rs.status()
简单的验证配置是否成功:
在 27301 的服务上执行:
use test
db.createCollection("testCollection")
db.testCollection.insert({"name":"test_insert_node1"})
db.testCollection.find()
主节点:负责数据的读写操做,
从节点:只负责读取。
仲裁节点:不负责数据的存储。
验证方法,
向主节点插入一个集合,
观察从节点和仲裁节点是否存在 向主节点插入的集合。
在主节点数据库命令窗口执行如下命令
执行前:
use test
db.createCollection("testCollection")
执行后:
主节点(27100)和从节点(27101)都会增长一个新的数据库test和新的集合testCollection
默认状况下,MongoDB会阻止对从节点的查询
mongo --port 27101
rs.slaveOk(1) 设置从节点容许读取操做
关闭主节点:
use admin
db.shutdownServer()
从节点(27101)上查看:
mongo --port 27101
rs.status()
27101 变成了主节点
db.testCollection.insert({"name":"mytest-New27101"})
在27101中插入新的数据
db.testCollection.insert({"name":"mytest-New27101"})
从新启动27100:
mongod --replSet mg-cluster0 --dbpath F:\mongodb\cluster0\node1 --port 27100
在27100 查询
rs.status()
27100被当作从节点,而且在其被关闭的时候,27101新插入的数据,被同步到了27100节点上
db.testCollection.find()
复制集依赖两个基本机制: oplog 和 hearbeat
oplog 容许复制数据
hearbeat监控状态并触发灾备
mongodb的扩展方式---分片,若是业务数据和系统负载不断增长,能够经过分片来解决。
分片就是指将数据拆分,分散到不一样的服务器上,从而处理更大的负载,存储大数据。
当数据增大到必定程度时,查询数据会变的很慢,难以忍受的地步,严重影响用户体验。每每就会根据业务对大表大数据库进行分表分库操做,人为的按照某种协定好的策略将若干不一样的数据存储到不一样的数据库服务器上,应用程序管理不一样服务器上的不一样数据,每台服务器上的链接都是彻底独立的。在我曾经工做过的地方,mysql分表分库大量应用,好比将论坛附件表根据uid拆分红10个表00-09,取模10,也就是取uid最后两位;将post_000到post_014存在db1服务器上,将post_015到post_029存在db2服务器上,如此类推。这种分表分库能够很好的工做,弊端就是很是难以维护,调整数据分布和服务器负载,添加或减除节点很是困难,变一处而动全身。
mongodb支持自动分片,集群自动的切分数据,作负载均衡。避免上面的分片管理难度。
mongodb分片是将集合切合成小块,分散到若干片里面,每一个片负责全部数据的一部分。这些块对应用程序来讲是透明的,不须要知道哪些数据分布到哪些片上,甚至不在意是否有作过度片,应用程序链接mongos进程,mongos知道数据和片的对应关系,将客户端请求转发到正确的片上,若是请求有了响应,mongos将结果收集起来返回给客户端程序。
分片适用场景:
1. 服务器磁盘不够用
2. 单个mongod不能知足日益频繁写请求
3. 将大量数据存放于内存中提升性能
分片集群由 分片、 mongos路由器、configServer配置服务器组成
① 配置服务器。是一个独立的mongod进程,保存集群和分片的元数据,即各分片包含了哪些数据的信息。最早开始创建,启用日志功能。像启动普通的mongod同样启动配置服务器,指定configsvr选项。不须要太多的空间和资源,配置服务器的1KB空间至关于真是数据的200MB。保存的只是数据的分布表。当服务不可用,则变成只读,没法分块、迁移数据。
② 路由服务器。即mongos,起到一个路由的功能,供程序链接。自己不保存数据,在启动时从配置服务器加载集群信息,开启mongos进程须要知道配置服务器的地址,指定configdb选项。
③ 分片服务器。是一个独立普通的mongod进程,保存数据信息。能够是一个副本集也能够是单独的一台服务器。
三台服务器:
172.21.4.104
172.21.4.31
172.21.4.103
在172.21.4.104 上安装:
实例 |
配置 |
说明 |
monogs |
172.21.4.104:40000 |
monogs |
configsvr |
172.21.4.104:28018 |
复制集-configsvr |
shard-a |
172.21.4.104:30000 |
复制集-a-Primay |
shard-b |
172.21.4.104:30103 |
复制集-b-Abr |
配置文件:
shard-a:
shard-b:
configsvr:
1.shard-a:
mongod --config "D:\mongodb\shard-a\bin\mongod.cfg" --install --serviceName "MongoDb-Cluster-Shard-a" --serviceDisplayName "MongoDb-Cluster-Shard-a"
2.shard-b:
mongod --config "D:\mongodb\shard-b\bin\mongod.cfg" --install --serviceName "MongoDb-Cluster-Shard-b" --serviceDisplayName "MongoDb-Cluster-Shard-b"
3.configsvr
mongod --config "D:\mongodb\configsvr\bin\mongod.cfg" --install --serviceName "MongoDb-Cluster-Configsvr" --serviceDisplayName "MongoDb-Cluster-Configsvr"
在172.21.4.31 上安装:
实例 |
配置 |
说明 |
monogs |
172.21.4.31:40000 |
monogs |
configsvr |
172.21.4.31:28018 |
复制集-configsvr |
shard-a |
172.21.4.31:30002 |
复制集-a-Abr |
shard-b |
172.21.4.31:30101 |
复制集-b-Primary |
在172.21.4.103 上安装:
实例 |
配置 |
说明 |
monogs |
172.21.4.103:40000 |
monogs |
configsvr |
172.21.4.103:28018 |
复制集-configsvr |
shard-a |
172.21.4.103:30001 |
复制集-a-Secondary |
shard-b |
172.21.4.103:30102 |
复制集-b- Secondary |
配置复制集a:
mongo --host 172.21.4.104 --port 30000
rs.initiate()
rs.add("172.21.4.103:30001")
rs.addArb("172.21.4.31:30002")
rs.status()
1. STARTUP:刚加入到复制集中,配置还未加载
2. STARTUP2:配置已加载完,初始化状态
3. RECOVERING:正在恢复,不适用读
4. ARBITER: 仲裁者
5. DOWN:节点不可到达
6. UNKNOWN:未获取其余节点状态而不知是什么状态,通常发生在只有两个成员的架构,脑裂
7. REMOVED:移除复制集
8. ROLLBACK:数据回滚,在回滚结束时,转移到RECOVERING或SECONDARY状态
9. FATAL:出错。查看日志grep “replSet FATAL”找出错缘由,从新作同步
10. PRIMARY:主节点
11. SECONDARY:备份节点
配置集群Shard-b:
mongo --host 172.21.4.31 --port 30101
rs.initiate()
rs.add("172.21.4.103:30102")
rs.addArb("172.21.4.104:30103")
rs.status()
或者
rs.initiate({
"_id": "cluster-shard-b",
"members": [
{
"_id": 1,
"host": "172.21.4.31:30101",
"priority": 1
},
{
"_id": 2,
"host": "172.21.4.103:30102",
"priority": 1
},
{
"_id": 2,
"host": "172.21.4.104:30103",
"priority": 0,
"arbiteOnly'": true
}
]
})
配置configServer复制集:
mongo "172.21.4.103:28018"
rs.initiate()
rs.add("172.21.4.104:28018")
rs.add("172.21.4.31:28018")
配置文件:
systemLog:
destination: file
logAppend: true
path: D:\mongodb\mongos\log\mongos.log
net:
port: 40000
bindIp: 172.21.4.103
sharding:
configDB: cluster-shard-confisvr/172.21.4.103:28018,172.21.4.104:28018,172.21.4.31:28018
启动为windows 服务:
mongos --config "D:\mongodb\mongos\bin\mongod.cfg" --install --serviceName "MongoDb-Cluster-Mongos" --serviceDisplayName "MongoDb-Cluster-Mongos"
日志:
链接mongos:
mongo --host 172.21.4.103 --port 40000
添加分片shard-a:
sh.addShard("cluster-shard-a/172.21.4.104:30000,172.21.4.103:30001")
添加分片shard-b:
sh.addShard("cluster-shard-b/172.21.4.31:30101,172.21.4.103:30102")
mongos 的config 数据库
查看分片状态:
sh.status()
演示示例1 (暂时没完成, 直接看演示示例2)
给数据库cloud-docs 启动分片:
sh.enableSharding("cloud-docs")
use config
db.databases.find().pretty()
集合分片:
sh.shardCollection("cloud-docs.spreadsheets", {username: 1, _id:1})
use config
db.collections.find().pretty()
建立数据库和集合:
链接 mongo --host 172.21.4.103 --port 30000
use cloud-docs
db.spreadsheets.insert({
"filename":"sheet-1",
"updated_at":new Date(),
"username":"banks",
data: "RAw Data"
});
插入数据成功后,
在每一个分片上,cloud-docs.spreadsheets 集合自动建立 与 片键对应的索引。
mongo --host 172.21.4.103 --port 30000
use cloud-docs
db.spreadsheets.getIndexes()
分片的状态;
mongos>sh.status()
批量插入数据:
检查分片
use config
db.chunks.count()
演示示例2:
链接mongs,
user shard-test
批量插入数据:
for(i=0; i<100000; i++){
db.collection1.insert({"username": "user"+i, "createtime":new Date()})
}
让数据库shard-test 支持分片
sh.enableShard("shard-test")
sh.shardCollection("shard-test.collection1",{"username":1, "_id":1})
提示得在集合中建立跟片键对应的索引
db.collection1.createIndex({"username":1, "_id":1})
再执行:
sh.shardCollection("shard-test.collection1",{"username":1, "_id":1})
使用指定的片键 {"username":1, "_id":1} ,对 集合进行分片
查看集合分片状态:
db.collection1.stats().sharded
查看集群的分片状态:
sh.status()
db.printShardingStatus()
查看chunk分布:
use config
db.chunks.count()
db.chunks.find().pretty()
db.chunks.find({"ns":"shard-test.collection1"}).pretty()
db.chunks.find({"ns":"shard-test.collection1"}).pretty()
注意到:
此时,我只插入了少许的数据,这些数据没有超过 chunk 的最小的容量64MB,
因此数据都存储在 1 个 chunk 中。
//db.collection1.stats().size
批量插入大量数据,使得数据量大于最小chunk 的值(64MB),这样就会产生多个chunk 的分割。
修改chunk 的大小
https://docs.mongodb.com/manual/tutorial/modify-chunk-size-in-sharded-cluster/
此次使用C#Drive 批量插入数据:
db.printShardingStatus()
或者这样查询查询
use config
db.chunks.find({"ns":"shard-test.collection1"}).pretty()
db.chunks.find({"ns":"shard-test.collection1"}).count()
查询分割和迁移状况:
use config
db.changelog.find({"ns":"shard-test.collection1", "what":"multi-split"}).count()
发生了 20 次 分割,
db.changelog.find({"ns":"shard-test.collection1", "what":"moveChunk.commit"}).count()
发生了9次数据迁移
查看具体的某次迁移信息:
db.changelog.findOne({"ns":"shard-test.collection1", "what":"moveChunk.commit"})
导入数据
mongoimport --db 数据库名 --collection 集合名 --type csv --headerline --ignoreBlanks --file CSV文件存放路径