文档如下所示:
{
data: [
{ identifier: 'a', value: 10 },
{ identifier: 'b', value: 53 },
{ identifier: 'c', value: 16 }
]
}
如果标识符为null
的同一数组中的另一个对象符合条件,我想将所有值设置为x
。现实生活中的例子:
如果标识为value
的对象的属性a
大于9
,请设置标识为value
或b
的对象的属性c
到null
。
我正在尝试使用$project
管道,但不知道如何找到其他对象。
// ... Rest
{
$unwind: '$data'
}, {
$project: {
data: {
identifier: 1,
value: {
$cond: {
if: {}, // Implement
then: null, // Only valid for current value
else: '$row.value'
}
}
}
}
// ... Rest
生成的聚合应该是一个数组。
如果a
的值符合条件:
[
{ data: { identifier: 'a', value: null } },
{ data: { identifier: 'b', value: null } },
{ data: { identifier: 'c', value: null } },
// ... more documents
]
如果a
的值不符合条件:
[
{ data: { identifier: 'a', value: 10 } },
{ data: { identifier: 'b', value: 53 } },
{ data: { identifier: 'c', value: 16 } },
// ... more documents
]
答案 0 :(得分:2)
您可以尝试以下聚合查询。
使用$cond
表达式与$filter
一起验证输入条件是否与数组中的任何元素匹配,并$size
输出$gt
的长度,而不是0比较;如果是,请使用$map
将所有值映射为null;如果没有按原样保留数据值。
db.colname.aggregate({"$addFields":{
"data":{
"$cond":[
{"$gt":[
{"$size":{
"$filter":{
"input":"$data",
"as":"d",
"cond":{
"$and":[
{"$eq":["a","$$d.identifier"]},
{"$gt":["$$d.value", 9]}
]
}
}
}},
0
]},
{"$map":{
"input":"$data",
"as":"d",
"in":{ "identifier": "$$d.identifier", "value": null }
}},
"$data"
]
}
}})
答案 1 :(得分:1)
尝试此聚合,而不使用$unwind
db.col.aggregate([
{$addFields : {
index : {$indexOfArray : ["$data.identifier", "a"]},
isTrue : {$gte : [{$arrayElemAt : ["$data.value", {$indexOfArray : ["$data.identifier", "a"]}]}, 10]}
}},
{$addFields : {
row : {
identifier : {$arrayElemAt : ["$data.identifier", "$index"]},
value : {$cond : ["$isTrue", {$arrayElemAt : ["$data.value", "$index"]}, null]}
}
}},
{$project : {index :0, isTrue : 0, data : 0}}
]).pretty()
结果
> db.col.aggregate([ {$addFields : { index : {$indexOfArray : ["$data.identifier", "a"]}, isTrue : {$gte : [{$arrayElemAt : ["$data.value", {$indexOfArray : ["$data.identifier", "a"]}]}, 10]} }}, {$addFields : { row : { identifier : {$arrayElemAt : ["$data.identifier", "$index"]}, value : {$cond : ["$isTrue", {$arrayElemAt : ["$data.value", "$index"]}, null]} } }}, {$project : {index :0, isTrue : 0, data : 0}} ]).pretty()
{ "_id" : 1, "row" : { "identifier" : "a", "value" : 10 } }
>
修改强>
使用$map
将值设置为所有标识符的值
db.col.aggregate([
{$addFields : {
isTrue : {$gte : [{$arrayElemAt : ["$data.value", {$indexOfArray : ["$data.identifier", "a"]}]}, 10]}
}},
{$addFields : {
data :
{$map : {
input : "$data",
as : "d",
in : {
identifier : "$$d.identifier",
value : {$cond : ["$isTrue", "$$d.value", null]}
}
}}
}},
{$project : {_id :0, isTrue : 0}}
]).pretty()
结果
{
"data" : [
{
"identifier" : "a",
"value" : 10
},
{
"identifier" : "b",
"value" : 53
},
{
"identifier" : "c",
"value" : 16
}
]
}