Mongodb findoneandupdate 与聚合管道
Posted
技术标签:
【中文标题】Mongodb findoneandupdate 与聚合管道【英文标题】:Mongodb findoneandupdate with aggregation pipeline 【发布时间】:2020-09-20 15:01:58 【问题描述】:我在 MongoDB 中有这样的数据
"_id":"$oid":"5ec4ed0b94996124187b95ce",
"cid":"245345323",
"dtl":[
"_id":"$oid":"5ed5ab655df7930ec424be1e",
"sid":"test",
"amt":"$numberInt":"48",
"Name":"test",
"_id":"$oid":"5ed5ac9f79a75423d4bc0270",
"sid":"s",
"amt":"$numberInt":"14",
"Name":"sfds",
"_id":"$oid":"5ed5ace7d204ab144863ed7a",
"sid":"wesad",
"amt":"$numberInt":"6",
"Name":"2sdad"
,
"updated":"$date":"$numberLong":"1589964043787",
"__v":"$numberInt":"6",
"TotalAmt":"$numberInt":"68"
仅当数组中的 amt 字段的值大于 10 时,我才需要更新 TotalAmt 字段。我使用了以下 2 个选项
PM.findOneAndUpdate(
_id: MongoId,
,
[
$set:
//TotalAmt: $sum: '$dtl.amt' ,
/*TotalAmt:
$cond:
if: $gte: ['$dtl.amt', 10] ,
then: $sum: '$dtl.amt' ,
else: 0,
,
,*/
,
,
],
new: true
)
如果没有 amt > 10 条件(第一个选项已注释),它可以正常工作。但如果我添加条件则不起作用。任何帮助,将不胜感激。谢谢
【问题讨论】:
【参考方案1】:尝试使用$map改变$sum
的输入结构:
PM.findOneAndUpdate(
_id: MongoId,
,
[
$set:
TotalAmt:
$cond:
if: $gte: ['$dtl.amt', 10],
then:
$sum:
$map:
input: '$dtl',
as: "item",
in: "$$item.amt"
,
,
else: 0, // 0 or "$TotalAmt" ?
,
,
,
,
],
new: true
)
【讨论】:
它有效,但 Valijon 的回答看起来很优雅。谢谢【参考方案2】:你需要使用$filter操作符:
PM.findOneAndUpdate(
_id: MongoId,
,
[
$set:
TotalAmt:
$sum:
$filter:
input: '$dtl.amt',
cond: $gte: ['$$this', 10]
]
new: true
)
---输出---
"_id" : ObjectId("5ec4ed0b94996124187b95ce"),
"cid" : "245345323",
"dtl" : [
"_id" : ObjectId("5ed5ab655df7930ec424be1e"),
"sid" : "test",
"amt" : 48,
"Name" : "test"
,
"_id" : ObjectId("5ed5ac9f79a75423d4bc0270"),
"sid" : "s",
"amt" : 14,
"Name" : "sfds"
,
"_id" : ObjectId("5ed5ace7d204ab144863ed7a"),
"sid" : "wesad",
"amt" : 6,
"Name" : "2sdad"
],
"updated" : ISODate("2020-05-20T08:40:43.787Z"),
"__v" : 6,
"TotalAmt" : 62
编辑:如果要按其他字段过滤,我们需要添加额外的$map
运算符。
PM.findOneAndUpdate(
_id: MongoId,
,
[
$set:
TotalAmt:
$sum:
$map:
input:
$filter:
input: '$dtl',
cond: $eq: ['$$this.Name', 'test']
,
in:"$$this.amt"
],
new: true
)
【讨论】:
它就像一个魅力......我想将条件更改为名称,即只有在名称字段的值为“测试”时才求和。我改变了这样的条件 cond: $eq: ['$$this.Name', 'test'] 但它不起作用。 @AnanthVivek 再看一遍,我已经更新了答案 谢谢它有效。请将 $gte 更改为 $eq。 (与这个问题的上下文无关)以上是关于Mongodb findoneandupdate 与聚合管道的主要内容,如果未能解决你的问题,请参考以下文章
MongoDB - Mongoose 查询 findOneAndUpdate() 不更新/复制数据库
findOneAndUpdate 未在 MongoDb 中返回更新的文档 [重复]
findOneAndUpdate 未在 MongoDb 中返回更新的文档 [重复]
如何在 mongodb 的 findOneAndUpdate 中使用对象作为过滤器