为什么mongoose在我使用它的findOneAndUpdate方法时改变了_id?

xqk2d5yq  于 9个月前  发布在  Go
关注(0)|答案(2)|浏览(107)

我来自关系数据库,而主键(本例中为_id)在其生命周期中沿着是相同的,所以当我在mongodb中看到这种行为时,我感到惊讶。
我以下面的方式使用mongoose的findOneAndUpdate插件方法:

User.findOneAndUpdate(
  { "products._id": _id, "_id": req.payload._id },
  {
    $set: {
      "products.$": { name: "New name" },
    },
  },
  {
    new: true,
    runValidators: true,
  },
  function (err, doc) {
    if (err != null) {
      res
        .status(500)
        .json({
          message: "Error on updating. Please, try again later.",
        });
    } else if (doc == null) {
      res.status(404).json({ message: "Product not found." });
    } else {
      res.status(200).json(doc.products);
    }
  }
);

字符串
开始前:

{_id: 58b5e637f9f904a800721abf, name: "Old name"}

**(_id更改)**后:

{_id: 58b5e35a7f4ff38c433a5bc9, name: "New name"}


我只是想在更新后保持相同的_id,因为我认为当我实现同步更新时,我可能会遇到麻烦。
我搜索了一下,发现这个mongoose方法对mongo的驱动程序来说是直接的,没有中间件。因此,我想这个问题可以由mongodb的Maven解决,而不需要mongoose的知识。

mwyxok5s

mwyxok5s1#

_id附加到文档修订版,而不是文档实体。
通过传递new: true,您要求Mongo返回最新修订版本的ID,它将具有与原始文档(Upsert)不同的ID。
对于基于文档的存储,建议实现您自己的UUID模式。
或者使用uuid确定性:

var UUID = require('uuid-1345');

UUID.v3({
  namespace: UUID.namespace.oid,
  name: "abc" // Some formula to calculate you uuid, could be based on the document's legacy id or some other unique identifier.
}, function (err, id) {
  console.log("Generated a name-based UUID using MD5:\n\t%s\n", id);
});

字符串
或随机与普通随机HEX:

var crypto = require('crypto');

var id = crypto.randomBytes(20).toString('hex');


将其包含在文档的主体中.

g0czyy6m

g0czyy6m2#

无论发生什么,都是在您的mongoose空间本地发生的。在 * 否 * 情况下,mongodb findOneAndUpdate() * 会更改 * 匹配文档的_id,但如果是upsert:true,则可能会创建新的_id

相关问题