目錄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文件存放路徑