字段已添加但随后消失。 这是 mongo shell 中的代码:
> db.users.aggregate([{$addFields:{totalAge:{$sum:"$age"}}}])
{ "_id" : ObjectId("5acb81b53306361018814849"), "name" : "A", "age" : 1, "totalAge" : 1 }
{ "_id" : ObjectId("5acb81b5330636101881484a"), "name" : "B", "age" : 2, "totalAge" : 2 }
{ "_id" : ObjectId("5acb81b5330636101881484b"), "name" : "C", "age" : 3, "totalAge" : 3 }
> db.users.find().pretty()
{ "_id" : ObjectId("5acb81b53306361018814849"), "name" : "A", "age" : 1 }
{ "_id" : ObjectId("5acb81b5330636101881484a"), "name" : "B", "age" : 2 }
{ "_id" : ObjectId("5acb81b5330636101881484b"), "name" : "C", "age" : 3 }
聚合仅从您的集合中读取数据;它也不编辑集合。考虑聚合的最佳方法是读取一些数据并对其进行操作以供立即使用。
如果你想在主源中更改它,那么你必须使用 update 方法。
或者更简单的方法(不是最好但简单)
db.users.aggregate([{$addFields:{totalAge:{$sum:"$age"}}}]).forEach(function (x){
db.users.save(x)
})
Nozar 的答案是正确的,但是 .save() 现已弃用。
不要使用他/她的确切答案,而是使用 .updateOne 和 $set 进行修改。
旧/已弃用的答案:
db.users
.aggregate([{$addFields:{totalAge:{$sum:"$age"}}}])
.forEach(function (x){db.users.save(x)})
新/工作答案:
db.users
.aggregate([{$addFields:{totalAge:{$sum:"$age"}}}])
.forEach(function (x){db.users.updateOne({name: x.name}, {$set: {totalAge: x.totalAge}})})
注意:在我的示例中,我使用“name”来过滤(在本例中基本上匹配)“users”集合中的文档,但您可以使用任何唯一字段(例如 _id 字段)。
感谢 Nozar 引导我找到了我提供的更新答案,因为我刚刚在我的项目中使用了它! (在我的项目中,我在 $addFields 管道阶段之前使用了 $match 管道阶段,因为我只是想对我的集合中的单个文档而不是所有文档执行此操作)
聚合管道不会改变原始数据;它的作用是获取数据的临时内存副本并对其执行一系列操作(仍在内存中)并将其发送到客户端。
这与您可以做的方式类似
db.collection.find().sort()
;那里的排序只会改变返回给客户端的内容,不会改变数据库中存储的内容。
唯一的例外是当您使用$out阶段时,它将聚合结果保存到另一个集合中。您可以看到,因为他们必须添加特殊类型的阶段来执行此操作,所以正常的聚合不会写回存储的数据。
原因是,您的两种方法完全不同。在聚合中,您在该查询中使用$addFields,您将获得totalAge。但是根据您的查找查询,您可以获得存储在数据库中的特定数据。这里您没有计算totalAge。
希望你能理解。
似乎你可以使用$merge,例如:
> db.users.aggregate([{$addFields:{totalAge:{$sum:"$age"}}},{merge: "users"}])