比较mongoose _id和字符串

我有一个node.js应用程序,它提取一些数据并将其粘贴到一个对象中,就像这样:

var results = new Object();


User.findOne(query, function(err, u) {
results.userId = u._id;
}

当我基于存储的ID执行if/then时,比较永远不会为真:

if (results.userId == AnotherMongoDocument._id) {
console.log('This is never true');
}

当我对这两个id执行console.log时,它们完全匹配:

User id: 4fc67871349bb7bf6a000002 AnotherMongoDocument id: 4fc67871349bb7bf6a000002

我假设这是某种数据类型问题,但我不确定如何转换结果。userId转换为一个数据类型,这将导致上述比较是正确的,我的外包大脑(又名谷歌)一直无法提供帮助。

165343 次浏览

__abc0是对象,所以如果你只是将它们与==比较,你是在比较它们的引用。如果你想比较它们的值,你需要使用ObjectID.equals方法:

if (results.userId.equals(AnotherMongoDocument._id)) {
...
}

Mongoose使用mongodb-native驱动程序,该驱动程序使用定制的ObjectID类型。你可以用.equals()方法比较objectid。在你的例子中,results.userId.equals(AnotherMongoDocument._id)。ObjectID类型还有一个toString()方法,如果你希望以JSON格式存储ObjectID的字符串化版本,或者一个cookie。

如果你使用ObjectID = require("mongodb").ObjectID(需要mongodb-native库),你可以用results.userId instanceof ObjectID检查results.userId是否是一个有效的标识符。

等。

公认的答案确实限制了您可以用代码做的事情。例如,你不能使用equals方法搜索Object Ids的数组。相反,总是强制转换为字符串并比较键会更有意义。

下面是一个示例答案,以防你需要使用indexOf()在引用数组中检查特定id。假设query是你正在执行的查询,假设someModel是你正在寻找的id的mongo模型,最后假设results.idList是你正在寻找对象id的字段。

query.exec(function(err,results){
var array = results.idList.map(function(v){ return v.toString(); });
var exists = array.indexOf(someModel._id.toString()) >= 0;
console.log(exists);
});

将对象id转换为字符串(使用toString()方法)将完成这项工作。

我遇到了完全相同的问题,我只是在JSON.stringify()的帮助下解决了这个问题,如下所示

if (JSON.stringify(results.userId) === JSON.stringify(AnotherMongoDocument._id)) {
console.log('This is never true');
}

根据以上,我找到了三种解决问题的方法。

  1. AnotherMongoDocument._id.toString()
  2. JSON.stringify(AnotherMongoDocument._id)
  3. results.userId.equals(AnotherMongoDocument._id)

这里建议的三个可能的解决方案有不同的用例。

  1. 在两个mongodocument上比较ObjectId时使用.equals
results.userId.equals(AnotherMongoDocument._id)
  1. 当比较ObjectId的字符串表示形式和mongoDocument的ObjectId时,使用.toString()。像这样
results.userId === AnotherMongoDocument._id.toString()

猫鼬从5到6的迁徙指南:

Mongoose现在为ObjectIds添加了valueOf()函数。这意味着你现在可以使用==将ObjectId与字符串进行比较。

https://mongoosejs.com/docs/migrating_to_6.html#objectid-valueof

下面是一个例子,解释了这个问题,以及为什么它让许多人感到困惑。只有第一个控制台日志显示了对象的真实形式,任何其他调试/日志都会令人困惑,因为它们看起来是一样的。

// Constructor for an object that has 'val' and some other stuffs
//   related to to librery...
function ID(_val) {
this.val = _val;
this.otherStuff = "other stuffs goes here";
}
// function to help user get usefull infos from the Object
ID.prototype.toString = function toString() {
return `${this.val}`;
};
// Create new Object of type ID
const id = new ID('1234567');
console.log("my ID: ", id);  // my ID: Object {
//    val: "1234567",
//    otherStuff: "other stuffs goes here"
// }


console.log("my ID: " + id); // my ID: 1234567
console.log(id === '1234567'); // false
console.log(id == '1234567'); // true
console.log(id.toString() === '1234567'); //true
console.log(`${id}` === '1234567'); // true
console.log(new ID('1234567') === id); // false