【问题标题】:Mongodb, $sum with conditionMongodb, $sum 有条件
【发布时间】:2018-01-12 23:12:37
【问题描述】:

文件:

[
  {
    name: 'abc'
    length: 25,
    area: 10
  },
  {
    name: 'abc',
    length: 5
  }
]

聚合查询后的输出:

[
  {
     count: 2,
     summarizedLength: 30,
     summarizedArea: null,
     _id: {
       name: 'abc'
     }
  }
]

应该总结length 和area。但前提是所有文档都具有area 或length 属性。

因此,如果分组属性中缺少任何length 属性,则summarizedLength 值应为null/undefined/not exisitng,与area 相同。

我试过这个:

let query = mongoose.model('mycollection').aggregate([
    {
      $group: {
        _id: {
          name: $name
        },
        count: {
          $sum: 1
        },
        summarizedLength: { $sum: "$length" },
        summarizedArea: { $sum: "$area" },
      }
    }
  ]);

问题是,如果缺少任何属性,我需要取消$sum。这可能吗?

【问题讨论】:

    标签: mongodb aggregation-framework


    【解决方案1】:

    来自 Mongo 文档 $sum behavior

    如果用于同时包含数字和非数字值的字段, $sum 忽略非数字值并返回数字的总和 价值观。

    如果用于不存在于任何文档中的字段 集合,$sum 为该字段返回 0。

    如果所有操作数都是非数字的,$sum 返回 0。

    我们可以将$push所有的面积和长度转为数组,并将count与数组的长度进行比较

    db.n.aggregate(

        [ 
            {
                $group: {
                    _id: { name: "$name" }, 
                    count: { $sum: 1 }, 
                    area : {$push : "$area"}, 
                    length : {$push : "$length"} } 
            },
            {
                $project:{
                    _id: "$_id",
                    count: "$count",
                    summarizedLength: { $cond : [ {$eq : [ "$count", {$size : "$length"} ]} , { $sum : ["$length"] }, "not all numbers" ] },
                    summarizedArea: { $cond : [ {$eq : [ "$count", {$size : "$area"} ]} , { $sum : ["$area"] }, "not all numbers" ] },
                }
            }
        ] 
    )
    

    或者,我们可以计算defined的长度和面积,以及count的总数,如果计数匹配,则所有其他数字都未定义。

    为了严格检查类型,如果面积和长度可能包含非数字数据,我们可以做undefined而不是$type检查

    db.n.aggregate(
        [
            {
                $group: {
                    _id: { name: "$name" },
                    count: { $sum: 1 },
                    areaCount : { $sum : { $cond : [ {$eq : [ "$area", undefined ]} , 0, 1 ] } },
                    lengthCount : { $sum : { $cond : [ {$eq : [ "$length", undefined ]} , 0, 1 ] } },
                    summarizedLength: { $sum: "$length"  },
                    summarizedArea: { $sum: "$area"  }
                }
            },
            {
                $project : {
                    _id : "$_id",
                    count: "$count",
                    summarizedLength: { $cond : [ {$eq : [ "$count", "$lengthCount" ]} , "$summarizedLength", "not all numbers" ] },
                    summarizedArea: { $cond : [ {$eq : [ "$count", "$areaCount" ]} , "$summarizedArea", "not all numbers" ] },
                }
            }
        ]
    ).pretty()
    

    输出

    {
        "_id" : {
            "name" : "abc"
        },
        "count" : 2,
        "summarizedLength" : 30,
        "summarizedArea" : "not all numbers"
    }
    

    【讨论】:

      猜你喜欢
      • 2020-02-06
      • 2021-10-31
      • 2016-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-17
      • 1970-01-01
      • 2021-10-24
      相关资源
      最近更新 更多