返回MongoDB中ID周围的文档范围

时间:2014-02-22 00:01:40

标签: mongodb mongodb-query

我有一份文件的ID,需要退回文件加上之前的10份文件和之后的10份文件。总共21个文档。

我没有任何键的开始或结束值。只有两个方向的限制。

最好的方法吗?提前谢谢。

2 个答案:

答案 0 :(得分:6)

您知道ObjectID's包含时间戳吗?因此,它们始终代表自然的插入顺序。因此,如果您在知道文档_id之后查找文档,则可以执行此操作:

我们的文件:

{ "_id" : ObjectId("5307f2d80f936e03d1a1d1c8"), "a" : 1 }
{ "_id" : ObjectId("5307f2db0f936e03d1a1d1c9"), "b" : 1 }
{ "_id" : ObjectId("5307f2de0f936e03d1a1d1ca"), "c" : 1 }
{ "_id" : ObjectId("5307f2e20f936e03d1a1d1cb"), "d" : 1 }
{ "_id" : ObjectId("5307f2e50f936e03d1a1d1cc"), "e" : 1 }
{ "_id" : ObjectId("5307f2e90f936e03d1a1d1cd"), "f" : 1 }
{ "_id" : ObjectId("5307f2ec0f936e03d1a1d1ce"), "g" : 1 }
{ "_id" : ObjectId("5307f2ee0f936e03d1a1d1cf"), "h" : 1 }
{ "_id" : ObjectId("5307f2f10f936e03d1a1d1d0"), "i" : 1 }
{ "_id" : ObjectId("5307f2f50f936e03d1a1d1d1"), "j" : 1 }
{ "_id" : ObjectId("5307f3020f936e03d1a1d1d2"), "j" : 1 }

所以我们知道“f”的_id,得到它和接下来的两个文件:

> db.items.find({ _id: {$gte: ObjectId("5307f2e90f936e03d1a1d1cd") } }).limit(3)

{ "_id" : ObjectId("5307f2e90f936e03d1a1d1cd"), "f" : 1 }
{ "_id" : ObjectId("5307f2ec0f936e03d1a1d1ce"), "g" : 1 }
{ "_id" : ObjectId("5307f2ee0f936e03d1a1d1cf"), "h" : 1 }

反过来做同样的事情:

> db.items.find({ _id: {$lte: ObjectId("5307f2e90f936e03d1a1d1cd") } })
    .sort({ _id: -1 }).limit(3)
{ "_id" : ObjectId("5307f2e90f936e03d1a1d1cd"), "f" : 1 }
{ "_id" : ObjectId("5307f2e50f936e03d1a1d1cc"), "e" : 1 }
{ "_id" : ObjectId("5307f2e20f936e03d1a1d1cb"), "d" : 1 }

这比扫描集合更好 更好。

答案 1 :(得分:1)

Neil的回答是对所述问题的一个很好的答案(假设您使用的是自动生成的ObjectIds),但请记住,在给定文档之前和之后,10个文档的概念存在一些微妙之处。

ObjectId的完整格式记录为here。请注意,它包含以下字段:

  • 时间戳到1秒的分辨率,
  • 机器标识符
  • 进程ID
  • 计数器

通常,如果您未指定自己的_ids,则它们将由客户端计算机上的驱动程序自动生成。因此,只要在客户机上的单个进程上生成ObjectId,它们的顺序确实反映了它们的生成顺序,在典型的应用程序中也将是插入顺序(但不一定是)。但是,如果您有多个进程或多个客户端计算机,那么多个源在给定秒内生成的对象的ObjectIds顺序与插入顺序之间存在不可预测的关系。