【问题标题】:Comparing mongoose _id and strings比较猫鼬_id和字符串
【发布时间】:2018-06-15 13:19:18
【问题描述】:

我有一个 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)一直无法帮助。

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

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

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

    等等

    【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          【解决方案5】:

          公认的答案确实限制了您可以对代码执行的操作。例如,您将无法使用 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 这么多年过去了,你猜怎么着。我现在更喜欢你的版本。介意我将其添加到我的答案中吗?
          • 进步的代价 :) 当然你可以使用答案,它的目的是尽可能提供替代方案或帮助。
          【解决方案6】:

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

          1. 在像这样在两个 mongoDocuments 上比较 ObjectId 时使用 .equals
          results.userId.equals(AnotherMongoDocument._id)
          
          1. 在将 ObjectId 的字符串表示形式与 mongoDocument 的 ObjectId 进行比较时,请使用 .toString()。像这样
          results.userId === AnotherMongoDocument._id.toString()
          

          【讨论】:

          • 第三种可能的解决方案是什么?
          【解决方案7】:

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

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

          【讨论】:

            猜你喜欢
            • 2016-10-01
            • 1970-01-01
            • 2012-05-08
            • 2021-04-18
            • 2020-02-22
            • 2023-02-22
            • 2020-04-25
            • 2015-06-07
            相关资源
            最近更新 更多