【发布时间】:2017-06-30 16:24:09
【问题描述】:
$push 如果该字段不存在,则聚合空值。 我想避免这种情况。
有没有办法为 $push 运算符创建一个子表达式,这样会跳过空值而不将其推送到结果数组中?
【问题讨论】:
标签: mongodb mongodb-query aggregation-framework
$push 如果该字段不存在,则聚合空值。 我想避免这种情况。
有没有办法为 $push 运算符创建一个子表达式,这样会跳过空值而不将其推送到结果数组中?
【问题讨论】:
标签: mongodb mongodb-query aggregation-framework
聚会有点晚了,但是..
我想做同样的事情,发现我可以用这样的表达式来完成它:
// Pushes events only if they have the value 'A'
"events": {
"$push": {
"$cond": [
{
"$eq": [
"$event",
"A"
]
},
"A",
"$noval"
]
}
}
这里的想法是当你这样做时
{ "$push": "$event" }
那么它似乎只推送非空值。
所以我编了一个不存在的列 $noval,作为我的 $cond 的错误条件返回。
它似乎工作。我不确定它是否是非标准的,因此有一天很容易坏,但是..
【讨论】:
collscan 来查看不存在的值是否存在。
$noval 为我工作:lol: 在这种情况下他们应该添加$$REMOVE。
如果没有示例,您的具体情况实际上并不完全清楚。 $ifNull 运算符可以用“其他”“替换”空值或缺失字段,但无法真正“跳过”。
也就是说,您始终可以根据您的实际用例“过滤”结果。
如果您的结果数据实际上是一个“集合”并且您的 MongoDB 版本是 2.6 或更高版本,那么您可以在 $addToSet 的帮助下使用 $setDifference 来减少保留的 null 值的数量最初:
db.collection.aggregate([
{ "$group": {
"_id": "$key",
"list": { "$addToSet": "$field" }
}},
{ "$project": {
"list": { "$setDifference": [ "$list", [null] ] }
}}
])
所以只有一个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" }
}}
])
如果您不想“破坏”最终会“空”的数组,因为它们包含“除了”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"
]
}
}}
])
使用最终的 $project 替换任何仅包含 null 值的数组,并使用空数组对象。
【讨论】: