注:本系列教程是自己學(xué)習(xí)的記錄轧坎,內(nèi)容來至 菜鳥教程
MongoDB入門教程01
MongoDB入門教程02
MongoDB入門教程03
MongoDB入門教程04
MongoDB入門教程05
1. MongoDB聚合
MongoDB中聚合(aggregate)主要用于處理數(shù)據(jù)(諸如統(tǒng)計平均值,求和等)泽示,并返回計算后的數(shù)據(jù)結(jié)果缸血。
aggregate()方法
語法
> db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
實例
集合中的數(shù)據(jù)如下:
{
"_id" : ObjectId("5aefc46e58072d466fd8277e"),
"title" : "MongoDB Overview",
"description" : "MongoDB is no sql database",
"by_user" : "runoob.com",
"url" : "http://www.runoob.com",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 100.0
},
{
"_id" : ObjectId("5aefc46e58072d466fd8277f"),
"title" : "NoSQL Overview",
"description" : "No sql database is very fast",
"by_user" : "runoob.com",
"url" : "http://www.runoob.com",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 10.0
},
{
"_id" : ObjectId("5aefc46e58072d466fd82780"),
"title" : "Neo4j Overview",
"description" : "Neo4j is no sql database",
"by_user" : "Neo4j",
"url" : "http://www.neo4j.com",
"tags" : [
"neo4j",
"database",
"NoSQL"
],
"likes" : 750.0
}
統(tǒng)計以上集合中每個作者所寫的文章數(shù),使用aggregate()計算結(jié)果如下:
> db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])
{
"result" : [
{
"_id" : "runoob.com",
"num_tutorial" : 2
},
{
"_id" : "Neo4j",
"num_tutorial" : 1
}
],
"ok" : 1
}
類似SQL: select by_user, count(*) from mycol group by by_user
下表展示了一些聚合的表達(dá)式:
表達(dá)式 | 描述 | 實例 |
---|---|---|
$sum | 計算總和 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum: "$likes"}}}]) |
$avg | 計算平均值 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}]) |
$min | 獲取集合中所有文檔對應(yīng)值得最小值械筛。 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}]) |
$max | 獲取集合中所有文檔對應(yīng)值得最大值捎泻。 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}]) |
$push | 在結(jié)果文檔中插入值到一個數(shù)組中。 | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}]) |
$addToSet | 在結(jié)果文檔中插入值到一個數(shù)組中埋哟,但不創(chuàng)建副本笆豁。 | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}]) |
$first | 根據(jù)資源文檔的排序獲取第一個文檔數(shù)據(jù)。 | db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}]) |
$last | 根據(jù)資源文檔的排序獲取最后一個文檔數(shù)據(jù) | db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last :"$url"}}}]) |
管道的概念
管道在Unix和Linux中一般用于將當(dāng)前命令的輸出結(jié)果作為下一個命令的參數(shù)赤赊。
MongoDB的聚合管道將MongoDB文檔在一個管道處理完畢后將結(jié)果傳遞給下一個管道處理闯狱。管道操作是可以重復(fù)的。
表達(dá)式:處理輸入文檔并輸出抛计。表達(dá)式是無狀態(tài)的哄孤,只能用于計算當(dāng)前聚合管道的文檔,不能處理其它的文檔吹截。
聚合框架中常用的幾個操作:
- $project:修改輸入文檔的結(jié)構(gòu)瘦陈∧#可以用來重命名、增加或刪除域晨逝,也可以用于創(chuàng)建計算結(jié)果以及嵌套文檔蛾默。
- $match: 用以過濾數(shù)據(jù),只輸出滿足條件的文檔捉貌,match使用MongoDB的標(biāo)準(zhǔn)查詢操作支鸡。
- $limit:用來限制MongoDB聚合管道返回的文檔數(shù)。
- $skip:在聚合管道中跳過指定數(shù)量的文檔趁窃,并返回余下的文檔苍匆。
- $unwind:將文檔中的某一個數(shù)組類型字段拆分成多條,每條包含數(shù)組中的一個值棚菊。
- $group:將集合中的文檔分組,可用于統(tǒng)計結(jié)果叔汁。
- $sort:將輸入文檔排序后輸出统求。
- $geoNear:輸出接近某一地理位置的有序文檔。
管道操作符實例
- $project實例
> db.article.aggregate({ $project : { title : 1, author : 1 }})
這樣的話結(jié)果中就只還有_id
, tilte
和 author
三個字段了据块,默認(rèn)情況下_id
字段是被包含的码邻,如果要想不包含_id
話可以這樣:
> db.article.aggregate( { $project : {_id : 0 , title : 1,author : 1}})
- $match實例
>db.articles.aggregate( [
{ $match : { score : { $gt : 70, $lte : 90 } } },
{ $group: { _id: null, count: { $sum: 1 } } }
] )
match
用以篩選分?jǐn)?shù)大于70小于等于90的記錄,將符合條件的記錄送入group
管道操作符進(jìn)行處理另假。
- $skip實例
> db.article.aggregate({ $skip : 5 });
經(jīng)過$skip管道操作符處理后像屋,前五個文檔被"過濾"掉。
2. MongoDB 復(fù)制(副本集)
MongoDB復(fù)制是將數(shù)據(jù)同步在多個服務(wù)器上的過程边篮。
復(fù)制提供了數(shù)據(jù)的冗余備份己莺,并在多個服務(wù)器上存儲數(shù)據(jù)副本,提高了數(shù)據(jù)的可用性戈轿,并可以保證數(shù)據(jù)的安全性凌受。
復(fù)制還允許您從硬件故障和服務(wù)中斷中恢復(fù)數(shù)據(jù)。
什么是復(fù)制?
- 保障數(shù)據(jù)的安全性
- 數(shù)據(jù)高可用性 (24*7)
- 災(zāi)難恢復(fù)
- 無需停機維護(hù)(如備份思杯,重建索引胜蛉,壓縮)
- 分布式讀取數(shù)據(jù)
MongoDB 復(fù)制原理
mongodb的復(fù)制至少需要兩個節(jié)點。其中一個是主節(jié)點色乾,負(fù)責(zé)處理客戶端請求誊册,其余的都是從節(jié)點,負(fù)責(zé)復(fù)制主節(jié)點上的數(shù)據(jù)暖璧。
mongodb各個節(jié)點常見的搭配方式為:一主一從案怯、一主多從。主節(jié)點記錄在其上的所有操作oplog澎办,從節(jié)點定期輪詢主節(jié)點獲取這些操作殴泰,然后對自己的數(shù)據(jù)副本執(zhí)行這些操作于宙,從而保證從節(jié)點的數(shù)據(jù)與主節(jié)點一致。
副本集特征
- N個節(jié)點的集群
- 任何節(jié)點可作為主節(jié)點
- 所有寫入操作都在主節(jié)點上
- 自動故障轉(zhuǎn)移
- 自動恢復(fù)
讀寫分離:主節(jié)點負(fù)責(zé)寫入悍汛,子節(jié)點負(fù)責(zé)讀取捞魁,從而實現(xiàn)讀寫分離
試驗參考:參考
3. MongoDB 分片
分片
在MongoDB里存在另一種集群,可以滿足MongoDB數(shù)據(jù)量大量增長的需求离咐。
當(dāng)MongoDB存儲海量的數(shù)據(jù)時谱俭,一臺機器可能不足以存儲數(shù)據(jù),也可能不足以提供可接受的讀寫吞吐量宵蛀。這時昆著,我們就可以通過在多臺機器上分割數(shù)據(jù),使得數(shù)據(jù)庫系統(tǒng)能存儲和處理更多的數(shù)據(jù)术陶。
為什么使用分片
- 復(fù)制所有的寫入操作到主節(jié)點
- 延遲的敏感數(shù)據(jù)會在主節(jié)點查詢
- 單個副本集限制在12個節(jié)點
- 當(dāng)請求量巨大時會出現(xiàn)內(nèi)存不足凑懂。
- 本地磁盤不足
- 垂直擴展價格昂貴
MongoDB分片
下圖展示了在MongoDB中使用分片集群結(jié)構(gòu)分布:
上圖中主要有如下所述三個主要組件:
- Shard: 用于存儲實際的數(shù)據(jù)塊,實際生產(chǎn)環(huán)境中一個shard server角色可由幾臺機器組個一個replica set承擔(dān)梧宫,防止主機單點故障
- Config Server: mongod實例接谨,存儲了整個 ClusterMetadata,其中包括 chunk信息塘匣。
- Query Routers: 前端路由脓豪,客戶端由此接入,且讓整個集群看上去像單一數(shù)據(jù)庫忌卤,前端應(yīng)用可以透明使用扫夜。
Mongos
MongoDB分片的基本思想就是將集合切分成小塊.這些塊分散到若干片里面,每個片只負(fù)責(zé)總數(shù)據(jù)的一部分。應(yīng)用程序不必知道哪片對應(yīng)哪些數(shù)據(jù)驰徊,甚至不需要知道數(shù)據(jù)已經(jīng)被拆分了笤闯,所以在分片之前要運行一個路由進(jìn)程,進(jìn)程名mongos棍厂,這個路由器知道所有數(shù)據(jù)的存放位置望侈,所以應(yīng)用可以連接它來正常發(fā)送請求.對應(yīng)用來說,它僅知道連接了一個普通的mongod勋桶。路由器知道和片的對應(yīng)關(guān)系,能夠轉(zhuǎn)發(fā)請求到正確的片上脱衙。如果請求有了回應(yīng),路由器將其收集起來回送給應(yīng)用例驹。
在沒有分片的時候捐韩,客戶端連接mongod進(jìn)程,分片時客戶端會連接mongos進(jìn)程鹃锈。mongos對應(yīng)用隱藏了分片的細(xì)節(jié)荤胁。從應(yīng)用的角度看,分片和不分片沒有區(qū)別屎债。所以需要擴展的時候仅政,不必修改應(yīng)用程序的代碼垢油。
健壯的片
生產(chǎn)環(huán)境中,每個片都應(yīng)是副本集,這樣單個服務(wù)器壞了,就不會導(dǎo)致整個片失效.用addshard命令就可以將副本集作為片添加,
添加時,只要指定副本集的名稱和種子就行了.
如要添加副本集圆丹,其中包含一個服務(wù)器127.0.0.1:27020(還有別的服務(wù)器),就可以用下列命令將其添加到集群中
>$ mongo localhost:40000
> use admin
> db.runCommand({ addshard: 'rs0/localhost:27020,localhost:27021'})
> db.runCommand({ addshard: 'rs1/localhost:27030,localhost:27031'})
> db.runCommand({ enablesharding: 'test'}) # 設(shè)置分片數(shù)據(jù)庫
> db.runCommand({ shardcollection: 'test.user', key: {name: 1}})
4. MongoDB 備份(mongodump)與恢復(fù)(mongorestore)
1. MongoDB數(shù)據(jù)備份
語法
mongodump命令腳本語法如下:
> mongodump -h dbhost -d dbname -o dbdirectory
- -h: MongDB所在服務(wù)器地址滩愁,例如:127.0.0.1,當(dāng)然也可以指定端口號:127.0.0.1:27017
- -d: 需要備份的數(shù)據(jù)庫實例辫封,例如:test
- -o: 備份的數(shù)據(jù)存放位置硝枉,例如:c:\data\dump,當(dāng)然該目錄需要提前建立倦微,在備份完成后妻味,系統(tǒng)自動在dump目錄下建立一個test目錄,這個目錄里面存放該數(shù)據(jù)庫實例的備份數(shù)據(jù)欣福,導(dǎo)出文件格式為 BSON 和 JSON
mongodump 命令可選參數(shù)列表如下所示:
語法 | 描述 | 實例 |
---|---|---|
mongodump --host HOST_NAME --port PORT_NUMBER | 該命令將備份所有MongoDB數(shù)據(jù) | mongodump --host runoob.com --port 27017 |
mongodump --dbpath DB_PATH --out BACKUP_DIRECTORY | 該命令將數(shù)據(jù)庫導(dǎo)出到指定文件夾 | mongodump --dbpath /data/db/ --out /data/backup/ |
mongodump --collection COLLECTION --db DB_NAME | 該命令將備份指定數(shù)據(jù)庫的集合责球。 | mongodump --collection mycol --db test |
2. MongoDB數(shù)據(jù)恢復(fù)
mongodb使用 mongorestore 命令來恢復(fù)備份的數(shù)據(jù)。
語法
mongorestore命令腳本語法如下:
> mongorestore -h <hostname><:port> -d dbname <path>
--host <:port>, -h <:port>: MongoDB所在服務(wù)器地址拓劝,默認(rèn)為: localhost:27017
--db, -d: 需要恢復(fù)的數(shù)據(jù)庫實例雏逾,例如:test,當(dāng)然這個名稱也可以和備份時候的不一樣凿将,比如test2
--drop: 恢復(fù)的時候,先刪除當(dāng)前數(shù)據(jù)价脾,然后恢復(fù)備份的數(shù)據(jù)牧抵。就是說,恢復(fù)后侨把,備份后添加修改的數(shù)據(jù)都會被刪除犀变,慎用哦!
path: mongorestore 最后的一個參數(shù)秋柄,設(shè)置備份數(shù)據(jù)所在位置获枝,例如:c:\data\dump\test。你不能同時指定 <path> 和 --dir 選項骇笔,--dir也可以設(shè)置備份目錄省店。
--dir: 指定備份的目錄你不能同時指定 <path> 和 --dir 選項。
5. MongoDB 監(jiān)控
mongostat 命令
它會間隔固定時間獲取mongodb的當(dāng)前運行狀態(tài)笨触,并輸出懦傍。
mongotop 命令
mongotop提供了一個方法,用來跟蹤一個MongoDB的實例芦劣,查看哪些大量的時間花費在讀取和寫入數(shù)據(jù)粗俱。 mongotop提供每個集合的水平的統(tǒng)計數(shù)據(jù)。默認(rèn)情況下虚吟,mongotop返回值的每一秒
> mongotop <sleeptime> —locks
輸出結(jié)果字段說明:
- ns: 包含數(shù)據(jù)庫命名空間寸认,后者結(jié)合了數(shù)據(jù)庫名稱和集合签财。
- db: 包含數(shù)據(jù)庫的名稱。名為 . 的數(shù)據(jù)庫針對全局鎖定偏塞,而非特定數(shù)據(jù)庫唱蒸。
- total: mongod花費的時間工作在這個命名空間提供總額。
- read: 提供了大量的時間烛愧,這mongod花費在執(zhí)行讀操作油宜,在此命名空間。
- write: 提供這個命名空間進(jìn)行寫操作怜姿,這mongod花了大量的時間慎冤。