2020重新出發(fā)唉侄,NOSQL咒吐,MongoDB的操作和索引

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 個問題锁荔。

  1. 當調(diào)用 find() 函數(shù)時,Shell 并不立即查詢數(shù)據(jù)庫蝙砌,而是等真正開始獲取結(jié)果時才發(fā)送查詢請求阳堕。

  2. 游標對象的每個方法幾乎都會返回游標對象本身,這樣可以方便進行鏈式函數(shù)的調(diào)用择克。

  3. 在 MongoDB Shell 中使用游標輸出文檔包含兩種情況恬总,如果不將 find() 函數(shù)返回的游標賦值給一個局部變量進行保存,在默認情況下游標會自動迭代 20 次肚邢。如果將 find() 函數(shù)返回的游標賦值給一個局部變量壹堰,則可以使用游標對象提供的函數(shù)進行手動迭代。

  4. 使用清空后的游標骡湖,進行迭代輸出時贱纠,顯示的內(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)算法形成的碘饼。樹索引存儲特定字段或字段集的值,按字段值排序悲伶。索引條目的排序支持有效的等式匹配和基于范圍的查詢操作艾恼。

下圖所示的過程說明了使用索引選擇和排序匹配文檔的查詢過程。

img

從根本上說麸锉,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)用程序和用戶可以添加額外的索引來支持重要的查詢操作脚粟,單鍵索引可參考下圖。

img

對于單字段索引和排序操作蘸朋,索引鍵的排序順序(即升序或降序)無關(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)包含多個字段,下圖說明了兩個字段的復合索引示例齐疙。

img

復合索引可以支持在多個字段上進行的匹配查詢膜楷,語法結(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ù)組字段的高效查詢特愿,如圖所示。

img

創(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ù)。聚合管道可以在分片集合上運行贞滨。

聚合管道方法的流程參見下圖入热。

img

上圖的聚合操作相當于 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ù)字型字段尤蒿,如 sum郑气、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 }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市搀矫,隨后出現(xiàn)的幾起案子抹沪,更是在濱河造成了極大的恐慌,老刑警劉巖瓤球,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件融欧,死亡現(xiàn)場離奇詭異,居然都是意外死亡冰垄,警方通過查閱死者的電腦和手機蹬癌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來虹茶,“玉大人逝薪,你說我怎么就攤上這事『铮” “怎么了董济?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長要门。 經(jīng)常有香客問我虏肾,道長廓啊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任封豪,我火速辦了婚禮谴轮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吹埠。我一直安慰自己第步,他們只是感情好,可當我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布缘琅。 她就那樣靜靜地躺著粘都,像睡著了一般。 火紅的嫁衣襯著肌膚如雪刷袍。 梳的紋絲不亂的頭發(fā)上翩隧,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天,我揣著相機與錄音呻纹,去河邊找鬼堆生。 笑死,一個胖子當著我的面吹牛雷酪,可吹牛的內(nèi)容都是我干的顽频。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼太闺,長吁一口氣:“原來是場噩夢啊……” “哼糯景!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起省骂,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蟀淮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后钞澳,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體怠惶,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年轧粟,在試婚紗的時候發(fā)現(xiàn)自己被綠了策治。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡兰吟,死狀恐怖通惫,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情混蔼,我是刑警寧澤履腋,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響遵湖,放射性物質(zhì)發(fā)生泄漏悔政。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一延旧、第九天 我趴在偏房一處隱蔽的房頂上張望谋国。 院中可真熱鬧,春花似錦迁沫、人聲如沸烹卒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至逢勾,卻和暖如春牡整,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背溺拱。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工逃贝, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人迫摔。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓沐扳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親句占。 傳聞我的和親對象是個殘疾皇子沪摄,可洞房花燭夜當晚...
    茶點故事閱讀 45,066評論 2 355