在单个字段上别名多个$ match条件

时间:2018-10-16 11:22:38

标签: mongodb mongoose aggregation-framework

我已经使用不同的组合进行了一段时间的研究 Mongodb聚合管道中的$ project,$ match,$ unwind。我的数据就像:

{
    "flow":[
        {"y":1},
        {"y":69696},
        {"y":3}
    ]
}
{
    "flow":[
        {"y":4},
        {"y":69632},
        {"y":6},
        {"y":7},
        {"y":8}
    ]
}

我想根据flow.y是否设置了第16位来对流数组元素进行分组。我想返回值的总和(不设置位)和匹配元素的计数。因此,对于上面的示例,我想检索:

[  
   {  "bitset": {
              "_id":null,
              "count":2,
              "y_total":8256
          },
       "bitunset": {
              "_id":null,
              "count":6,
              "y_total":29
          },
   }
]

我可以在两个单独的聚合调用中检索信息,但希望将它们组合在一起。

db.collection.aggregate([
  {$unwind: {path: "$flow"}},
  {$match: {"flow.y": { $bitsAllSet: 65536 }}},
  {$group: {
    _id: null,
    count: { $sum: 1 },
    y_total: {$sum: "$flow.y"}
  }}

我也尝试过:

db.collection.aggregate([
  {$unwind: {path: "$flow"}},
  {$match: {$or: [{"flow.y": { $bitsAllSet: 65536 }},
                  {"flow.y": { $bitsAllClear: 65536 }}]}},
  {$group: {
    _id: null,
    count: { $sum: 1 },
    y_total: {$sum: "$flow.y"}
  }}

如果我可以别名$ or运算符的结果,那会很好。 数据库版本v3.6.5

1 个答案:

答案 0 :(得分:1)

这是基于$facet的解决方案:

db.collection.aggregate([{
    $unwind: "$flow"
}, {
    $facet: {
        "bitset": [{
                $match: { "flow.y": { $bitsAllSet: 65536 } }
            }, {
                $group: {
                    _id: null,
                    count: { $sum: 1 },
                    y_total: {$sum: {$subtract: [ "$flow.y", 65536 ] }}
                }
            }
        ],
        "bitunset": [{
                $match: { "flow.y": { $bitsAllClear: 65536 } }
            }, {
                $group: {
                    _id: null,
                    count: { $sum: 1 },
                    y_total: { $sum: "$flow.y" }
                }
            }
        ]
    }
}])

或者没有$group阶段:

db.collection.aggregate([{
    $unwind: "$flow"
}, {
    $facet: {
        "bitset": [{
                $match: { "flow.y": { $bitsAllSet: 65536 } }
            }
        ],
        "bitunset": [{
                $match: { "flow.y": { $bitsAllClear: 65536 } }
            }
        ]
    }
}, {
    $project: {
        y_count_set: { $size: "$bitset.flow.y" },
        y_total_set: { $subtract: [ { $sum: "$bitset.flow.y" }, { $multiply: [ { $size: "$bitset.flow.y" }, 65536 ] } ] },
        y_count_unset: { $size: "$bitunset.flow.y" },
        y_total_unset: { $sum: "$bitunset.flow.y" }
    }
}])