在第一章中我们对 `find` 命令做了一个初步的了解。除了 `selectors` 以外 `find` 还有更丰富的功能。我们已经说过,`find` 返回的结果是一个 `cursor`。我们将进一步看看它到底是什么意思。
## [](https://github.com/geminiyellow/the-little-mongodb-book/blob/master/zh-cn/mongodb.markdown#字段选择)字段选择
在开始 `cursors` 的话题之前,你应该知道 `find` 有第二个可选参数,叫做 "projection"。这个参数是我们要检索或者排除字段的列表。比如,我们可以仅查询返回独角兽的名字而不带别的字段:
~~~
db.unicorns.find({}, {name: 1});
~~~
默认的,`_id` 字段总是会返回的。我们可以通过这样显式的把它从返回结果中排除 `{name:1, _id: 0}`。
除了 `_id` 字段,你不能把检索和排除混合使用。仔细想想,这是有道理的。你只能显式的检索或者排除某些字段。
## [](https://github.com/geminiyellow/the-little-mongodb-book/blob/master/zh-cn/mongodb.markdown#排序ordering)排序(Ordering)
到目前位置我已经提到好多次, `find` 返回的是一个游标,它只有在需要的时候才会执行。但是,你在 shell 中看确实到的是 `find` 被立刻执行了。这只是 shell 的行为。 我们可以通过一个 `find` 的链式方法,观察到 `cursors` 的真正行为。我们来看看 `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})
~~~
就像关系型数据库那样,MongoDB 允许对索引进行排序。我们再稍后将详细讨论索引。那,你应该知道的是,MongoDB 对未经索引的字段进行排序是有大小限制的。就是说,如果你试图对一个非常大的没有经过索引的结果集进行排序的话,你会得到个异常。有些人认为这是一个缺点。说实话,我是多希望更多的数据库可以有这种能力去拒绝未经优化的查询。(我不是把每个 MongoDB 的缺点硬说成优点,但是我已经看够了那些缺乏优化的数据库了,我真心希望他们能有一个 strict-mode。)
## [](https://github.com/geminiyellow/the-little-mongodb-book/blob/master/zh-cn/mongodb.markdown#分页paging)分页(Paging)
对结果分页可以通过 `limit` 和 `skip` 游标方法来实现。比如要获取第二和第三重的独角兽,我们可以这样:
~~~
db.unicorns.find()
.sort({weight: -1})
.limit(2)
.skip(1)
~~~
通过 `limit` 和 `sort` 的配合,可以在对非索引字段进行排序时避免引起问题。
## [](https://github.com/geminiyellow/the-little-mongodb-book/blob/master/zh-cn/mongodb.markdown#计数count)计数(Count)
shell 中可以直接对一个集合执行 `count` ,像这样:
~~~
db.unicorns.count({vampires: {$gt: 50}})
~~~
实际上,`count` 是一个 `cursor` 的方法,shell 只是简单的提供了一个快捷方式。以不提供快捷方式的方法来执行的时候需要这样(在 shell 中同样可以执行):
~~~
db.unicorns.find({vampires: {$gt: 50}})
.count()
~~~
## [](https://github.com/geminiyellow/the-little-mongodb-book/blob/master/zh-cn/mongodb.markdown#小结-2)小结
使用 `find` 和 `cursors` 非常简单。还讲了一些我们后面章节会用到的或是非常特殊情况才用的命令,不过不管怎样,现在,你应该已经非常熟练使用 mongo shell 以及理解 MongoDB 的基本原则了。