如何使用 MongoDB/Mongoose 中的先前值更新字段 [英] How to update a field using its previous value in MongoDB/Mongoose

查看:31
本文介绍了如何使用 MongoDB/Mongoose 中的先前值更新字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如,我有一些看起来像这样的文档:

For example, I have some documents that look like this:

{
    id: 1
    name: "foo"
}

我想将另一个 string 附加到当前的 name 字段值.

And I want to append another string to the current name field value.

我使用 Mongoose 尝试了以下操作,但没有奏效:

I tried the following using Mongoose, but it didn't work:

Model.findOneAndUpdate({ id: 1 }, { $set: { name: +"bar" } }, ...);

推荐答案

您不能引用要更新的文档的值,因此您需要一个查询来检索文档,并需要另一个查询来更新它.看起来在 OPEN 中有一个 功能请求自 2016 年以来的状态.

You can't refer to the values of the document you want to update, so you will need one query to retrieve the document and another one to update it. It looks like there's a feature request for that in OPEN state since 2016.

如果您有一个包含以下文档的集合:

If you have a collection with documents that look like:

{ "_id" : ObjectId("590a4aa8ff1809c94801ecd0"), "name" : "bar" }

使用 MongoDB shell,您可以执行以下操作:

Using the MongoDB shell, you can do something like this:

db.test.find({ name: "bar" }).snapshot().forEach((doc) => {
    doc.name = "foo-" + doc.name;

    db.test.save(doc);
});

文档将按预期更新:

{ "_id" : ObjectId("590a4aa8ff1809c94801ecd0"), "name": "foo-bar" }

注意.snapshot() 呼叫.这可确保查询不会多次返回文档,因为中间的写入操作会因文档大小的增长而移动它.

Note the .snapshot() call. This ensures that the query will not return a document multiple times because an intervening write operation moves it due to the growth in document size.

将此应用到您的 Mongoose 示例,如此官方示例中所述:

Applying this to your Mongoose example, as explained in this official example:

Cat.findById(1, (err, cat) => {
    if (err) return handleError(err);

    cat.name = cat.name + "bar";

    cat.save((err, updatedCat) => {
        if (err) return handleError(err);

        ...
    });
});

值得一提的是,有一个$concat 运算符在聚合框架中,但遗憾的是您不能在 update 查询中使用它.

It's worth mentioning that there's a $concat operator in the aggregation framework, but unfortunately you can't use that in an update query.

无论如何,根据您需要做什么,您可以将它与 $out 运算符将聚合结果保存到新集合中.

Anyway, depending on what you need to do, you can use that together with the $out operator to save the results of the aggregation to a new collection.

使用相同的示例,您将执行以下操作:

With that same example, you will do:

db.test.aggregate([{
    $match: { name: "bar" }
}, {
    $project: { name: { $concat: ["foo", "-", "$name"] }}
}, {
    $out: "prefixedTest"
}]);

一个新的集合 prefixedTest 将被创建,文档看起来像:

And a new collection prefixedTest will be created with documents that look like:

{ "_id" : ObjectId("XXX"), "name": "foo-bar" }

作为参考,关于同一主题还有另一个有趣的问题,其中一些答案值得一读:使用另一个字段的值更新 MongoDB 字段

Just as a reference, there's another interesting question about this same topic with a few answers worth reading: Update MongoDB field using value of another field

这篇关于如何使用 MongoDB/Mongoose 中的先前值更新字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆