MongoDB是否按创建时间查找()查询返回文档?

时间:2015-06-17 08:59:30

标签: mongodb sorting database

我需要按创建时间(从最旧到最新)排序的文档。

由于ObjectID默认保存时间戳,我们可以使用它来获取按创建时间CollectionName.find().sort({_id: 1})排序的文档。

另外,我注意到常规CollectionName.find()查询始终会以相同顺序返回与CollectionName.find().sort({_id: 1})相同的文档。

我的问题是:

CollectionName.find()是否保证以与CollectionName.find().sort({_id: 1})相同的顺序返回文档,以便我可以将整理出来?

2 个答案:

答案 0 :(得分:4)

  

CollectionName.find()保证以与CollectionName.find()相同的顺序返回文档.sort({_ id:1})

不,它不是!如果您没有指定任何订单,那么所谓的"自然"使用订购。这意味着文档将按照它们实际出现在数据文件中的顺序返回。

现在,如果您只插入文档而从不修改它们,则此自然顺序将与升序_id顺序一致。但是,想象一下,您以一种大小增长的方式更新文档,并且必须将其移动到数据文件内的空闲插槽(通常这意味着文件末尾的某处)。如果您现在要查询文档,他们就不会遵循任何合理的(对外部观察员)订单。

因此,如果您关心订单,请明确说明。

来源:http://docs.mongodb.org/manual/reference/glossary/#term-natural-order

  

自然顺序

     

数据库引用磁盘上文档的顺序。这是默认的排序顺序。参见$ natural和Return in Natural Order。

测试脚本(困惑)

> db.foo.insert({name: 'Joe'})
WriteResult({ "nInserted" : 1 })

> db.foo.insert({name: 'Bob'})
WriteResult({ "nInserted" : 1 })

> db.foo.find()
{ "_id" : ObjectId("55814b944e019172b7d358a0"), "name" : "Joe" }
{ "_id" : ObjectId("55814ba44e019172b7d358a1"), "name" : "Bob" }

> db.foo.update({_id: ObjectId("55814b944e019172b7d358a0")}, {$set: {answer: "On a sharded collection the $natural operator returns a collection scan sorted in natural order, the order the database inserts and stores documents on disk. Queries that include a sort by $natural order do not use indexes to fulfill the query predicate with the following exception: If the query predicate is an equality condition on the _id field { _id: <value> }, then the query with the sort by $natural order can use the _id index. You cannot specify $natural sort order if the query includes a $text expression."}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

> db.foo.find()
{ "_id" : ObjectId("55814ba44e019172b7d358a1"), "name" : "Bob" }
{ "_id" : ObjectId("55814b944e019172b7d358a0"), "name" : "Joe", "answer" : "On a sharded collection the $natural operator returns a collection scan sorted in natural order, the order the database inserts and stores documents on disk. Queries that include a sort by $natural order do not use indexes to fulfill the query predicate with the following exception: If the query predicate is an equality condition on the _id field { _id: <value> }, then the query with the sort by $natural order can use the _id index. You cannot specify $natural sort order if the query includes a $text expression." }

答案 1 :(得分:4)

没有。好吧,不完全是。 db.collection.find()将按照它们在数据文件主机中出现的顺序为您提供文档,但这不能保证。

  

结果排序

     

除非指定sort()方法或使用$ near运算符,否则MongoDB不保证查询结果的顺序。

只要您的数据文件相对较新并且几乎没有更新,文档可能(并且大部分时间)将以_id的方式返回,因为ObjectId是单调增加的。

在生命周期的后期,旧文档可能已经从旧位置移开(因为它们的大小增加,文档从未被分区),而新文档则被写入以前由另一个文档占用的位置。在这种情况下,可以在两个旧文档之间的位置返回较新的文档。

_id排序文档没有任何问题,因为索引将用于此,只为文档检索添加一些延迟。

但是,我强烈建议不要将ObjectId用于日期操作,原因如下:

  1. ObjectIds不能用于日期比较查询。因此,您无法查询在日期x和日期y之间创建的所有文档。要归档它,你必须加载所有文档,从ObjectId中提取日期并进行比较 - 这是非常低效的。
  2. 如果创建日期很重要,则应在文档
  3. 中明确说明
  4. 我认为ObjectIds是_id字段的最后选择,并倾向于使用其他值(偶尔复合)作为_id,因为该字段默认为索引,并且非常很可能通过使用更有意义的值作为id来节省宝贵的RAM。
  5. 您可以使用以下内容,例如使用DBRef s

    {
      _id: {
        creationDate: new ISODate(),
        user: { 
          "$ref" : "creators",
          "$id" : "mwmahlberg",
          "$db" : "users"
        }
      }
    }
    

    使用

    做一个非常便宜的排序
    db.collection.find().sort({_id.creationDate:1})