当我使用findOneAndUpdate方法时为什么mongodb正在改变_id?

时间:2017-02-28 21:29:17

标签: node.js mongodb mongoose

我来自关系数据库,而主键(本例,_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的专家解决,而不知道猫鼬。

1 个答案:

答案 0 :(得分:1)

_id附加到文档修订版,而不是文档实体。

通过传递new: true,您要求Mongo返回最新版本的ID,该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');

将此内容包含在您的文档正文中......并且不要忘记index它!