Mongo ObjectId 如何在内部进行比较?

How is Mongo ObjectId Compared Internally?

TLDR:当运行 Mongo Shell命令时,ObjectId("LowerCaseHexString")ObjectId("UpperCaseHexString")没有区别。

只是我的一个粗心错误...

原Qn:

我刚刚注意到一些 非常 奇怪的行为,同时执行几个命令,删除子中的一些数组元素文档,在 Mongo Shell.

这与构造对象 ID 时是否使用 大写小写 十六进制字符串有关,即 ObjectId("UpperOrLowerCaseString")

首先,这两个查询 return 文档:

db.users.findOne({"id":1, "SubDoc._id":{$lt: ObjectId("54B4EF540000000000000000")}})
db.users.findOne({"id":1, "SubDoc._id":{$lt: ObjectId("54b4ef540000000000000000")}})

而这两个都不是(注意 $lt 已替换为 $gt):

db.users.findOne({"id":1, "SubDoc._id":{$gt: ObjectId("54B4EF540000000000000000")}})
db.users.findOne({"id":1, "SubDoc._id":{$gt: ObjectId("54b4ef540000000000000000")}})

这是意料之中的。 HOWEVER 当尝试 $pull 子文档中的元素时,以下查询有效:

db.users.update(
    {"id":1}, 
    {$pull:
        {"SubDoc":
            {_id: {$lt: ObjectId("54b4ef540000000000000000")}}
        }
    }
)

虽然这不是(注意从小写到大写的变化):

db.users.update(
    {"id":1}, 
    {$pull:
        {"SubDoc":
            {_id: {$lt: ObjectId("54B4EDC40000000000000000")}}
        }
    }
)

有趣的是,这个有效(注意 $lt 替换为 $gt):

db.users.update(
    {"id":1}, 
    {$pull:
        {"SubDoc":
            {_id: {$gt: ObjectId("54B4EDC40000000000000000")}}
        }
    }
)

这让我相信在 update 的情况下,实际的字符串值用于比较对象 ID(由于字节表示,小写字符串更大)。

findOne 的情况下,情况似乎并非如此,即对象 ID 在比较之前被转换为 12 字节形式。

希望这不是我的错误(很容易犯这些错误)...

但是有人愿意透露一些信息吗?特别是关于我的 findOneupdate 查询之间的行为不一致?

如果确实将完整的字符串值用于比较,那么这不是非常令人担忧的性能明智吗? IE。每次比较 24 个字节而不是 12 个?

使用相同十六进制值的小写或大写版本所产生的 ObjectID 没有区别。您看到不同的结果,因为您在这两种情况下使用了不同的十六进制值:

ObjectId("54b4ef540000000000000000")
...            ^^
ObjectId("54B4EDC40000000000000000")