如何使用MongoDB/Mongoose中的先前值更新字段 [英] How to update a field using its previous value in MongoDB/Mongoose
问题描述
例如,我有一些看起来像这样的文件:
{
id: 1
name: "foo"
}
我想将另一个string
附加到当前的name
字段值.
我使用Mongoose尝试了以下操作,但没有成功:
Model.findOneAndUpdate({ id: 1 }, { $set: { name: +"bar" } }, ...);
您无法引用要更新的文档的值,因此您将需要一个查询来检索文档,而又需要一个查询来更新文档.自2016年以来,对于处于OPEN
状态的请求,似乎有一个功能请求. /p>
如果您的集合中包含如下文档:
{ "_id" : ObjectId("590a4aa8ff1809c94801ecd0"), "name" : "bar" }
使用MongoDB Shell,您可以执行以下操作:
db.test.find({ name: "bar" }).snapshot().forEach((doc) => {
doc.name = "foo-" + doc.name;
db.test.save(doc);
});
文档将按预期更新:
{ "_id" : ObjectId("590a4aa8ff1809c94801ecd0"), "name": "foo-bar" }
请注意 .snapshot()
调用.
这样可以确保查询不会多次返回文档,因为由于文档大小的增加,中间的写操作会移动该查询.
将其应用于您的Mongoose示例,如此官方示例所述:
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
查询中使用它.
无论如何,根据您需要执行的操作,可以将其与 然后将使用如下文档创建一个新集合 仅作为参考,关于同一主题还有另一个有趣的问题,有一些值得阅读的答案: And I want to append another I tried the following using Mongoose, but it didn't work:
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 If you have a collection with documents that look like: Using the MongoDB shell, you can do something like this: The document will be updated as expected: Note the Applying this to your Mongoose example, as explained in this official example: It's worth mentioning that there's a Anyway, depending on what you need to do, you can use that together with the With that same example, you will do: And a new collection 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屋!prefixedTest
:{ "_id" : ObjectId("XXX"), "name": "foo-bar" }
string
to the current name
field value. Model.findOneAndUpdate({ id: 1 }, { $set: { name: +"bar" } }, ...);
OPEN
state since 2016.{ "_id" : ObjectId("590a4aa8ff1809c94801ecd0"), "name" : "bar" }
db.test.find({ name: "bar" }).snapshot().forEach((doc) => {
doc.name = "foo-" + doc.name;
db.test.save(doc);
});
{ "_id" : ObjectId("590a4aa8ff1809c94801ecd0"), "name": "foo-bar" }
.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.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
operator in the aggregation framework, but unfortunately you can't use that in an update
query.$out
operator to save the results of the aggregation to a new collection.db.test.aggregate([{
$match: { name: "bar" }
}, {
$project: { name: { $concat: ["foo", "-", "$name"] }}
}, {
$out: "prefixedTest"
}]);
prefixedTest
will be created with documents that look like:{ "_id" : ObjectId("XXX"), "name": "foo-bar" }