【发布时间】:2012-08-23 19:36:40
【问题描述】:
我想知道mongodb在进行如下查询时如何比较“_id”字段:
db.data.find({"_id":{$gt:ObjectId("502aa46c0674d23e3cee6152")}}).sort({"_id":1}).limit(10);
是否纯粹基于 id 的时间戳部分?
【问题讨论】:
标签: mongodb
我想知道mongodb在进行如下查询时如何比较“_id”字段:
db.data.find({"_id":{$gt:ObjectId("502aa46c0674d23e3cee6152")}}).sort({"_id":1}).limit(10);
是否纯粹基于 id 的时间戳部分?
【问题讨论】:
标签: mongodb
稍微扩展安德烈所说的:
由于 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 本身生成,因此除非您完全控制它们的生成方式,否则上述任何或全部都可能适用。
【讨论】:
ObjectId 或 auto increment 主键哪个更好?
在某种程度上您是正确的,如果您按_id 排序,您将按插入时间排序。这并不意味着唯一的比较是在时间戳部分上进行的。 ObjectID 本身就是一个 BSON 对象类型,它们可以直接相互比较。由于它们以时间戳开头,因此从逻辑上讲,过去的时间将少于未来的时间。
您可以在documentation中找到更多详细信息
【讨论】:
从 Mongo 规范复制粘贴 https://docs.mongodb.com/manual/reference/bson-types/#objectid
ObjectId 值的顺序与生成时间的关系在单秒内并不严格。如果多个系统,或单个系统上的多个进程或线程生成值,在一秒钟内; ObjectId 值不代表严格的插入顺序。客户端之间的时钟偏差也可能导致非严格排序,即使对于值也是如此,因为客户端驱动程序生成 ObjectId 值,而不是 mongod 进程。
【讨论】: