MongoDB - 如果字段不存在,如何仅更新字段

Tri*_*yen 1 mongoose mongodb

如何更新具有以下要求的 mongo 文档:

通过电子邮件属性查找文档:

如果文档存在:

  1. 如果检索到的文档和新文档都具有属性 A,则保留属性 A(检索到的)。
  2. 如果检索到的文档属性 A 为空或未定义或不存在,则使用新对象的属性 A 进行更新。

如果文档不存在

  1. 插入新文档。

findOneAndUpdate似乎没有传达的要求,两个3。谢谢。

小智 6

我的建议是走以下路径:

db.getCollection('<some-collection>').update(
    { email: 'someguy@email.com' },
    {
        $set: {
            name: "some guy",
            username: someguy,
            tel: '1234'
        }
    },
    { upsert: true }
);
Run Code Online (Sandbox Code Playgroud)

检查 upsert 文档:https ://docs.mongodb.com/manual/reference/method/db.collection.update/#upsert-option

现在让我们来看看您的要求:

3. 如果文档不存在,插入新文档。

是的,如果它没有通过电子邮件找到文档,它将插入新文档到集合中。生成的文档将是查找条件 + $set + 自动生成的 _id 的组合,因此它看起来像这样:

{
    _id: ObjectId(...)
    email: 'someguy@email.com'
    name: "some guy",
    username: someguy,
    tel: '1234'
}
Run Code Online (Sandbox Code Playgroud)

2. 如果检索到的文档属性 A 为空或未定义或不存在,则使用新对象的属性 A 进行更新。

中提供的所有属性都$set将无条件地保留在数据库中,这也涵盖了您更新空/未定义值的要求

3. 如果检索到的文档和新文档都具有属性 A,则保留属性 A(检索到的)。

如果新提供的A和数据库A都一样,我们就没有问题。如果As 不同,您不想存储新A值吗?如果您害怕空值/未定义值,您可以在向 $set 提供对象之前省略它们。您不想使用新提供的值更新数据库属性的用例是什么?我可以看到的一个用例是,如果您要createdAt创建新记录,但不想为现有记录更新该值,您希望通过。如果是这样,并且您事先知道这些属性,则可以使用$setOnInsert更新运算符。https://docs.mongodb.com/manual/reference/operator/update/#id1

所以你的更新查询可以是这样的:

db.getCollection('<some-collection>').update(
    { email: 'someguy@email.com' },
    {
        $set: {
            name: "some guy",
            username: someguy,
            tel: '1234'
        },
        $setOnInsert: {
            createdAt: new Date(),
            updatedAt: new Date()
        }
    },
    { upsert: true }
);
Run Code Online (Sandbox Code Playgroud)

我希望这有帮助!