我有一个json数据如下:
[{
finale: [ { sign: '~', prob: 0.5 },
{ sign: '~', prob: 0.4 } ]
},
{
finale: [ { sign: '~', prob: 0.7 },
{ sign: '>', prob: 0.25 } ]
}]
现在我想要的结果是这样的:
[{
result : {
sign: '~', prob: 0.2
}
},
{
result : {
sign: '>', prob: 0.25
}
}]
这是我推导的逻辑:
如果“结局”中的数组元素为'拥有所有"〜"在'签署'元素,然后我希望结果具有所有' prob'的乘法。数组中的字段恰好是:
0.5 * 0.4 = 0.2
但是,如果至少有一个标志是'>'或者'<&#;我只需要从“' sign'中复制完全相同的东西。和' prob'在结果中忽略所有其他值,如上面第二个结果所示
[注意:只能有一个'<'或者'>'在数组中。 “finale”中的数组元素'最多可以有3个元素,但它至少应该包含1个元素。元素的顺序也可以是随机的。]
答案 0 :(得分:1)
我正在使用 MongoDB聚合框架。
此查询适用于此限制: 在每个文件中不能存在多于1"<"或1">"。基本上每个对象可以有多个"〜"但是0或1">"或"<"。
重点是逐个分组,然后拒绝每个对象有"〜"除了它只有"〜"的情况。
db.Test1.aggregate([
{
$unwind:"$finale"
},
{
$group:{
_id: {_id: "$_id", sign:"$finale.sign"},
finaleitems:{$push:"$finale"}
}
},
{
$match: {
$or: [
{$and:[ {finaleitems: {$size: 1}}, {$or:[ {"_id.sign":">"}, {"_id.sign":"<"} ]} ]},
{$or:[ {finaleitems: {$size: 2}}, {finaleitems: {$size: 3}} ]}
]
}
},
{
$project: {
_id: 1,
finaleitems: 1,
result: {
$cond: [{$eq:["$_id.sign","~"]},
{
$reduce: {
input: "$finaleitems",
initialValue: 1,
in: { $multiply : ["$$value", "$$this.prob"] }
}
},
{$arrayElemAt:["$finaleitems",0]}]
}
}
}
]);
<强> INPUT 强>:
{
"_id" : ObjectId("58033a8bd63cf401292fe09a"),
"finale" : [
{
"sign" : "~",
"prob" : 0.5
},
{
"sign" : "~",
"prob" : 0.4
}
]
}
{
"_id" : ObjectId("58033a98d63cf401292fe09d"),
"finale" : [
{
"sign" : "~",
"prob" : 0.7
},
{
"sign" : ">",
"prob" : 0.25
}
]
}
{
"_id" : ObjectId("58035251d63cf401292fe0a0"),
"finale" : [
{
"sign" : "<",
"prob" : 0.7
},
{
"sign" : "~",
"prob" : 0.25
}
]
}
{
"_id" : ObjectId("5803622dd63cf401292fe0a3"),
"finale" : [
{
"sign" : "~",
"prob" : 0.7
},
{
"sign" : ">",
"prob" : 0.25
}
]
}
<强>输出强>:
{
"_id" : {
"_id" : ObjectId("5803622dd63cf401292fe0a3"),
"sign" : ">"
},
"finaleitems" : [
{
"sign" : ">",
"prob" : 0.25
}
],
"result" : {
"sign" : ">",
"prob" : 0.25
}
}
{
"_id" : {
"_id" : ObjectId("58035251d63cf401292fe0a0"),
"sign" : "<"
},
"finaleitems" : [
{
"sign" : "<",
"prob" : 0.7
}
],
"result" : {
"sign" : "<",
"prob" : 0.7
}
}
{
"_id" : {
"_id" : ObjectId("58033a98d63cf401292fe09d"),
"sign" : ">"
},
"finaleitems" : [
{
"sign" : ">",
"prob" : 0.25
}
],
"result" : {
"sign" : ">",
"prob" : 0.25
}
}
{
"_id" : {
"_id" : ObjectId("58033a8bd63cf401292fe09a"),
"sign" : "~"
},
"finaleitems" : [
{
"sign" : "~",
"prob" : 0.5
},
{
"sign" : "~",
"prob" : 0.4
}
],
"result" : 0.2
}
正如您所看到的,返回的属性更多,您不需要它们,但我认为这对于调试管道正在生成的内容是有益的。
我使用具有$reduce
功能的Mongo DB 3.4RC:
https://docs.mongodb.com/master/reference/operator/aggregation/reduce/
希望这可以解决您的问题。