Mongodb中的聚合和条件

时间:2018-11-21 13:34:02

标签: mongodb aggregation

我是MongoDB的新手。我有以下集合:CallLeg包含以下格式的数据

{
    "_id" : ObjectId("5bf5504a937eb609c4d020e4"),
    "startedAt" : ISODate("2018-11-21T17:50:45.909Z"),
    "endedAt" : ISODate("2018-11-21T18:02:09.909Z"),
    "cc" : "91",
    "phone" : "1234567890",
    "type" : "pstn",
    "status" : true,
    "channel" : "mF4YnGi7SM4qCeKHJ6SYunqkano2BNQQ",
    "cost" : 0,
    "duration" : 0,
    "cid" : "ABCDEFGH"

}
{
    "_id" : ObjectId("5bf5504a937eb609c4d020e5"),
    "startedAt" : ISODate("2018-11-21T17:50:10.110Z"),
    "endedAt" : ISODate("2018-11-21T18:02:10.110Z"),
    "cc" : "91",
    "phone" : "0007654321",
    "type" : "voip",
    "status" : true,
    "channel" : "mF4YnGi7SM4qCeKHJ6SYunqkano2BNQQ",
    "cost" : 0,
    "duration" : 0,
    "cid" : "ABCDEFGH"

}

我想获得如下输出:

  • 如果'n'个对象的cid相同,则应返回这些对象。假设它返回2
  • 然后,如果obj1type=pstnobj2type=voip,则应返回MIXED的答案,如果obj1_type = obj2_type = voip应返回{{ 1}},对于相同的VOIPpstn相似。

希望我的问题很清楚。

1 个答案:

答案 0 :(得分:1)

您可以使用以下汇总:

db.CallLeg.aggregate([
    {
        $group: {
            _id: "$cid",
            objects: { $push: "$$ROOT" }
        }
    },
    {
        $match: { objects: { $size: 2 } }
    },
    {
        $addFields: {
            answer: {
                $switch: {
                    branches: [
                        { case: { $allElementsTrue: [ 
                            { $map: { input: "$objects", as: "o", in: { $eq: [ "$$o.type", "voip" ] } } } ] } , then: "voip" },
                        { case: { $allElementsTrue: [ 
                            { $map: { input: "$objects", as: "o", in: { $eq: [ "$$o.type", "pstn" ] } } } ] } , then: "pstn" },
                    ],
                    default: "MIXED"
                }
            }
        }
    }
])

基本上,您需要按cid $group来比较多个文档。如果仅需要分析一个$match,也可以在$group之前添加cid。然后,您可以使用$size检查“相同”对象的数量。在最后阶段,您需要比较objects数组中的元素。您可以使用$map获得一个布尔值数组,该布尔值将指示您有多少个voippstns值。然后,您需要$allElementsTrue来检查所有项目是否都具有一种类型。一切都可以放在$switch内以定义最后的默认分支MIXED