【问题标题】:MongoDB difference between $orderby and Sort$orderby 和 Sort 之间的 MongoDB 区别
【发布时间】:2014-07-31 11:41:02
【问题描述】:

我想获取最新的文档,这显然是一个文档,因此findOne 应该可以正常工作。但是findOne 这里返回插入的第一个文档。所以我现在有两个选择,要么使用$orderByfindOne,要么使用.sort() 函数和.limit().limit() 中@

使用 $orderBy 它看起来像:

db.collection.findOne({$query:{},$orderby:{_id:-1}}) 

并使用排序:

db.collection.find().sort({_id:-1}).limit(1).pretty()

两者都可以正常工作,我只是想知道我应该在这里更喜欢哪个查询?在性能方面,还是两者在内部工作方式相同,两者之间没有这种区别。

【问题讨论】:

    标签: mongodb mongoose


    【解决方案1】:

    从 Mongo 3.2 开始,$orderbydeprecated

    docs explicitly say:

    不推荐使用 $orderby 运算符。请改用 cursor.sort()。

    很遗憾,findOne() 不支持sort() 方法,因此您需要切换到find()

    db.collection.find({}).sort({'key': -1}).limit(1)
    

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

    【讨论】:

    • 要使用带有sort() 方法而不是已弃用的$orderby 的findOne 进行复制,您可以在此链末尾的光标上调用.next()。与 Mongo 3.2 兼容的 db.collection.findOne({$query: {}, $orderby: {_id: -1}}) 的完整等效项是:db.collection.find({}).sort({_id: -1}).limit(1).next()
    • 如果需要结果数组 - 只需添加 .toArray(),如下所示:db.collection.find({}).sort({'key': -1}).limit(1).toArray()
    【解决方案2】:

    它们是相同的,事实上$orderby 的文档页面实际上主要讨论的是提供的sort() 函数。

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

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

    db.collection.findOne({"$query":{},"$orderby":{ "_id": -1 }}) 
    

    但要注意的是:

    db.collection.findOne({}).sort({ "_id":-1})
    

    实际产生:

    2014-07-31T04:59:50.183-0700 TypeError: Object [object Object] has no method '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") }
    

    答案其实是正确的:

    > 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")
    }
    

    因此有趣的是,findOne 支持查询修饰符,而函数访问器则不支持,这可能是使用查询修饰符的原因。

    【讨论】:

    • 澄清一下:find 支持.sortfindOne 不支持的原因是find 返回一个游标对象,该对象上定义了一个.sort 方法来确定返回文档的顺序(只能在光标开始返回批量文档之前设置)。 findOne 返回零个或一个文档。 返回哪个文档由谁先根据$orderBy(如果已设置)确定。否则为natural order,即磁盘上文档的顺序。
    • @wdberkeley 确实忘了提到 findOne 没有返回光标,谢谢
    猜你喜欢
    • 2018-02-28
    • 1970-01-01
    • 1970-01-01
    • 2011-09-01
    • 2017-03-28
    • 1970-01-01
    • 2021-06-02
    • 1970-01-01
    • 2021-10-20
    相关资源
    最近更新 更多