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比较?

== (或=== )比较将通过引用来比较这两个对象,而不是值。 所以只有当它们都引用同一个实例时才会评估为真。

相反,你应该使用ObjectIDequals方法来比较它们的值:

 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方法。