【问题标题】:Comparing ObjectID's in Jade and MongoDB比较 Jade 和 MongoDB 中的 ObjectID
【发布时间】:2014-09-26 13:02:43
【问题描述】:

翡翠模板代码

    each member in team.members
      if member == user._id
       - flag=true;  

这里,team 是 Mongo DB 中“teams”集合中的一个文档,“members”是一个以数组为值的属性。

这里#{member} 的值分别是53fecc27bace957811633dcc5412a08fa51c105017b9f1fe。两者都是对象 ID。

#{user.id} 的值为53fecc27bace957811633dcc

但是,此比较返回为假,并且标志永远不会设置为真。 为什么会这样?

【问题讨论】:

    标签: mongodb variables comparison pug objectid


    【解决方案1】:

    为清晰而编辑:

    mongodb-native 驱动使用自定义的 ObjectID 类型。即使 ObjectID 相同,memberuser._id 仍然会引用两个不同的对象,因此比较失败。

    这是我所说的一个简化示例。在下面的示例中,我有一个 TestObject 的构造函数(模拟 mongo ObjectID)。我用相同的参数实例化了两个对象(即x1x2)。虽然x1x2 是同一个对象的实例并且都使用相同的参数创建,但它们实际上只是具有相同数据/有效负载的两个不同对象。因此,第一次直接比较失败了,因为它们实际上并不相同。为了进一步模拟,我添加了一个原型方法.equals(),它确保两个对象都是 TestObject 的实例并且有效负载相同。

    function TestObject(data) {
        this.payload = data;
    }
    TestObject.prototype.equals = function(anotherObject) {
        return (anotherObject instanceof TestObject) && (this.payload === anotherObject.payload);  
    };
    
    var x1 = new TestObject(1), x2 = new TestObject(1);
    
    console.log(x1 == x2); // <-- false
    console.log(x1.equals(x2)); // <-- true
    

    您可以通过将 ObjectID 转换为字符串来比较它们。

    each member in team.members
      if member.toString() == user._id.toString()
       - flag=true;
    

    另一种可能的解决方案是使用 ObjectId .equal() 方法:

    each member in team.members
      if member.equals(user._id)
       - flag=true;  
    

    【讨论】:

    • 我们将理解为什么早期方案不起作用的原因。
    • 我假设您使用的是 Mongoose,它使用 mongodb-native 驱动程序。 mongodb-native 驱动使用自定义的 ObjectID 类型。即使 ObjectID 相同,member 和 user._id` 指的是两个不同的对象,因此比较失败。只有两种方法可以比较这些自定义 ObjectID:(1).equals() 方法(例如member.equals(user._id)),或(2)使用我在上面的回答中演示的.toString()
    【解决方案2】:

    MongoDB objectIds 可能不是简单的字符串。根据docs,它们是 BSON 类型。 member 和 user._id 可能是两个不同的对象,这就是“引用等于”比较失败的原因,即使它们的字符串表示形式相同。

    在相关说明中,在您的应用程序中使用 MongoDB 生成的对象 ID 是一个坏主意。更健壮的设计是为每种记录类型设置自己的标识符。

    【讨论】:

    • 那么,如果我将一个对象 id 存储在另一个对象 x 中,您的意思是说 x 不再是一个 objectid?
    • @Aniket Lawande 想说的是,虽然这两个对象仍然是 ObjectID,但就 Mongoose 而言,它们代表相同的 ObjectID,就 JavaScript(因此 Jade)而言,它们是两个不同的对象,即使它们属于相同类型并且具有相同的有效负载(ObjectID 引用)。我编辑了原始答案以使用简单的自定义对象来模拟问题。
    猜你喜欢
    • 1970-01-01
    • 2015-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-03
    • 2014-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多