MongoDB創(chuàng)建和查看數(shù)據(jù)庫
MongoDB 將 BSON 文檔(即數(shù)據(jù)記錄)存儲在集合中,數(shù)據(jù)庫包含文檔集合。在 MongoDB 里面存在數(shù)據(jù)庫的概念恬叹,但沒有模式候生,保存數(shù)據(jù)的結(jié)構(gòu)是 BSON 結(jié)構(gòu),只不過在進行一些數(shù)據(jù)處理的時候才會使用 MongoDB 自己的操作绽昼。
MongoDB 自帶了一個功能強大的 JavaScript Shell唯鸭,可以用于管理或操作 MongoDB。
MongoDB 數(shù)據(jù)庫初始安裝完成后硅确,默認的數(shù)據(jù)庫是 test目溉,學習時可以在默認 test 數(shù)據(jù)庫上進行各種練習操作。當然在實際的操作過程中需要創(chuàng)建很多實例疏魏,因此停做,用戶需要掌握自定義數(shù)據(jù)庫名稱的基本規(guī)則。
MongoDB 數(shù)據(jù)庫的命名規(guī)則
MongoDB 數(shù)據(jù)庫的命名要符合 UTF-8 標準的字符串大莫,同時要遵循下表所示的注意事項蛉腌。
序號 | 注意事項 |
---|---|
1 | 不能是空串 |
2 | 不得含有 /、\只厘、?烙丛、$、空格羔味、空字符等河咽,基本只能使用 ASCII 中的字母和數(shù)字 |
3 | 區(qū)分大小寫,建議全部小寫 |
4 | 名稱最多為 64 字節(jié) |
5 | 不得使用保留的數(shù)據(jù)庫名赋元,如:admin忘蟹、local、config |
注意:數(shù)據(jù)庫最終會成為文件搁凸,數(shù)據(jù)庫名就是文件的名稱媚值。
- 由于數(shù)據(jù)庫名稱在 MongoDB 中不區(qū)分大小寫,因此數(shù)據(jù)庫名稱不能僅僅區(qū)別于字符护糖。
- 對于在 Windows 上運行的 MongoDB褥芒,數(shù)據(jù)庫名稱不能包含以下字符:/、\嫡良、“锰扶、$、*寝受、< >坷牛、:、|很澄、? 漓帅。
- 對于在 UNIX 和 Linux 系統(tǒng)上運行的 MongoDB锨亏,數(shù)據(jù)庫名稱不能包含以下字符:/、\忙干、。浪藻、"捐迫、$。
- 雖然 UTF-8 可以提供很多國家的語言的命名格式爱葵,在 MongoDB 數(shù)據(jù)庫命名時也可以使用漢字作為數(shù)據(jù)庫名施戴,但是最好盡量采用英文字母、數(shù)字萌丈、字符等為主的命名格式赞哗。
如下命名格式是正確的:myDB、my_NewDB辆雾、myDB12肪笋。
以下命名格式則不被 MongoDB 接受:.myDB、/123度迂。
保留數(shù)據(jù)庫
MongoDB 系統(tǒng)保留的數(shù)據(jù)庫如表所示藤乙。
庫名 | 作用 |
---|---|
admin | 權(quán)限數(shù)據(jù)庫,添加用戶到該數(shù)據(jù)庫中惭墓,該用戶會自動繼承數(shù)據(jù)庫的所有權(quán)限 |
local | 數(shù)據(jù)庫中的數(shù)據(jù)永遠不會被復制 |
config | 分片時坛梁,config 數(shù)據(jù)庫在內(nèi)部使用,保存分子信息 |
test | 默認數(shù)據(jù)庫腊凶,可以用來做各種測試等 |
創(chuàng)建數(shù)據(jù)庫
MongoDB 使用 use 命令創(chuàng)建數(shù)據(jù)庫划咐,如果數(shù)據(jù)庫不存在,MongoDB 會在第一次使用該數(shù)據(jù)庫時創(chuàng)建數(shù)據(jù)庫钧萍。如果數(shù)據(jù)庫已經(jīng)存在則連接數(shù)據(jù)庫褐缠,然后可以在該數(shù)據(jù)庫進行各種操作。
use myDB
查看數(shù)據(jù)庫
MongoDB 使用 show 命令查看當前數(shù)據(jù)庫列表划煮,代碼如下:
>show dbs //可以在任意當前數(shù)據(jù)庫上執(zhí)行該命令
admin 0.000GB //保留數(shù)據(jù)庫送丰,admin
myDB 0.000GB //自定義數(shù)據(jù)庫,myDB,該數(shù)據(jù)庫里已經(jīng)插入記錄弛秋,沒有記錄的自定義數(shù)據(jù)庫不會顯示
local 0.000GB //保留數(shù)據(jù)庫器躏,local
test 0.000GB //保留數(shù)據(jù)庫,test
MongoDB 默認的數(shù)據(jù)庫為 test蟹略,如果沒有創(chuàng)建新的數(shù)據(jù)庫登失,集合將存儲在 test 數(shù)據(jù)庫中。如果自定義數(shù)據(jù)庫沒有插入記錄挖炬,則用戶在查看數(shù)據(jù)庫時是不會顯示的揽浙,只有插入數(shù)據(jù)的數(shù)據(jù)庫才會顯示相應(yīng)的信息。
統(tǒng)計數(shù)據(jù)庫信息
MongoDB 使用 stats() 方法查看某個數(shù)據(jù)庫的具體統(tǒng)計信息,注意對某個數(shù)據(jù)庫進行操作之前馅巷,一定要用 use 切換至數(shù)據(jù)庫膛虫,否則會出錯,代碼如下:
>use test //選擇執(zhí)行的test數(shù)據(jù)庫
switched to db test //use執(zhí)行后返回的結(jié)果
> db. stats () //統(tǒng)計數(shù)據(jù)信息
{
"db" : "test", //數(shù)據(jù)庫名
"collections" : 0, //集合數(shù)量
"views" : 0,
"objects" : 0, //文檔數(shù)量
"avgObjSize" : 0, //平均每個文檔的大小
"dataSize" : 0, //數(shù)據(jù)占用空間大小钓猬,不包括索引稍刀,單位為字節(jié)
"storageSize" : 0, //分配的存儲空間
"nuinExtents" : 0, //連續(xù)分配的數(shù)據(jù)塊
"indexes" : 0, //索引個數(shù)
"indexsize" : 0, //索引占用空間大小
"fileSize" : 0, //物理存儲文件的大小
"ok" : 1
}
刪除數(shù)據(jù)庫
MongoDB 使用 dropDatabase() 方法刪除數(shù)據(jù)庫,代碼如下:
>db.dropDatabase () //刪除當前數(shù)據(jù)庫
{ ndropped" : "myDBn Jok" : 1} //顯示結(jié)果刪除成功
查看集合
MongoDB 使用 getCollectionNames() 方法查詢當前數(shù)據(jù)庫下的所有集合敞曹,代碼如下:
>use test
>db.getCollectionNames () //查詢當前數(shù)據(jù)下所有的集合名稱
MongoDB創(chuàng)建集合
MongoDB 將文檔存儲在集合中账月。集合類似于關(guān)系數(shù)據(jù)庫中的表。如果集合不存在澳迫,則 MongoDB 會在第一次存儲該集合數(shù)據(jù)時創(chuàng)建該集合局齿。
MongoDB 集合的命名規(guī)則
MongoDB 的集合就相當于 MySQL 的一個表 table,MySQL 列出的所有表都可以使用 show tables橄登,MongoDB 可以使用 show collections 展示所有集合抓歼。
集合是一組文檔,是無模式的示绊,集合名稱要求符合 UTF-8 標準的字符串锭部,同時要遵循下表所示的注意事項。
序號 | 注意事項 |
---|---|
1 | 集合名不能是空串 |
2 | 不能含有空字符 \0 |
3 | 不能以“system.”開頭面褐,這是系統(tǒng)集合保留的前綴 |
4 | 集合名不能含保留字符“$” |
對于分別部署在 Windows拌禾、Linux、UNIX 系統(tǒng)上的 MongoDB展哭,集合的命名方式與數(shù)據(jù)庫命名方式一致湃窍。
創(chuàng)建集合
MongoDB 集合的創(chuàng)建有顯式和隱式兩種方法。
顯式創(chuàng)建集合可通過使用db.createCollection(name, options)
方法來實現(xiàn)匪傍,參數(shù) name 指要創(chuàng)建的集合名稱您市,options 是可選項,指定內(nèi)存大小和索引等役衡,下表描述 了 options 可使用的選項茵休。
參數(shù) | 類型 | 描述 |
---|---|---|
capped | Boolean | (可選)如果為 true,則啟用封閉的集合手蝎。上限集合是固定大小的集合榕莺,它在達到其最大時自動覆蓋其最舊的條目。如果指定 true棵介,則還需要指定 size 參數(shù) |
size | 數(shù)字 | (可選)指定上限集合的最大大卸ぱ臁(以字節(jié)為單位)。如果 capped 為 true邮辽,那么還需要指定次字段的值 |
max | 數(shù)字 | (可選)指定上限集合中允許的最大文檔數(shù) |
注意:在插入文檔時唠雕,MongoDB 首先檢查上限集合 capped 字段的大小贸营,然后檢查 max 字段。
顯式創(chuàng)建集合的一個例子:
db.createCollection("mySet", {capped:true,size:6142800, max :10000 })
在 MongoDB 中岩睁,當插入文檔時钞脂,如果集合不存在,則 MongoDB 會隱式地自動創(chuàng)建集合笙僚,方法如下:
db.myDB.insert( {"name": "tom"} )
其他集合操作
創(chuàng)建集合后可以通過 show collections 命令查看集合的詳細信息芳肌,使用 renamecollection() 方法可對集合進行重新命名。
刪除集合使用 drop() 方法肋层,具體代碼如下:
Show collections;
db.mySet.renameCollection( "orders2014");
db.orders2014.drop()
MongoDB文檔鍵的命名規(guī)則
文檔是 MongoDB 中存儲的基本單元,是一組有序的鍵值對集合翎迁。文檔中存儲的文檔鍵的格式必須是符合 UTF-8 標準的字符串栋猖,同時要遵循以下注意事項:
- 不能包含
\0
字符(空字符),因為這個字符表示鍵的結(jié)束汪榔; - 不能包含
$
和.
蒲拉,因為.
和$
是被保留的,只能在特定環(huán)境下使用痴腌; - 鍵名區(qū)分大小寫雌团;
- 鍵的值區(qū)分類型(如字符串和整數(shù)等);
- 鍵不能重復士聪,在一條文檔里起唯一的作用锦援。
注意,以上所有命名規(guī)范必須符合 UTF-8 標準的字符串剥悟,文檔的鍵值對是有順序的灵寺,相同的鍵值對如果有不同順序,也是不同的文檔区岗。
例1:以下兩組文檔是不同的略板,因為值的類型不同。
{"recommend":"5"}
{"recommend":5}
例2:以下兩組文檔也是不同的慈缔,因為鍵名是區(qū)分大小寫的叮称。
{ "Recommend" : " 5 "}
{"recommend":"5"}
MongoDB insert()方法:插入數(shù)據(jù)
要將數(shù)據(jù)插入 MongoDB 集合中,可以使用 MongoDB 的 insert() 方法藐鹤,同時 MongoDB 針對插入一條還是多條數(shù)據(jù)瓤檐,提供了更可靠的 insertOne() 和 insertMany() 方法。
MongoDB 向集合里插入記錄時教藻,無須事先對數(shù)據(jù)存儲結(jié)構(gòu)進行定義距帅。如果待插入的集合不存在,則插入操作會默認創(chuàng)建集合括堤。
在 MongoDB 中碌秸,插入操作以單個集合為目標绍移,MongoDB 中的所有寫入操作都是單個文檔級別的原子操作。
向集合中插入數(shù)據(jù)的語法如下:
db.collection.insert(
<document or array of documents>,
{
writeConcern: <document>, //可選字段
ordered: <boolean> //可選字段
}
)
db 為數(shù)據(jù)庫名讥电,如當前數(shù)據(jù)庫名為“test”刃泡,則用 test 代替 db,collection 為集合名怜珍,insert() 為插入文檔命令乔外,三者之間用連接。
參數(shù)說明:
- <document or array of documents> 參數(shù)表示可設(shè)置插入一條或多條文檔纠炮。
- writeConcern:<document> 參數(shù)表示自定義寫出錯的級別月趟,是一種出錯捕捉機制。
- ordered:<boolean> 是可選的恢口,默認為 true孝宗。
- 如果為 true,在數(shù)組中執(zhí)行文檔的有序插入耕肩,并且如果其中一個文檔發(fā)生錯誤因妇,MongoDB 將返回而不處理數(shù)組中的其余文檔;
- 如果為 false猿诸,則執(zhí)行無序插入婚被,若其中一個文檔發(fā)生錯誤,則忽略錯誤梳虽,繼續(xù)處理數(shù)組中的其余文檔址芯。
插入不指定 _id 字段的文檔的代碼如下:
> db.test.insert( { item : "card", qty : 15 })
在插入期間,mongod 將創(chuàng)建 _id 字段并為其分配唯一的 Objectld 值怖辆,這里的 mongod 是一個 MongoDB 服務(wù)器的實例是复,也就是 MongoDB 服務(wù)駐扎在計算機上的進程。
查看集合文檔的代碼如下:
> db.test.find()
{"_id":Objectlid("5bacac84bb5e8c5dff78dc21"), "item":"cardn, "qty":15 }
這些 Objectld 值與執(zhí)行操作時的機器和時間有關(guān)竖螃,因此淑廊,用戶執(zhí)行這段命令后的返回值與示例中的值是不同的。
插入指定 _id 字段的文檔特咆,值 _id 必須在集合中唯一季惩,以避免重復鍵錯誤,代碼如下:
> db.test.insert(
{ _id: 10, item: "box", qty: 20 }
)
> db.test.find()
{ "_id" : 10, "item" : "box" , "qty": 20 }
可以看到新插入文檔的 id 值為設(shè)置的 id 值腻格。
插入的多個文檔無須具有相同的字段画拾。例如,下面代碼中的第一個文檔包含一個 _id 字段和一個 type 字段菜职,第二個和第三個文檔不包含 _id 字段青抛。因此,在插入過程中酬核,MongoDB 將會為第二個和第三個文檔創(chuàng)建默認 _id 字段蜜另,代碼如下:
db.test.insert(
[
{ _id: 11, item: "pencil", qty: 50, type: "no.2" },
{ item: "pen", qty: 20 },
{ item: "eraser", qty: 25 }
]
)
查詢驗證适室,可以看到在 _id 插入期間,系統(tǒng)自動為第二举瑰、第三個文檔創(chuàng)建了字段捣辆,代碼如下:
> db.test.find()
{ "_id" : 11, "item" : "pencil", "qty" : 50, "type" : "no.2" }
{ "_id" : Objectld("5bacf31728b746e917e06b27"), "item" : "pen", "qty" : 20 }
{ "_id" : Objectld("5bacf31728b746e917e06b28"), "item" : "eraser", "qty" : 25 }
用變量方式插入文檔此迅,代碼如下:
> document= ({ name: "c語言", price: 40 }) //document 為變量名.
> db.test.insert(document)
有序地插入多條文檔的代碼如下:
> db.test.insert([
{_id:10, item:"pen", price:"20" },
{_id:12, item:"redpen", price: "30" },
{_id:11, item:"bluepen", price: "40" }
],
{ordered:true}
)
在設(shè)置 ordered:true 時汽畴,插入的數(shù)據(jù)是有序的,如果存在某條待插入文檔和集合的某文檔 _id 相同的情況耸序,_id 相同的文檔與后續(xù)文檔都將不再插入忍些。在設(shè)置 ordered:false 時,除了出錯記錄(包括 _id 重復)外其他的記錄繼續(xù)插入坎怪。
MongoDB 3.2 更新后新增以下兩種新的文檔插入命令如下:
db.collection.insertone ()
db.collection.insertMany()
使用 insertOne() 插入一條文檔的代碼如下:
db.test.iusertone( { item: "card", qty: 15 } );
使用 insertMany() 插入多條文檔的代碼如下:
db.test.insertMany([
{ item: "card", qty: 15 },
{ item: "envelope", qty: 20 },
{ item: "stamps", qty:30 }
]);
MongoDB update()和save()方法:更新或修改數(shù)據(jù)
MongoDB 使用 update() 和 save() 方法來更新(修改)集合中的文檔坐昙。
update() 方法
MongoDB update() 更新文檔的基本語法如下:
db.collection.update(
<query>,
<update>,
{
upsert,
multi,
writeConcern,
collation
}
)
參數(shù)說明:
- <query>:參數(shù)設(shè)置查詢條件。
- <update>:為更新操作符芋忿。
- upsert:為布爾型可選項,表示如果不存在 update 的記錄疾棵,是否插入這個新的文檔戈钢。true 為插入;默認為 false是尔,不插入殉了。
- multi:也是布爾型可選項,默認是 false拟枚,只更新找到的第一條記錄薪铜。如果為 true,則把按條件查詢出來的記錄全部更新恩溅。
- writeConcem:表示出錯級別隔箍。
- collation:指定語言。
例如脚乡,插入多條數(shù)據(jù)后蜒滩,使用 update 進行更改,代碼如下:
db.test.insertMany ([
{ item : "card"奶稠,qty : 15 },
{ item : "envelope", qty: 20 },
{ item : "stamps", qty: 30 }
]);
將 item 為 card 的數(shù)量 qty 更正為 35俯艰,代碼如下:
db.test.update(
{
item : "card"
},
{
$set: {qty: 35}
}
collation 特性允許 MongoDB 的用戶根據(jù)不同的語言定制排序規(guī)則,在 MongoDB 中字符串默認當作一個普通的二進制字符串來對比锌订。而對于中文名稱竹握,通常有按拼音順序排序的需求,這時就可以通過collation來實現(xiàn)辆飘。
創(chuàng)建集合時啦辐,指定 collation 為 zh谓传,按 name 字段排序時,則會按照 collation 指定的中文規(guī)則來排序昧甘,代碼如下:
db.createCollection ("person", {collation: {locale: "zh" }}) //創(chuàng)建集合并指定語言
db.person.insert ({name: ”張三”})
db.person.insert ({name:"李四”})
db.person.insert ({name: ”王五"})
db.person.insert ({name: ”馬六”})
db.person.insert ({name:"張七"})
db.person.find().sort({name: 1}) //查詢并排序
//查詢返回結(jié)果
{ "_id" : Objectld ("586b995d0cec8d86881cffae") , "name": "李四" }
{ "_id" : Objectld ("586b995d0cec8d8 6881cffb0") , "name" : "馬六" }.
{ "_id" : Objectld ("586b995d0cec8d86881cffaf"), "name": "王五" }
{ "_id" : Objectld ("586b995d0cec8d86881cffb1"), "name": "張七" }
{ "_id" : Objectld ("586b995d0cec8d86881cffad"), "name" : "張三" }
save() 方法
MongoDB 另一個更新(修改)文檔的方法是 save()良拼,語法格式如下:
db.collection.save ( obj )
obj 代表需要更新的對象,如果集合內(nèi)部已經(jīng)存在一個與 obj 相同的“_id”的記錄充边,Mongodb 會把 obj 對象替換為集合內(nèi)已存在的記錄庸推;如果不存在,則會插入 obj 對象浇冰。
如下代碼會先保存一個 _id 為 100 的記錄贬媒,然后再執(zhí)行 save,并對當前已經(jīng)存在的數(shù)據(jù)進行修改:
db.products.save( { _id: 100, item: "watern, qty: 30 })
db.products.save( { _id : 100, item : "juice" })
如果使用 insert 插入記錄肘习,若新增數(shù)據(jù)的主鍵已經(jīng)存在际乘,則會拋出 DuplicateKeyException 異常提示主鍵重復,不保存當前數(shù)據(jù)漂佩。
MongoDB刪除數(shù)據(jù):remove()和delete()方法
MongoDB 使用 remove() 和 delete() 方法來刪除集合中的文檔脖含。
remove() 方法
如果不再需要 MongoDB 中存儲的文檔,可以通過刪除命令將其永久刪除投蝉。刪除 MongoDB 集合中的數(shù)據(jù)可以使用 remove() 函數(shù)养葵。
remove() 函數(shù)可以接受一個查詢文檔作為可選參數(shù)來有選擇性地刪除符合條件的文檔。刪除文檔是永久性的瘩缆,不能撤銷关拒,也不能恢復。因此庸娱,在執(zhí)行 remove() 函數(shù)前最好先用 find() 命令來查看是否正確着绊。
remove() 方法的基本語法格式如下所示:
db.collection.remove(
<query>,
{
justOne: <boolean>, writeConcern: <document>
}
)
參數(shù)說明:
- query:必選項,是設(shè)置刪除的文檔的條件熟尉。
- justOne:布爾型的可選項归露,默認為false,刪除符合條件的所有文檔臣樱,如果設(shè)為 true靶擦,則只刪除一個文檔。
- writeConcem:可選項雇毫,設(shè)置拋出異常的級別玄捕。
下面舉例說明刪除集合中的文檔,先進行兩次插入操作棚放,代碼如下:
>db.test.insert(
{
title : 'MongoDB',
description : 'MongoDB 是一個 NoSQL 數(shù)據(jù)庫',
by : 'C語言中文網(wǎng)',
tags : ['mongodb', 'database', 'NoSQL'],
likes : 100
}
)
使用 find() 函數(shù)查詢的代碼如下:
> db.test.find()
{ "_id" : Objectld ("5ba9d8b:L24857a5fefclfde6"), "titlen : "MongoDB", "description" : "MongoDB 是一個 NoSQL 數(shù)據(jù)庫", "by" : "C語言中文網(wǎng)", "tags" : [ "mongodb", "database", "NoSQL" ], "Tikes" : 100 }
{ "_id" : ObjectId("5ba9d90924857a5fefclfde7"), "title" : "MongoDB ", "description" : "MongoDB 是一個 NoSQL 數(shù)據(jù)庫", "by" : "C語言中文網(wǎng)", "tags" : [ "mongodb", "database", "NoSQL"], "likes" : 100 }
接下來移除 title 為“MongoDB”的文檔枚粘,執(zhí)行以下操作后,查詢會發(fā)現(xiàn)兩個文檔記錄均被刪除:
>db.test.remove({'title': 'MongoDB'})
WriteResult({ 'nRemoved' : 2 }) #刪除了兩條數(shù)據(jù)
另外飘蚯,可以設(shè)置比較條件馍迄,如下操作為刪除 price 大于 3 的文檔記錄:
>db.test.remove(
{
price:{$gt:3}
}
)
delete() 方法
官方推薦使用 deleteOne() 和 deleteMany() 方法刪除文檔福也,語法格式如下:
db.collection.deleteMany ({})
db.collection.deleteMany ({ status : "A" })
db.collection.delete.One ({ status : "D" })
第一條語句刪除集合下所有的文檔,第二條語句刪除 status 等于 A 的全部文檔攀圈,第三條語句刪除 status 等于 D 的一個文檔暴凑。
MongoDB find()方法:查詢數(shù)據(jù)
在關(guān)系型數(shù)據(jù)庫中,可以實現(xiàn)基于表的各種各樣的查詢赘来,以及通過投影來返回指定的列现喳,相應(yīng)的查詢功能也可以在 MongoDB 中實現(xiàn)。同時由于 MongoDB 支持嵌套文檔和數(shù)組犬辰,MongoDB 也可以實現(xiàn)基于嵌套文檔和數(shù)組的查詢嗦篱。
find() 簡介
MongoDB 中查詢文檔使用 find() 方法。find() 方法以非結(jié)構(gòu)化的方式來顯示所要查詢的文檔幌缝, 查詢數(shù)據(jù)的語法格式如下:
\>db.collection.find(query, projection)
query 為可選項灸促,設(shè)置查詢操作符指定查詢條件;projection 也為可選項涵卵,表示使用投影操作符指定返回的字段浴栽,如果忽略此選項則返回所有字段。
查詢 test 集合中的所有文檔時轿偎,為了使顯示的結(jié)果更為直觀吃度,可使用 pretty() 方法以格式化的方式來顯示所有文檔,方法如下:
\> db.test.find().pretty()
除了 find() 方法贴硫,還可使用 findOne() 方法,它只返回一個文檔伊者。
查詢條件
MongoDB 支持條件操作符英遭,下表為 MongoDB 與 RDBMS 的條件操作符的對比,讀者可以通過對比來理解 MongoDB 中條件操作符的使用方法亦渗。
操作符 | 格式 | 實例 | 與 RDBMS where 語句比較 |
---|---|---|---|
等于(=) | {<key> : {<value>}} | db.test.find( {price : 24} ) | where price = 24 |
大于(>) | {<key> : {$gt : <value>}} | db.test.find( {price : {$gt : 24}} ) | where price > 24 |
小于(<) | {<key> : {$lt : <value>}} | db.test.find( {price : {$lt : 24}} ) | where price < 24 |
大于等于(>=) | {<key> : {$gte : <value>}} | db.test.find( {price : {$gte : 24}} ) | where price >= 24 |
小于等于(<=) | {<key> : {$lte : <value>}} | db.test.find( {price : {$lte : 24}} ) | where price <= 24 |
不等于(!=) | {<key> : {$ne : <value>}} | db.test.find( {price : {$ne : 24}} ) | where price != 24 |
與(and) | {key01 : value01, key02 : value02, ...} | db.test.find( {name : "《MongoDB 入門教程》", price : 24} ) | where name = "《MongoDB 入門教程》" and price = 24 |
或(or) | {$or : [{key01 : value01}, {key02 : value02}, ...]} | db.test.find( {$or:[{name : "《MongoDB 入門教程》"},{price : 24}]} ) | where name = "《MongoDB 入門教程》" or price = 24 |
特定類型查詢
特定類型查詢結(jié)果在 test 集合中有以下文檔為基礎(chǔ):
> db.test.find()
{"_id" : Objectld("5ba7342c7f9318ea62161351"), "name" : "《MongoDB教程》", "price" : 24, "tags" : [ "MongoDB", "NoSQL", "database" ], "by": "C語言中文網(wǎng)"}
{"_id" : Objectld("5ba747bd7f9318ea62161352"), "name" : "ava 教程", "price" : 36, "tags" : ["編程語言", "Java語言", "面向?qū)ο蟪绦蛟O(shè)計語言"], "by" : "C語言中文網(wǎng)"}
{"_id" : Objectld("5ba75a057f9318ea62161356"), "name" : "王二", "age" : null }
查詢 age 為 null 的字段的語法格式如下:
\> db.test.find({age:null})
此語句不僅匹配出 age 為 null 的文檔挖诸,其他不同類型的文檔也會被查出。這是因為 null 不僅會匹配某個鍵值為 null 的文檔法精,而且還會匹配不包含這個鍵的文檔多律。
查詢數(shù)組可使用以下語法格式:
> db.test.find(
{
tags:['MongoDB', 'NoSQL', 'database']
}
)
{"_id" : ObjectId("5ba7342c7f9318ea62161351"), "name": "《MongoDB教程》", "price" : 24, "tags" : [ "MongoDB", "NoSQL", "database"], "by" : "C語言中文網(wǎng)"}
查詢有 3 個元素的數(shù)組的代碼如下:
> db.test.find(
{
tags:{$size:3}
}
)
{"_id" : Objectld("5baf9b6663ba0fb3ccccle77"), "name" : "《MongoDB 教程》", ''price" : 24, "tags" : ["MongoDB","NoSQL", "database"], "by" : "C語言中文網(wǎng)"}
{"_id" : Objectld ("5baf 9bc763ba0fk>3ccccle78"), "name" : "《Java 教程》", "price" : 36, "tags" : ["編程語言", "Java語言", "面向?qū)ο蟪绦蛟O(shè)計語言"], "by" : "C語言中文網(wǎng)"}
查詢數(shù)組里的某一個值的代碼如下:
> db.test.find(
{
tags: "MongoDB"
}
)
{"_id" : Objectld("5baf9b6663ba0fb3ccccle77"), "name" : "《MongoDB 教程》", ''price" : 24, "tags" : ["MongoDB"搂蜓,"NoSQL", "database"], "by" : "C語言中文網(wǎng)"}
limit() 函數(shù)與 SQL 中的作用相同狼荞,用于限制查詢結(jié)果的個數(shù),如下語句只返回 3 個匹配的結(jié)果帮碰。若匹配的結(jié)果不到 3 個相味,則返回匹配數(shù)量的結(jié)果:
>db.test.find().limit(3)
Skip() 函數(shù)用于略過指定個數(shù)的文檔,如下語句略過第一個文檔殉挽,返回后兩個:
>db.test.find().skip(1)
sort() 函數(shù)用于對查詢結(jié)果進行排序丰涉,1 是升序拓巧,-1 是降序,如下語句可將查詢結(jié)果升序顯示:
>db.test.find().sort({"price" : 1})
使用 $regex 操作符來設(shè)置匹配字符串的正則表達式一死,不同于全文檢索肛度,使用正則表達式無須進行任何配置。如下所示為使用正則表達式查詢含有 MongoDB 的文檔:
> db.test.find({tags:{$regex:"MongoDB"}})
{"_id" : Objectld("5baf9b6663ba0fb3ccccle77"), "name" : "《MongoDB 教程》", ''price" : 24, "tags" : ["MongoDB"投慈,"NoSQL", "database"], "by" : "C語言中文網(wǎng)"}
游標
游標是指對數(shù)據(jù)一行一行地進行操作承耿,在 MongoDB 數(shù)據(jù)庫中對游標的控制非常簡單,只需使用 firid() 函數(shù)就可以返回游標逛裤。有關(guān)游標的方法參見下表瘩绒。
方法名 | 作用 |
---|---|
hasNext | 判斷是否有更多的文檔 |
next | 用來獲取下一條文檔 |
toArray | 將查詢結(jié)構(gòu)放到數(shù)組中 |
count | 查詢的結(jié)果為文檔的總數(shù)量 |
limit | 限制查詢結(jié)果返回數(shù)量 |
skip | 跳過指定數(shù)目的文檔 |
sort | 對查詢結(jié)果進行排序 |
objsLeftlnBatch | 查看當前批次剩余的未被迭代的文檔數(shù)量 |
addOption | 為游標設(shè)置輔助選項,修改游標的默認行為 |
hint | 為查詢強制使用指定索引 |
explain | 用于獲取查詢執(zhí)行過程報告 |
snapshot | 對查詢結(jié)果使用快照 |
使用游標時带族,需要注意下面 4 個問題锁荔。
當調(diào)用 find() 函數(shù)時,Shell 并不立即查詢數(shù)據(jù)庫蝙砌,而是等真正開始獲取結(jié)果時才發(fā)送查詢請求阳堕。
游標對象的每個方法幾乎都會返回游標對象本身,這樣可以方便進行鏈式函數(shù)的調(diào)用择克。
在 MongoDB Shell 中使用游標輸出文檔包含兩種情況恬总,如果不將 find() 函數(shù)返回的游標賦值給一個局部變量進行保存,在默認情況下游標會自動迭代 20 次肚邢。如果將 find() 函數(shù)返回的游標賦值給一個局部變量壹堰,則可以使用游標對象提供的函數(shù)進行手動迭代。
使用清空后的游標骡湖,進行迭代輸出時贱纠,顯示的內(nèi)容為空。
游標從創(chuàng)建到被銷毀的整個過程存在的時間响蕴,被稱為游標的生命周期谆焊,包括游標的創(chuàng)建、使用及銷毀三個階段浦夷。當客戶端使用 find() 函數(shù)向服務(wù)器端發(fā)起一次查詢請求時辖试,會在服務(wù)器端創(chuàng)建一個游標,然后就可以使用游標函數(shù)來操作查詢結(jié)果劈狐。
以下三種情況會讓游標被銷毀罐孝。
- 客戶端保存的游標變量不在作用域內(nèi)。
- 游標遍歷完成后肥缔,或者客戶端主動發(fā)送終止消息肾档。
- 在服務(wù)器端 10 分鐘內(nèi)未對游標進行操作。
以下語句顯示使用游標查找所有文檔:
>var cursor = db.test.find()
>while (cursor.hasNext()){
var doc = cursor.next();
print(doc.name); //把每一條數(shù)據(jù)都單獨拿出來進行逐行的控制
print(doc); //將游標數(shù)據(jù)取出來后,其實每行數(shù)據(jù)返回的都是一個[object BSON]型的內(nèi)容
printjson(doc); //將游標獲取的集合以JSON的形式顯示
}
MongoDB索引
索引的作用是為了提升查詢效率怒见,在查詢操作中俗慈,如果沒有索引,MongoDB 會掃描集合中的每個文檔遣耍,以選擇與查詢語句匹配的文檔闺阱。如果查詢條件帶有索引,MongoDB 將掃描索引舵变, 通過索引確定要查詢的部分文檔酣溃,而非直接對全部文檔進行掃描。
索引簡介
索引可以提升文檔的查詢速度纪隙,但建立索引的過程需要使用計算與存儲資源赊豌,在已經(jīng)建立索引的前提下,插入新的文檔會引起索引順序的重排绵咱。
MongoDB 的索引是基于 B-tree 數(shù)據(jù)結(jié)構(gòu)及對應(yīng)算法形成的碘饼。樹索引存儲特定字段或字段集的值,按字段值排序悲伶。索引條目的排序支持有效的等式匹配和基于范圍的查詢操作艾恼。
下圖所示的過程說明了使用索引選擇和排序匹配文檔的查詢過程。
從根本上說麸锉,MongoDB 中的索引與其他數(shù)據(jù)庫系統(tǒng)中的索引類似钠绍。MongoDB 在集合級別定義索引,并支持 MongoDB 集合中文檔的任何字段或子字段的索引花沉。
MongoDB 在創(chuàng)建集合時柳爽,會默認在 _id 字段上創(chuàng)建唯一索引。該索引可防止客戶端插入具有相同字段的兩個文檔碱屁,_id 字段上的索引不能被刪除泻拦。
在分片集群中,如果不將該 _id 字段用作分片鍵忽媒,則應(yīng)用需要自定義邏輯來確保 _id 字段中值的唯一性,通常通過使用標準的自生成的 Objectld 作為 _id腋粥。
索引類型+創(chuàng)建索引
MongoDB 中索引的類型大致包含單鍵索引晦雨、復合索引、多鍵值索引隘冲、地理索引闹瞧、全文索引、 散列索引等展辞,下面簡單介紹各類索引的用法奥邮。
單鍵索引
MongoDB 支持文檔集合中任何字段的索引,在默認情況下,所有集合在 _id 字段上都有一個索引洽腺,應(yīng)用程序和用戶可以添加額外的索引來支持重要的查詢操作脚粟,單鍵索引可參考下圖。
對于單字段索引和排序操作蘸朋,索引鍵的排序順序(即升序或降序)無關(guān)緊要核无,因為 MongoDB 可以在任意方向上遍歷索引。
創(chuàng)建單鍵索引的語法結(jié)構(gòu)如下:
\>db.collection.createlndex ( { key: 1 } ) //1 為升序藕坯,-1 為降序
以下示例為插入一個文檔团南,并在 score 鍵上創(chuàng)建索引,具體步驟如下:
>db.records.insert(
{
"score" : 1034,
"location" : { state: "NY", city: "New York"}
}
)
db.records.createTndex( { score: 1 } )
使用 score 字段進行查詢炼彪,再使用 explain() 函數(shù)吐根,可以查看查詢過程:
db.records.find({score:1034}).explain()
具體返回結(jié)果這里不再顯示,讀者可自行查閱辐马。
復合索引
MongoDB 支持復合索引拷橘,其中復合索引結(jié)構(gòu)包含多個字段,下圖說明了兩個字段的復合索引示例齐疙。
復合索引可以支持在多個字段上進行的匹配查詢膜楷,語法結(jié)構(gòu)如下:
db.collection.createIndex ({ <key1> : <type>, <key2> : <type2>, ...})
需要注意的是,在建立復合索引的時候一定要注意順序的問題贞奋,順序不同將導致查詢的結(jié)果也不相同赌厅。
如下語句創(chuàng)建復合索引:
>db.records.createIndex ({ "score": 1, "location.state": 1 })
查看復合索引的查詢計劃的語法如下:
>db.records.find({score:1034, "location.state" : "NY"}).explain()
多鍵值索引
若要為包含數(shù)組的字段建立索引,MongoDB 會為數(shù)組中的每個元素創(chuàng)建索引鍵轿塔。這些多鍵值索引支持對數(shù)組字段的高效查詢特愿,如圖所示。
創(chuàng)建多鍵值索引的語法如下:
\>db.collecttion.createlndex( { <key>: < 1 or -1 > })
需要注意的是勾缭,如果集合中包含多個待索引字段是數(shù)組揍障,則無法創(chuàng)建復合多鍵索引。
以下示例代碼展示插入文檔俩由,并創(chuàng)建多鍵值索引:
>db.survey.insert ({item : "ABC", ratings: [ 2, 5, 9 ]})
>db.survey.createIndex({ratings:1})
>db.survey.find({ratings:2}).explain()
地理索引
地理索引包含兩種地理類型毒嫡,如果需要計算的地理數(shù)據(jù)表示為類似于地球的球形表面上的坐標,則可以使用 2dsphere 索引幻梯。
通扯祷可以按照坐標軸、經(jīng)度碘梢、緯度的方式把位置數(shù)據(jù)存儲為 GeoJSON 對象咬摇。GeoJSON 的坐標參考系使用的是 wgs84 數(shù)據(jù)。如果需要計算距離(在一個歐幾里得平面上)煞躬,通掣嘏簦可以按照正常坐標對的形式存儲位置數(shù)據(jù)逸邦,可使用 2d 索引。
使用 2dsphere 索引的語法結(jié)構(gòu)如下:
db.collection.createlndex( { <location field> : "2dsphere"})
使用 2d 索引的語法結(jié)構(gòu)如下:
db.<collection>.createIndex(
{
<location field> : "2d",
<additional field> : <value>
},
{
<index-specification options>
}
)
這里以 2dsphere 為示例在扰,創(chuàng)建地理索引:
>db.places.insert(
{
loc : { type: "Point", coordinates: [ -73.97, 40.77 ] },
name: "Central Park",
category : "Parks"
}
)
>db.places.insert(
{
loc : { type: "Point", coordinates:[ -73.88, 40.78 ] },
name: "La Guardia Airport",
category : "Airport"
}
)
>db.places.createIndex ({loc : "2dsphere"})
>db.places.find({loc : "2dsphere"}).explain()
MongoDB 在地理空間查詢方面還有很多的應(yīng)用缕减,讀者可以進行適當?shù)耐卣埂?/p>
全文索引
MongoDB 的全文檢索提供三個版本,用戶在使用時可以指定相應(yīng)的版本健田,如果不指定則默認選擇當前版本對應(yīng)的全文索引烛卧。
MongoDB 提供的文本索引支持對字符串內(nèi)容的文本搜索查詢,但是這種索引因為需要檢索的文件比較多妓局,因此在使用的時候檢索時間較長总放。
全文索引的語法結(jié)構(gòu)如下:
db.collection.createIndex ({ key: "text" })
散列索引
散列(Hashed)索引是指按照某個字段的散列值來建立索引,目前主要用于 MongoDB Sharded Cluster 的散列分片好爬,散列索引只能用于字段完全匹配的查詢局雄,不能用于范圍查詢等。
散列其語法如下:
db.collection.createlndex( { _id : "hashed" })
MongoDB 支持散列任何單個字段的索引存炮,但是不支持多鍵(即數(shù)組)索引炬搭。
需要說明的是,MongoDB 在進行散列索引之前穆桂,需要將浮點數(shù)截斷為 64 位整數(shù)宫盔。例如,散列將對 2.3享完、2.2 和 2.9 這些值產(chǎn)生同樣的返回值灼芭。
上面列出的都是索引的類別,在每個索引的類別上還可以加上一些參數(shù)般又,使索引更加具有針對性彼绷,常見的參數(shù)包括稀疏索引、唯一索引茴迁、過期索引等寄悯。
稀疏索引只檢索包含具有索引字段的文檔,即使索引字段包含空值堕义,檢索時也會跳過所有缺少索引字段的文檔猜旬。因為索引不包含集合的所有文檔,所以說索引是稀疏的倦卖。相反洒擦,非稀疏索引包含集合中的所有文檔,存儲不包含索引字段的文檔的空值糖耸。
設(shè)置稀疏索引的語法如下:
db.collection.createlndex ({ "key" : 1 }, { sparse : true })
如果設(shè)置了唯一索引,新插入文檔時丘薛,要求 key 的值是唯一的嘉竟,不能有重復的出現(xiàn),設(shè)置唯一索引的語法如下:
db.collection.createlndex ({ "key" : 1 }, { unique: true })
過期索引是一種特殊的單字段索引,MongoDB 可以用來在一定時間或特定時間后從集合中自動刪除文檔舍扰。
過期索引對于處理某些類型的信息非常有用倦蚪,例如,機器生成的事務(wù)數(shù)據(jù)边苹、日志和會話信息陵且,這些信息只需要在數(shù)據(jù)庫中存在有限的時間,不需要長期保存个束。
創(chuàng)建過期索引的語法如下:
db.collection.createlndex( {"key" : 1 }, { expireAfterSeconds: 3600 })
需要注意的是慕购,MongoDB 是每 60s 執(zhí)行一次刪除操作,因此短時間內(nèi)執(zhí)行會出現(xiàn)延遲現(xiàn)象茬底。
查看現(xiàn)有索引
若要返回集合上所有索引的列表沪悲,則需使用驅(qū)動程序的 db.collection.getlndexes() 方法或類似方法。
例如阱表,可使用如下方法查看 records 集合上的所有索引:
db.records.getIndexes()
列出數(shù)據(jù)庫的所有索引
若要列出數(shù)據(jù)庫中所有集合的所有索引殿如,則需在 MongoDB 的 Shell 客戶端中進行以下操作:
db.getCollectionNames().forEach(function(collection){
indexes = db[collection].getIndexes();
print("Indexes for " + collection + ":" );
printjson(indexes);
});
刪除索引
MongoDB 提供的兩種從集合中刪除索引的方法如下:
db.collection.dropIndex()
db.collection.dropIndexes()
若要刪除特定索引,則可使用該 db.collection.droplndex() 方法最爬。
例如涉馁,以下操作將刪除集合中 score 字段的升序索引:
db.records.dropIndex ({ "score" : 1 }) //升序降序不能錯,如果為-1爱致,則提示無索引
還可以使用 db.collection.droplndexes() 刪除除 _id 索引之外的所有索引烤送。
例如,以下命令將從 records 集合中刪除所有索引:
db.records.dropIndexes()
修改索引
若要修改現(xiàn)有索引蒜鸡,則需要刪除現(xiàn)有索引并重新創(chuàng)建索引胯努。
MongoDB聚合查詢詳解
聚合操作主要用于處理數(shù)據(jù)并返回計算結(jié)果。聚合操作將來自多個文檔的值組合在一起逢防,按條件分組后叶沛,再進行一系列操作(如求和、平均值忘朝、最大值灰署、最小值)以返回單個結(jié)果。
MongoDB 提供了三種執(zhí)行聚合的方法:聚合管道局嘁、map-reduce 和單一目標聚合方法溉箕,本節(jié)只介紹前兩種方法。
聚合管道方法
MongoDB 的聚合框架就是將文檔輸入處理管道悦昵,在管道內(nèi)完成對文檔的操作肴茄,最終將文檔轉(zhuǎn)換為聚合結(jié)果。
最基本的管道階段提供過濾器但指,其操作類似查詢和文檔轉(zhuǎn)換寡痰,可以修改輸出文檔的形式抗楔。其他管道操作提供了按特定字段對文檔進行分組和排序的工具,以及用于聚合數(shù)組內(nèi)容(包括文檔數(shù)組)的工具拦坠。
此外连躏,在管道階段還可以使用運算符來執(zhí)行諸如計算平均值或連接字符串之類的任務(wù)。聚合管道可以在分片集合上運行贞滨。
聚合管道方法的流程參見下圖入热。
上圖的聚合操作相當于 MySQL 中的以下語句:
select cust_id as _id, sum(amount) as total from orders where status like "%A%" group by cust_id;
MongoDB 中的聚合操作語法如下:
db.collection.aggregate([
{
$match : {< query >},
}
{
$group: {< fieldl >: < field2 >}
}
])
Query 設(shè)置統(tǒng)計查詢條件,類似于 SQL 的 where晓铆,field1 為分類字段勺良,要求使用 _id 名表示分類字段,field2 為包含各種統(tǒng)計操作符的數(shù)字型字段尤蒿,如 avg、$min 等腰池。
這個語法看起來比較難以理解尾组,下面給出一個示例進行對照:
db.mycol.aggregate([
{
$group : {_id : "$by_user", num_tutorial : {$sum : 1}}
}
])
相當于MySQL中的:
select by_user as _id, count(*) as num_tutorial from mycol group by by_user;
再舉一個復雜的例子,按照指定條件對文檔進行過濾示弓,然后對滿足條件的文檔進行統(tǒng)計讳侨,并將統(tǒng)計結(jié)果輸出到臨時文件中。
首先插入多條文檔奏属,代碼如下:
db.articles.insert([
{ "_id" : 10, "author" : "dave", "score" : 80, "views" :100 },
{ "_id" : 11, "author" : "dave", "score" : 85, "views" : 521 },
{ "_id" : 12, "author" : "ahn", "score" : 60, "views" : 1000 },
{ "_id" : 13, "author" : "li", "score" : 55, "views" : 5000 },
{ "_id" : 14, "author" : "annT", "score" : 60, "views" : 50 },
{ "_id" : 15, "author" : "1i", "score": 94, "views": 999 },
{ "_id" : 16, "author" : "ty", "score" : 95, "views": 1000 }
]);
再進行聚合分類統(tǒng)計跨跨,代碼如下:
db.articles.aggregate([
{
$match: { $or: [{ score: { $gt: 70, $1t: 90 }}, { views: { $gte: 1000 }}]}}, { $group: { _id: null, count: { $sum: 1 }}
}
]);
最終統(tǒng)計結(jié)果為:
{ "_id" : null, "count" : 5 }
管道階段的 RAM 限制為 100MB。若要允許處理大型數(shù)據(jù)集囱皿,則可使用 allowDiskUse 選項啟用聚合管道階段勇婴,將數(shù)據(jù)寫入臨時文件。
map-reduce 方法
MongoDB 還提供了 map-reduce 方法來執(zhí)行聚合嘱腥。通常 map-reduce 方法有兩個階段:首先 map 階段將大批量的工作數(shù)據(jù)分解執(zhí)行耕渴,然后 reduce 階段再將結(jié)果合并成最終結(jié)果。
與其他聚合操作相同齿兔,map-reduce 可以指定查詢條件以選擇輸入文檔以及排序和限制結(jié)果毙玻。
map-reduce 使用自定義 JavaScript 函數(shù)來執(zhí)行映射和減少操作善涨,雖然自定義 JavaScript 與聚合管道相比提供了更大的靈活性汗菜,但通常 map-reduce 比聚合管道效率更低梢褐、更復雜。
map-reduce 可以在分片集合上運行医寿,也可以輸出到分片集合栏赴。map-reduce 的語法如下:
\>db.collection.mapReduce(
function() { emit(key,value); },
function(key, values) { return reduceFunction }
{ query: document, out: collection }
)
參數(shù)說明:
- function() { emit(key,value); } 為 map 映射函數(shù),負責生成鍵值對序列靖秩,并作為 reduce 函數(shù)輸入?yún)?shù)须眷。
- function(key, values) { return reduceFunction } 為 reduce 統(tǒng)計函數(shù)乌叶,reduce 函數(shù)的任務(wù)就是將 key-values 變成 key-value,也就是把 values 數(shù)組轉(zhuǎn)換成一個單一的值 value柒爸。
- query 設(shè)置篩選條件,只有滿足條件的文檔才會調(diào)用 map 函數(shù)事扭。
- out 為統(tǒng)計結(jié)果的存放集合捎稚,如果不指定則使用臨時集合,但會在客戶端斷開后自動刪除求橄。
舉例說明使用 map-Teduce 方法進行 MongoDB 文檔數(shù)據(jù)的聚合今野。首先插入數(shù)據(jù),數(shù)據(jù)為每位顧客 cust_id 的消費情況罐农,代碼如下:
db.order.insert([
{ "cust_id" : "l", "status" : "A", "price" : 25, "items" : [{"sku" : "mmm", "qty" : 5, "price" : 2.5 },
{ "sku" : "nnn", "qty" : 5, "price" : 2.5 }]},
{ "cust_id" : "l", "status" : "A", "price" : 25, "items" : [{"sku" : "mmm", "qty" : 5, "price" : 2.5 },
{ "sku" : "nnn", "qty" : 5, "price" : 2.5 }]},
{ "cust_id" : "2", "status" : "A", "price" : 25, "items" : [{"sku" : "mmm", "qty" : 5, "price" : 2.5 },
{ "sku" : "nnn", "qty" : 5, "price" : 2.5 }]},
{ "cust_id" : "3", "status" : "A", "price" : 25, "items" : [{"sku" : "mmm", "qty" : 5, "price" : 2.5 },
{ "sku" : "nnn", "qty" : 5, "price" : 2.5 }]},
{ "cust_id" : "3", "status" : "A", "price" : 25, "items" : [{"sku" : "mmm", "qty" : 6, "price" : 2.5 },
{ "sku" : "nnn", "qty" : 6, "price" : 2.5 }]},
])
編寫 map 函數(shù)条霜,cust_id 作為 map 的輸出 key,price 作為 map 的輸出 value涵亏,代碼如下:
var mapFunc = function(){
emit(this.cust_id, this.price);
};
編寫 reduce 函數(shù)宰睡,將相同的 map 的輸出 key(cust_id) 聚合起來,這里對輸出的 value 進行 sum 操作气筋,代碼如下:
var reduceFunc = function(key,values){
return Array.sum(values);
};
執(zhí)行 map-reduce 任務(wù)拆内,將 reduce 的輸出結(jié)果保存在集合 map_result_result 中,代碼如下:
db.order.mapReduce(mapFunc, reduceFunc, { out: { replace: 'map_result_result' }})
查看當前數(shù)據(jù)庫下的所有集合宠默,會發(fā)現(xiàn)新建了一個 map_result_result麸恍,此集合里保存了 map-reduce 聚合后的結(jié)果:
>show collections
map_result_result
myColl
order
>db.map_result_result.find()
{ "_id" : "l", "value" : 50.0 }
{ "_id" : "2", "value" : 25.0 }
{ "_id" : "3", "value" : 55.0 }