我希望通过使用$或on property来获得$ cond的$ sum:
db.collectionName.aggregate(
{
"$group": {
"_id":'$created_at',
"count": {"$sum": 1},
"count_failure": {
"$sum": {
"$cond": [
{
"$id":
{ "$in": [ 0,100,101,102,103,104,105 ] }
},
1,
0
]
}
}
}
}
)
但错误说:Invalid operator "$id"
语法有什么问题?或者我错误地写了查询。
目前我通过以下方式实现这一目标:
db.collectionName.aggregate(
{
"$group": {
"_id":'$created_at',
"count": {"$sum": 1},
"count_failure": {
"$sum": {
"$cond": [
{
"$or":[
{ "$eq": [ "$id", 0 ] },
{ "$eq": [ "$id", 100 ]},
{ "$eq": [ "$id", 101 ]},
{ "$eq": [ "$id", 102 ]},
{ "$eq": [ "$id", 103 ]},
{ "$eq": [ "$id", 104 ]},
{ "$eq": [ "$id", 105 ]}
]
},
1,
0
]
}
}
}
}
)
答案 0 :(得分:10)
$setIsSubset
上的比较比您正在使用的$or
条件更短,但它仍然基本上可以正常执行您的工作。
$setIsSubset
的唯一问题是每个参数都是一个数组,因此您需要将单个元素转换为单个元素数组。使用$map
:
db.collectionName.aggregate([
{ "$group": {
"_id": "$createdAt",
"count": { "$sum": 1 },
"count_failure": {
"$sum": {
"$cond": [
{ "$setIsSubset": [
{ "$map": {
"input": ["A"],
"as": "el",
"in": "$id"
}},
[ 0,100,101,102,103,104,105 ],
]},
1,
0
]
}
}
}}
])
或者,如果您愿意,则使用$anyElementTrue
来匹配奇异值的参数数组:
db.collectionName.aggregate([
{ "$group": {
"_id": "$createdAt",
"count": { "$sum": 1 },
"count_failure": {
"$sum": {
"$cond": [
{ "$anyElementTrue": { "$map": {
"input": [ 0,100,101,102,103,104,105 ],
"as": "el",
"in": { "$eq": [ "$$el", "$id" ] }
}}},
1,
0
]
}
}
}}
])
$map
正在遍历参数以匹配单数而不是将单数形式强制转换为数组。
当然,由于任何一种表单基本上都会向true/false
提供$cond
,因此您可以在必要时使用$not
来反转逻辑:
db.collectionName.aggregate([
{ "$group": {
"_id": "$createdAt",
"count": { "$sum": 1 },
"count_failure": {
"$sum": {
"$cond": [
{ "$not": [{ "$anyElementTrue": { "$map": {
"input": [ 0,100,101,102,103,104,105 ],
"as": "el",
"in": { "$eq": [ "$$el", "$id" ] }
}}}]},
1,
0
]
}
}
}}
])
这实际上取决于你如何看待它,但仅仅作为提供的参数,你就不会在$or
的原始形式上获得任何东西。它可能看起来更清洁,更容易键入"但通常我不会"键入"这样的逻辑直接进入聚合管道,而是首先基于普通列表生成结构的那部分:
即
var failList = [ 0,100,101,102,103,104,105 ];
var orCondition = failList.map(function(el) {
return { "$eq": [ "$id", el ] }
})
然后只使用管道定义中重新映射的数组内容:
{ "$group": {
"_id": "$createdAt",
"count": { "$sum": 1 },
"count_failure": {
"$sum": {
"$cond": [
{ "$or": orCondition },
1,
0
]
}
}
}}
])
无论你如何看待它,请记住它只是数据结构而且你有基本的操作过程。管道处理内部以及管道构造本身。
答案 1 :(得分:0)
我认为$ in不是聚合管道运营商。
答案 2 :(得分:0)
首先,您应该在项目中使用$map创建$id
列表,然后在群组中使用setIsSubset,如下所示:
db.collectionName.aggregate([{
"$project": {
"idsArray": {
"$map": {
"input": ["A"],
"as": "el",
"in": {
"$cond": [{
"$eq": ["$$el", "A"]
}, "$id",
null
]
}
}
}
}
}, {
"$group": {
"_id": "$created_at",
"count": {
"$sum": 1
},
"count_failure": {
"$sum": {
"$cond": [{
"$setIsSubset": ["$idsArray", [
0,
100,
101,
102,
103,
104,
105
]]
},
1,
0
]
}
}
}
}])