32

我有一个简单的工具,用于构建文档集合,然后自动将它们格式化为 EPUB 或 LaTeX 渲染,编写在 ExpressJS 之上。我正在使用 Coffeescript,如果这很重要(我对此表示怀疑)。

使用猫鼬,我有以下内容:

DocumentSchema = new Schema
    title:     String

Offrefs = new Schema
    ref:       { type: ObjectId }
    isa:       String

BinderSchema = new Schema
    title:     String
    contains:  [Offrefs]

Offrefs 没有指定它所指的内容,因为我希望能够在其他活页夹中包含一些活页夹,以创建逻辑集合:“这些用于打印机,”“这些用于 epub”,“这些仅用于网络, "等(我已经把所有杂项都去掉了。)

不幸的是,我遇到了查询,对于检索到的对象

(story._id == offref.ref) -> True 

而且两者确实看起来一样。但:

(binder._id == offref.ref) -> False
(String(binder._id) == String(offref.ref)) -> True

并且对最后两个中的两个引用进行视觉比较,它们相同的 ID 号,但ObjectId对象没有正确比较。

我不想不断地进行字符串转换,当我将这些复杂的对象转换为数据树时,这是一个很大的可能性。树关系在任何数据库中都是熊;它们在 MongoDB 中应该不难。

你如何在 MongoDB 中进行 ObjectId 比较?

4

2 回答 2

96

直接==(或===)比较将通过引用而不是值来比较两个对象。因此,只有当它们都引用相同的实例时,才会评估为 true。

相反,您应该使用 的equals方法ObjectID来比较它们的值:

story._id.equals(offref.ref)

正如@bendytree 在评论中指出的那样,如果任何一个值都可以为空(并且您希望空值比较相等),那么您可以改用以下内容:

String(story._id) === String(offref.ref)
于 2012-06-16T03:32:19.023 回答
1

这在一定程度上超出了最初提出的问题,但我发现 ObjectID 的 .equals 方法在某些情况下会返回 false,即使值不为空,字符串比较也会返回 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模式创建的Collection,而linkedOwningUser(也是一个ObjectID)来自一个不是使用Mongoose创建的Collection(只是常规的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"
            ]
        }
    ]
}

所以,作为我的底线,我将使用字符串比较技术来比较 ObjectID,而不是 .equals 方法。

于 2016-07-11T01:58:37.457 回答