MongoDB $ orderby和Sort之间的区别

Sam*_*rma 13 mongoose mongodb

我想获取最新的文档,这显然是一个单独的文档,因此findOne应该工作正常.但findOne这里返回插入的第一个文件.所以,我有两个选择现在要么使用$orderByfindOne或使用.sort()功能与.limit()find()

使用$ orderBy它看起来像:

db.collection.findOne({$query:{},$orderby:{_id:-1}}) 
Run Code Online (Sandbox Code Playgroud)

并使用排序:

db.collection.find().sort({_id:-1}).limit(1).pretty()
Run Code Online (Sandbox Code Playgroud)

两者都工作正常,我只是想知道我更喜欢哪个查询?在性能方面,或者两者在内部的工作方式相同,两者之间没有这种差异.

Jef*_*man 28

截至Mongo 3.2,$orderby已被弃用.

文件明确地说:

$ orderby运算符已弃用.请改用cursor.sort().

不幸的是,findOne()不支持该sort()方法,因此您需要切换到find():

db.collection.find({}).sort({'key': -1}).limit(1)
Run Code Online (Sandbox Code Playgroud)

这将返回a cursor,因此您需要从光标中提取第一个结果.

  • 要使用findOne和`sort()`方法而不是弃用的`$ orderby`进行复制,可以在此链末尾的光标上调用`.next()`.完全相当于:`db.collection.findOne({$ query:{},$ orderby:{_ id:-1}})与Mongo 3.2兼容的是``db.collection.find({}).sort( {_id:-1}).limit(1).next()` (6认同)
  • 如果需要结果数组 - 只需添加 `.toArray()`,就像这样:`db.collection.find({}).sort({'key': -1}).limit(1).toArray() ` (2认同)

Sam*_*aye 19

它们是相同的,实际上是$orderby 实际谈论的文档页面主要是关于提供的sort()功能.

这些查询修饰符允许您在不使用功能访问器的情况下添加查询的部分,但确实存在将这两者混合在一起的错误,因此我建议您选择查询修饰符或功能方法并坚持使用该选项.

在尝试提供示例代码时,我还发现了另一件事,当我再次查看您的问题时.你提供:

db.collection.findOne({"$query":{},"$orderby":{ "_id": -1 }}) 
Run Code Online (Sandbox Code Playgroud)

但值得注意的是:

db.collection.findOne({}).sort({ "_id":-1})
Run Code Online (Sandbox Code Playgroud)

实际产生:

2014-07-31T04:59:50.183-0700 TypeError:对象[object Object]没有方法'sort'

正如您在我的测试数据集中看到的那样:

> db.rooms.find()
{ "_id" : ObjectId("53ad206e1d8f2d8351182830"), "id" : 1, "from" : ISODate("2014-06-26T00:00:00Z"), "to" : ISODate("2014-06-28T00:00:00Z") }
{ "_id" : ObjectId("53ad276f1d8f2d8351182831"), "id" : 1, "from" : ISODate("2014-06-24T00:00:00Z"), "to" : ISODate("2014-07-01T00:00:00Z") }
{ "_id" : ObjectId("53ad28ad1d8f2d8351182832"), "id" : 1, "from" : ISODate("2014-06-20T00:00:00Z"), "to" : ISODate("2014-06-28T00:00:00Z") }
{ "_id" : ObjectId("53ad28c61d8f2d8351182833"), "id" : 1, "from" : ISODate("2014-06-20T00:00:00Z"), "to" : ISODate("2014-07-03T00:00:00Z") }
{ "_id" : ObjectId("53ad29971d8f2d8351182834"), "id" : 1, "from" : ISODate("2014-06-20T00:00:00Z"), "to" : ISODate("2014-06-21T00:00:00Z") }
Run Code Online (Sandbox Code Playgroud)

答案其实是正确的:

> db.rooms.findOne({ "$query":{}, "$orderby":{ "_id": -1 }})
{
        "_id" : ObjectId("53ad29971d8f2d8351182834"),
        "id" : 1,
        "from" : ISODate("2014-06-20T00:00:00Z"),
        "to" : ISODate("2014-06-21T00:00:00Z")
}
Run Code Online (Sandbox Code Playgroud)

因此,值得注意的是findOne,函数访问器不在哪里支持查询修饰符,这可能是使用查询修饰符的原因.

  • 澄清:`find`支持`.sort`而`findOne`的原因不是`find`返回一个游标对象,它上面定义了一个`.sort`方法,用于确定返回文档的顺序(并且只能在光标开始返回批量文档之前设置).`findOne`返回零个或一个文档.*返回哪个*文件取决于谁首先根据`$ orderBy`设置.否则它是[自然顺序](http://docs.mongodb.org/manual/reference/operator/meta/natural/),这是磁盘上文档的顺序. (4认同)