在第一章中我們對(duì) find
命令做了一個(gè)初步的了解。除了 selectors
以外 find
還有更豐富的功能。我們已經(jīng)說(shuō)過(guò),find
返回的結(jié)果是一個(gè) cursor
。我們將進(jìn)一步看看它到底是什么意思。
在開(kāi)始 cursors
的話題之前,你應(yīng)該知道 find
有第二個(gè)可選參數(shù),叫做 "projection"。這個(gè)參數(shù)是我們要檢索或者排除字段的列表。比如,我們可以僅查詢返回獨(dú)角獸的名字而不帶別的字段:
db.unicorns.find({}, {name: 1});
默認(rèn)的,_id
字段總是會(huì)返回的。我們可以通過(guò)這樣顯式的把它從返回結(jié)果中排除 {name:1, _id: 0}
。
除了 _id
字段,你不能把檢索和排除混合使用。仔細(xì)想想,這是有道理的。你只能顯式的檢索或者排除某些字段。
到目前為止我已經(jīng)提到好多次, find
返回的是一個(gè)游標(biāo),它只有在需要的時(shí)候才會(huì)執(zhí)行。但是,你在 shell 中看到的確實(shí)是 find
被立刻執(zhí)行了。這只是 shell 的行為。 我們可以通過(guò)一個(gè) find
的鏈?zhǔn)椒椒?,觀察到 cursors
的真正行為。我們來(lái)看看 sort
。我們指定我們希望排序的字段,以 JSON 方式,其中 1 表示升序 -1 表示降序。比如:
//heaviest unicorns first
db.unicorns.find().sort({weight: -1})
//by unicorn name then vampire kills:
db.unicorns.find().sort({name: 1,
vampires: -1})
就像關(guān)系型數(shù)據(jù)庫(kù)那樣,MongoDB 允許對(duì)索引進(jìn)行排序。我們?cè)偕院髮⒃敿?xì)討論索引。那,你應(yīng)該知道的是,MongoDB 對(duì)未經(jīng)索引的字段進(jìn)行排序是有大小限制的。就是說(shuō),如果你試圖對(duì)一個(gè)非常大的沒(méi)有經(jīng)過(guò)索引的結(jié)果集進(jìn)行排序的話,你會(huì)得到個(gè)異常。有些人認(rèn)為這是一個(gè)缺點(diǎn)。說(shuō)實(shí)話,我是多希望更多的數(shù)據(jù)庫(kù)可以有這種能力去拒絕未經(jīng)優(yōu)化的查詢。(我不是把每個(gè) MongoDB 的缺點(diǎn)硬說(shuō)成優(yōu)點(diǎn),但是我已經(jīng)看夠了那些缺乏優(yōu)化的數(shù)據(jù)庫(kù)了,我真心希望他們能有一個(gè) strict-mode。)
對(duì)結(jié)果分頁(yè)可以通過(guò) limit
和 skip
游標(biāo)方法來(lái)實(shí)現(xiàn)。比如要獲取第二和第三重的獨(dú)角獸,我們可以這樣:
db.unicorns.find()
.sort({weight: -1})
.limit(2)
.skip(1)
通過(guò) limit
和 sort
的配合,可以在對(duì)非索引字段進(jìn)行排序時(shí)避免引起問(wèn)題。
shell 中可以直接對(duì)一個(gè)集合執(zhí)行 count
,像這樣:
db.unicorns.count({vampires: {$gt: 50}})
實(shí)際上,count
是一個(gè) cursor
的方法,shell 只是簡(jiǎn)單的提供了一個(gè)快捷方式。以不提供快捷方式的方法來(lái)執(zhí)行的時(shí)候需要這樣(在 shell 中同樣可以執(zhí)行):
db.unicorns.find({vampires: {$gt: 50}})
.count()
使用 find
和 cursors
非常簡(jiǎn)單。還講了一些我們后面章節(jié)會(huì)用到的或是非常特殊情況才用的命令,不過(guò)不管怎樣,現(xiàn)在,你應(yīng)該已經(jīng)非常熟練使用 mongo shell 以及理解 MongoDB 的基本原則了。
更多建議: