TLDR:运行Mongo Shell命令时,ObjectId("LowerCaseHexString")
和ObjectId("UpperCaseHexString")
之间没有区别。
对我来说只是一个粗心的错误......
原版Qn:
我刚刚在Mongo Shell中执行了几个命令,删除子文档中的一些数组元素时,发现了一些 非常 的古怪行为。 / p>
这与构造对象ID时是否使用大写或小写十六进制字符串有关,即ObjectId("UpperOrLowerCaseString")
首先,这两个查询都返回文档:
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")}})
预期。尝试从子文档中的$pull
元素时 HOWEVER ,以下查询有效:
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字节形式。
希望这对我来说不是一个错误(很容易出现这些错误)......
但是有人想关注一些事情吗?特别是我的findOne
和update
查询之间的行为不一致?
如果确实将完整的字符串值用于比较,那么表现不是很令人担忧吗?即每次比较24个字节而不仅仅是12个字节?
答案 0 :(得分:2)
使用相同十六进制值的小写或大写版本产生的ObjectID没有区别。您会看到不同的结果,因为您在两种情况下使用不同的十六进制值:
ObjectId("54b4ef540000000000000000")
... ^^
ObjectId("54B4EDC40000000000000000")