2

翡翠模板代码

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

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

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

#{user.id} 的值为53fecc27bace957811633dcc

但是,此比较返回为 false,并且 flag 永远不会设置为 true。为什么会这样?

4

2 回答 2

3

为清晰而编辑:

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

这是我正在谈论的一个简化示例。在下面的示例中,我有一个TestObject(模拟 mongo ObjectID)的构造函数。我用相同的参数实例化两个对象(即x1和)。x2虽然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;  
于 2014-09-26T14:11:39.547 回答
1

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

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

于 2014-09-26T14:08:03.510 回答