Iva*_*dov 8 mongodb mongodb-query aggregation-framework
如果该字段不存在,$ push将聚合空值.我想避免这个.
有没有办法为$ push运算符创建一个子表达式,以便跳过空值而不将其推入结果数组?
use*_*842 22
派对迟到了,但..
我想做同样的事情,发现我可以用这样的表达式完成它:
// Pushes events only if they have the value 'A'
"events": {
"$push": {
"$cond": [
{
"$eq": [
"$event",
"A"
]
},
"A",
"$noval"
]
}
}
Run Code Online (Sandbox Code Playgroud)
这里的想法是,当你这样做
{ "$push": "$event" }
Run Code Online (Sandbox Code Playgroud)
那么它似乎只推动非空值.
所以我编写了一个不存在的列,$ noval,作为我的$ cond的错误条件返回.
它似乎工作.我不确定它是否是非标准的,因此很容易打破一天,但..
如果没有一个例子,你的具体案例真的不完全清楚.有一个$ifNull运算符可以用"其他东西""替换"空值或缺少字段,但是真正"跳过"是不可能的.
也就是说,您可以根据实际使用情况随时"过滤"结果.
如果您的结果数据实际上是一个"Set"并且您有一个2.6或更高版本的MongoDB版本,那么您可以使用$setDifference一些帮助$addToSet来减少null最初保留的值的数量:
db.collection.aggregate([
{ "$group": {
"_id": "$key",
"list": { "$addToSet": "$field" }
}},
{ "$project": {
"list": { "$setDifference": [ "$list", [null] ] }
}}
])
Run Code Online (Sandbox Code Playgroud)
所以只有一个null然后$setDifference操作将在比较中"过滤"出来.
在早期版本中或当值实际上不是"唯一"而不是"设置"时,则通过使用$unwind和处理来"过滤" $match:
db.collection.aggregate([
{ "$group": {
"_id": "$key",
"list": { "$push": "$field" }
}},
{ "$unwind": "$list" },
{ "$match": { "list": { "$ne": null } }},
{ "$group": {
"_id": "$_id",
"list": { "$push": "$list" }
}}
])
Run Code Online (Sandbox Code Playgroud)
如果你不想成为"破坏性"的数组,这些数组最终会"空",因为它们只包含"只有" null,那么你可以$ifNull在条件上保持计数使用和匹配:
db.collection.aggregate([
{ "$group": {
"_id": "$key",
"list": { "$push": "$field" },
"count": {
"$sum": {
"$cond": [
{ "$eq": { "$ifNull": [ "$field", null ] }, null },
0,
1
]
}
}
}},
{ "$unwind": "$list" },
{ "$match": {
"$or": [
{ "list": { "$ne": null } },
{ "count": 0 }
]
}},
{ "$group": {
"_id": "$_id",
"list": { "$push": "$list" }
}},
{ "$project": {
"list": {
"$cond": [
{ "$eq": [ "$count", 0 ] },
{ "$const": [] },
"$list"
]
}
}}
])
Run Code Online (Sandbox Code Playgroud)
最后$project用null一个空数组对象替换任何只包含值的数组.
| 归档时间: |
|
| 查看次数: |
6112 次 |
| 最近记录: |