【问题标题】:Schema ._id not the same as ._id returned with .find()? [NodeJS/Mongoose]架构 ._id 与 .find() 返回的 ._id 不同? [NodeJS/猫鼬]
【发布时间】:2018-11-27 02:56:24
【问题描述】:

我目前正在尝试使用 MongoDB 学习 NodeJS。我正在使用 mongoose 连接到本地安装的 MongoDB 版本,并在我的 TTD 中使用 mocha。

我知道这种情况的解决方案,但不知道为什么会这样。

让我解释一下: 我创建了一个模式和一个名为MarioCharacter 的模型。 我使用猫鼬的.save 函数将这个MarioCharacter 保存到MongoDB。 我想使用它的id在数据库中找到这个MarioCharacter(只有一个,它的变量是“newCharacter”)。

我的 mongoose 和 mocha 代码如下所示:

  //Find a record by its ID
  it("Finds a record by id from the database", function(done) {

    MarioCharacter.findOne({_id: newCharacter._id}).then(function(result) {
      //Log the value
      console.log(newCharacter._id); // returns 5b277477fd8f6f2c6437e5bc
      console.log(result._id); // returns 5b277477fd8f6f2c6437e5bc

      //Log the type
      console.log(typeof newCharacter._id); // returns object
      console.log(typeof result._id); // returns object

      //Test fails - returns false
      assert(result._id === newCharacter._id);
      done();
    })
  });

解决方案是使用.toString() 方法将两者都转换为字符串,这意味着这两种类型似乎并不相同,即使它们都表示对象也很难。

什么是我没有到达这里?是否还有对象的子类型或什么?

【问题讨论】:

  • 因为你在比较对象。它是 javascript,与 mongo 无关。 console.log({a:1} === {a:1}) 输出 false 因为这些是 2 个不同的对象。
  • 您可以从Object comparison in JavaScript 阅读更多内容以获得更好的想法。
  • 如果你真的想比较_id的两个BSON类型,你可以做assert.ok(result._id.equals(newCharacter._id)),基于Node.js MongoDB native driver。你也可以去查看 Node.js MongoDB 原生驱动的源代码,你会发现即使你使用 equals() 方法,在底层,它仍然在为你做 id1.toString() === id2.toString()。
  • 也就是说,这是因为两个对象都引用了不同的对象,即使它们具有相同的值?

标签: node.js mongodb mongoose mocha.js


【解决方案1】:

您从// Log the value 部分看到的内容实际上是因为Node.js MongoDB 原生驱动程序具有覆盖方法toString(),因此当您执行console.log() 时,它会在您的控制台上打印toString() 结果。

请参阅此 MDN post 谈论 Object.prototype.toString() 和 Node.js MongoDB native driver source code(第 189-197 行)。


原来MongoDB的ObjectId是这样的:

ObjectId 很小,可能是唯一的,生成速度快,并且是有序的。 ObjectId 值由 12 个字节组成,其中前四个字节是反映 ObjectId 创建的时间戳。具体来说:

  • 一个 4 字节的值,表示自 Unix 纪元以来的秒数,
  • 一个 3 字节的机器标识符,
  • 一个 2 字节的进程 ID,以及
  • 一个 3 字节的计数器,从一个随机值开始。

——Introduction to MongoDB > BSON types

【讨论】:

  • 我知道为什么 toString() 工作以及如何工作,但更重要的是为什么两个对象,这些字符串的来源不一样
  • 你的意思是result._id.toString()和newCharacter._id.toString()不一样?还是result._id 和newCharacter._id?如果是后者,那是因为 Objects result._id 和 newCharacter._id 是两个不同的 Object,它们没有相同的引用,所以在 JavaScript 中它们不会是完全一样的东西。
猜你喜欢
  • 2020-10-23
  • 2021-04-18
  • 2013-06-19
  • 2016-11-12
  • 2016-11-06
  • 1970-01-01
  • 2012-05-08
  • 2023-02-22
  • 2014-05-30
相关资源
最近更新 更多