80

我想知道 mongodb 在进行如下查询时如何比较“_id”字段:

db.data.find({"_id":{$gt:ObjectId("502aa46c0674d23e3cee6152")}}).sort({"_id":1}).limit(10);

它是否纯粹基于 id 的时间戳部分?

4

3 回答 3

66

稍微扩展安德烈所说的话:

由于 ObjectID 时间戳只是第二个,因此可以轻松地创建两个(或更多)ObjectID,并使用相同的时间戳值(前 4 个字节)。如果它们是在同一台机器上创建的(机器 ID - 接下来的 3 个字节),由同一个进程(PID - 接下来的 2 个字节),那么唯一可以区分它们的是“inc”字段,即最后 3 个字节在最后。

更新:2020 年 1 月

这个答案仍然很受欢迎,所以值得更新一下。自 8 年前编写此答案以来,ObjectID 规范已经发展,时间戳后的 5 个字节现在只是随机的,这将大大降低任何冲突的可能性。最后三个字节仍然是递增的,但以随机值初始化,再次降低了冲突的可能性。ObjectID 现在包含更少的上下文(您不能轻易地知道它是在哪里生成的以及由什么过程生成的),但我猜想该信息没有以任何有意义的方式被使用,并且已被弃用,以支持更好的 ID 随机化。

结束更新

有关完整规格,请参见此处:

https://docs.mongodb.com/manual/reference/method/ObjectId/#ObjectIDs-BSONObjectIDSpecification

该“inc”字段要么是一个不断递增的字段(那么您可以合理地期望排序按照插入/创建顺序)或一个随机值(然后可能是唯一的,但不是有序的),当然假设规范是正确实现的. 请注意,ObjectID 可能由驱动程序或应用程序(或实际上是手动)而不是由 MongoDB 本身生成,因此除非您完全控制它们的生成方式,否则上述任何或全部都可能适用。

于 2012-08-23T21:11:43.643 回答
33

在某种程度上你是正确的,如果你_id按插入时间排序,你将按插入时间排序。这并不意味着唯一的比较是在时间戳部分上完成的。ObjectID 本身就是一个 BSON 对象类型,它们可以直接相互比较。由于它们以时间戳开始,因此从逻辑上讲,过去的时间将少于未来的时间。

您可以在文档中找到更多详细信息

于 2012-08-23T19:51:36.167 回答
18

从 Mongo 规范复制粘贴 https://docs.mongodb.com/manual/reference/bson-types/#objectid

ObjectId 值的顺序与生成时间的关系在单秒内并不严格。如果多个系统,或单个系统上的多个进程或线程生成值,在一秒钟内;ObjectId 值不代表严格的插入顺序。客户端之间的时钟偏差也可能导致非严格排序,即使对于值也是如此,因为客户端驱动程序生成 ObjectId 值,而不是 mongod 进程。

于 2014-07-22T11:51:08.213 回答