如何避免在mongo聚合框架中推送$推送空值

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的错误条件返回.

它似乎工作.我不确定它是否是非标准的,因此很容易打破一天,但..


Nei*_*unn 5

如果没有一个例子,你的具体案例真的不完全清楚.有一个$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)

最后$projectnull一个空数组对象替换任何只包含值的数组.