Mongoose:ObjectId比较失败不一致
我有一个直接的工具来构build文档集合,然后自动格式化它们,以便在ExpressJS上编写EPUB或LaTeX渲染。 我使用Coffeescript,如果重要的话(我怀疑它)。
使用mongoose,我有以下几点:
DocumentSchema = new Schema title: String Offrefs = new Schema ref: { type: ObjectId } isa: String BinderSchema = new Schema title: String contains: [Offrefs]
Offrefs没有指定它引用的内容,因为我希望能够在其他活页夹中包含一些活页夹,以创build逻辑集合:“这些用于打印机”,“这些用于epub”,“这些仅限于Web, “等等(我已经把所有的杂项都删掉了。)
不幸的是,我已经跑到查询的地方,为检索的对象
(story._id == offref.ref) -> True
而且两人确实看起来一样。 但:
(binder._id == offref.ref) -> False (String(binder._id) == String(offref.ref)) -> True
和最后两个引用中的两个ObjectId
比较,它们是相同的ID号,但ObjectId
对象不能正确比较。
我不想不断地进行string转换,当我将这些复杂的对象转换为数据树时,这是一个很大的可能性。 任何数据库中的树关系都是熊; 在MongoDB中它们不应该很难。
你如何在MongoDB中进行ObjectId比较?
直==
(或===
)比较将通过引用来比较这两个对象,而不是值。 所以只有当它们都引用同一个实例时才会评估为真。
相反,你应该使用ObjectID
的equals
方法来比较它们的值:
story._id.equals(offref.ref)
正如@bendytree在注释中指出的那样,如果两个值中的任何一个值都可以为null(并且您希望空值相等),则可以使用下面的代码:
String(story._id) === String(offref.ref)
这超出了最初提出的问题,但我发现ObjectID的.equals方法在某些情况下返回false,即使值不为null,string比较也会返回true。 例:
var compare1 = invitationOwningUser.toString() === linkedOwningUser.toString(); var compare2 = invitationOwningUser.equals(linkedOwningUser); var compare3 = String(invitationOwningUser) === String(linkedOwningUser); logger.debug("compare1: " + compare1 + "; " + "compare2: " + compare2 + "; " + "compare3: " + compare3);
输出:
compare1: true; compare2: false; compare3: true
当invitationOwningUser(ObjectID)来自使用Mongoose模式创build的集合,而linkedOwningUser(也是ObjectID)来自不是使用Mongoose创build的集合(只是常规的MongoDB方法)时,就会发生这种情况。
这是包含invitationOwningUser(owningUser字段)的文档:
{ "_id" : ObjectId("5782faec1f3b568d58d09518"), "owningUser" : ObjectId("5781a5685a06e69b158763ea"), "capabilities" : [ "Read", "Update" ], "redeemed" : true, "expiry" : ISODate("2016-07-12T01:45:18.017Z"), "__v" : 0 }
这是包含linkedOwningUser(owningUser字段)的文档:
{ "_id" : ObjectId("05fb8257c95d538d58be7a89"), "linked" : [ { "owningUser" : ObjectId("5781a5685a06e69b158763ea"), "capabilities" : [ "Read", "Update" ] } ] }
所以,作为我的底线,我将使用string比较技术来比较ObjectID,而不是.equals方法。