javascript - Mongodb 版本 3+ : how to insert new document only if it doesn't exist and get the result

标签 javascript node.js mongodb mongodb-query

我尝试了数十种解决方案,但没有一个有效,而且大多数都已被弃用。

我有一个包含如下文档的集合:

    _id: 5d99ef3285c93711828cd15d
    code: 1234
    name: "Foo"
    surname: "Bar"
    address: "That street"
    phone: 1234567

仅当没有任何具有相同代码的文档时,我才想插入新文档。

我最后一次尝试是这样的:

const result = await db.collection('users').findOneAndUpdate(
    { code: user.code },
    {
        $setOnInsert: user,
    },
    {
        upsert: true,
    }
);

但我得到E11000重复键错误集合...

updateOne() 返回相同的错误; update() 已弃用...

那么,如何仅添加新文档并获取结果(如果已添加文档则为 true,如果文档已存在则为 false)?

谢谢。

最佳答案

据我所知,

使用 $set 和 $setOnInsert,我们可以更新/插入相同的字段。

$set 和 $setOnInsert 应该是互斥的。

如果正在更新文档,它会起作用,但如果正在插入文档,则会抛出异常。

如果更新,$setOnInsert 将被忽略。

如果插入,两者都会被执行。

我认为解决方案是,

使用 returnNewDocument 并在架构中有一个字段 isUpdated 默认为 false。

Note:

make sure whenever you use "insert" operation on the collection, you don't add isUpdated which will be set to false then or set it to false.

形成一个查询,例如

db.collection('users').findOneAndUpdate(
    { code: user.code },
    {
        $set: user,          // which has user.isUpdated set to true
    },
    {
        upsert: true,
        returnNewDocument: false, // (by default it is false only)
    }
);

按照这个逻辑,

所以让我们一步一步来

  1. 如果文档doc1不存在,它将被插入,并且mongo将返回响应null。你会知道,它是已插入

  2. 如果文档 doc2 存在(考虑到此逻辑不适用于之前插入的文档 doc2 且 doc2 中不存在 isUpdated 字段),它将执行$set,因此在返回的游标中,该字段不存在,即未定义,因此您可以从中知道,它已更新

  3. 假设我们再次对 doc1 发出相同的查询(该查询存在并且我们已经应用了新逻辑),那么有两种情况

    a.它将被更新,并且在游标中,我们的 isUpdated 等于 false。

    b.它将被更新,并且在游标中,我们的 isUpdated 等于 true。

    在这两种情况下,您都知道它已更新

我认为这种方法应该可以解决您的问题。

如果这对您有帮助,或者您找到任何其他解决方案,请分享。

更新

实际上

您甚至不需要另一个字段isUpdated,没有这个字段,这应该使用相同的逻辑。

即如果光标为空,则插入,如果不为空,则更新。

关于javascript - Mongodb 版本 3+ : how to insert new document only if it doesn't exist and get the result,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58258301/

相关文章:

javascript - 如何从 mongo shell 中的 Date 值创建 ObjectId?

Javascript RegEx 使用全局修饰符产生不寻常的结果

JavaScript : unable to read file content using XMLHttpRequest

javascript - 通过 Express 发送静态资源时,如何在开发过程中自动刷新浏览器?

javascript - 为什么在将用户输入数据库时​​出现错误?

c# - Mongodb 无法插入我的所有记录

javascript - 如何在 PHP 中使用 SVG 绘制正方形?

javascript - 如何停止嵌入式YouTube视频

mysql - Mocha 测试与数据库的连接

node.js - NodeJS Hbase 节俭怪异