ChatGPT解决这个技术问题 Extra ChatGPT

比较猫鼬_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

我假设这是某种数据类型问题,但我不确定如何将 results.userId 转换为会导致上述比较成立的数据类型,而我的外包大脑(又名 Google)一直无法提供帮助。


c
cjohn

Mongoose 使用 mongodb-native 驱动程序,该驱动程序使用自定义 ObjectID 类型。您可以将 ObjectID 与 .equals() 方法进行比较。以您的示例为例,results.userId.equals(AnotherMongoDocument._id)。如果您希望以 JSON 格式或 cookie 存储 ObjectID 的字符串化版本,ObjectID 类型还有一个 toString() 方法。

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

等等。


如果您已经在使用 mongoose,您可以只使用 require('mongoose').mongo.ObjectID,这样您就不必列出任何其他依赖项
我发现 doc._id == stringId 也可以工作,尽管由于严格的类型比较,doc._id === stringId 当然会是假的。这只是更容易编码。
J
JohnnyHK

ObjectID 是对象,因此如果您只是将它们与 == 进行比较,您就是在比较它们的引用。如果要比较它们的值,则需要使用 ObjectID.equals 方法:

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

D
Dila Gurung

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


A
Antoni

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

在像这样比较两个 mongoDocuments 上的 ObjectId 时使用 .equals

results.userId.equals(AnotherMongoDocument._id)

在将 ObjectId 的字符串表示形式与 mongoDocument 的 ObjectId 进行比较时使用 .toString()。像这样

results.userId === AnotherMongoDocument._id.toString()

第三种可能的解决方案是什么?
j
joy

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

AnotherMongoDocument._id.toString() JSON.stringify(AnotherMongoDocument._id) results.userId.equals(AnotherMongoDocument._id)


r
r3wt

接受的答案确实限制了您可以对代码执行的操作。例如,您将无法使用 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);
});

或单行:let exists = results.idList.filter(val => val.toString() === thisIsTheStringifiedIdWeAreLookingFor).length ? true : false
@Zlatko 我不是新语法的忠实粉丝,而是每个人自己的。
@Zlatko const exists = results.idList.some(val => val.toString() === thisIsTheStringifiedIdWeAreLookingFor)const exists = results.idList.some(val => val.equals(someModel._id))
@Zlatko 这么多年过去了,你猜怎么着。我现在更喜欢你的版本。介意我是否以适当的归属将其添加到我的答案中?
进步的代价 :) 当然,您可以使用答案,其目的是尽可能提供替代方案或帮助。
J
Jitendra

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

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

j
julius-huck

Mongoose 从 5 到 6 迁移指南:

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

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


p
phoenixstudio

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

// 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