在MongoDB集合中,如何检索给定记录的前一个记录?

3

我对使用MongoDB还比较陌生。

我需要检索MongoDB集合中给定记录的前一条记录。

  1. 是否可以通过"_id = ObjectId(...)"字段来实现?
  2. 如果不行,那么我们是否需要显式插入一个带有顺序值的键来标识给定记录的前一条记录?(假设当前集合中没有顺序键/值对)

非常感谢任何帮助。

2个回答

4

一切都相等的情况下,_id字段的默认值是一个单调递增的ObjectId

这意味着,如果已知一个ObjectId值,则可以使用以下方法检索在其之前插入的文档:

db.collection.find(
    { "_id": { "$lt": ObjectId("538c271a19b3a188ca6135eb") }}
).sort({ "_id": -1 }).limit(1)

这是一般情况。唯一可能的变化是不同来源生成ObjectId值,并且它们的时钟设置为不同的时间(例如完全不同的UTC时间)。

因此,结合插入速率,您可以考虑是否对您足够好。除了罕见且管理不善的情况之外,应该永远不会出现顺序未被保留的情况。


2

我建议您使用索引以获得最佳性能。

例如: 创建索引:

db.books.ensureIndex({book: 1}) // for next records in collection
db.books.ensureIndex({book: -1}) // for previous records in collection

下一个查询看起来像这样:
db.books.find({book: {$gt:"a"}}).sort({book: 1}).hint({book: 1}).limit(1)

之前的查询看起来像这样:

db.books.find({book: {$lt:"b"}}).sort({book: -1}).hint({book: -1}).limit(1)

1
也许我应该指出,_id字段始终被索引,并且对于优化器来说是最快的访问点,因为它是始终存在的主索引。 - undefined
非常感谢大家宝贵的反馈。我已经使用Scala中的Casbah编写了下面的代码,用于指定索引。请问我是否走在正确的道路上。val collection = MongoConnection()(<数据库名称>)(<集合名称>) collection.ensureIndex(DBObject("days"-> 1)) val record = (collection.find("days" $lt begin)).sort(MongoDBObject("days" -> -1)).limit(1) - undefined
@hel 不确定为什么你接受了与你实际提问相反的答案。我只是在这个答案之后才参与讨论,而且我已经提供了一个解答。如果你想要插入顺序,请使用已经解释过的_id字段。 - undefined
对于任何错误的标记,我们表示歉意。实际上,有两个集合,一个我们需要通过"_id"字段关注插入顺序,另一个集合我们需要关注一个"自定义字段"的降序排列,而不考虑插入顺序。因此,这两个答案对我们非常有帮助。再次感谢您分享宝贵的技术。 - undefined
注意:对于简单索引情况(或者在复合索引中按照最后一个字段排序的情况),您不需要创建正向和反向索引。同一个索引可以用于任何方向的排序。此外,除非是极少数情况,您几乎不需要使用hint()来指定索引的使用。强制使用提示会迫使查询优化器使用特定的索引,除非您确定查询优化器没有正确处理,否则应该谨慎使用。您可以通过explain(true)查看查询计划的详细信息。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接