使用mongoDB

时间:2017-04-23 23:27:35

标签: mongodb aggregation-framework

我有一个大型数据集,我想用它来描述测试的性能。数据库如下:

db.test.insertMany({
    "_id" : ObjectId("58e574a768afb6085ec3a388"),
    "tests" : [
        {
            "name" : "2",
            "evaluation" : [
                {
                    "aHigh" : [1,2],
                    "aLow" : [ ],
                    "zHigh" : [ ],
                    "zLow" : [1,3]
                },
                {
                    "aHigh" : [1,4],
                    "aLow" : [2],
                    "zHigh" : [ 3],
                    "zLow" : [ ]
                },
                {
                    "aHigh" : [ ],
                    "aLow" : [1,2,3],
                    "zHigh" : [1,2,3,4],
                    "zLow" : [ ]
                },]
            }
            ]
        },
        {
    "_id" : ObjectId("58eba09e51f7f631dd24aa1c"),
    "tests" : [
        {
            "name" : "2",
            "evaluation" : [
                {
                    "aHigh" : [2],
                    "aLow" : [3 ],
                    "zHigh" : [ ],
                    "zLow" : [1,2,3,4]
                },
                {
                    "aHigh" : [ ],
                    "aLow" : [ ],
                    "zHigh" : [ ],
                    "zLow" : [3,4]
                },
                {
                    "aHigh" : [1,2],
                    "aLow" : [3,4],
                    "zHigh" : [ ],
                    "zLow" : [1,2,3,4]
                },]
            }
            ]
        })

我有一套条件逻辑,我需要应用并计算结果的数量。基本上,我需要知道有多少评估符合某个标准。逻辑是:

case1: if the `$size` of the array `aHigh` is `$gte` to 3 AND 
       if the `$size` of the array `aLow` is `$lt` to 1
       then AHI
case2: if the `$size` of the array `aLow` is `$gte` to 3 AND 
       if the `$size` of the array `aHigh` is `$lt` to 1
       then ALO
case3: if the `$sum` of `$size` of the array `aHigh` and the `$size` of the array `aLow` is `$gte` to 3
       then AVR

我的预期输出基本上是一个列表。

我希望得到一些东西
{ "_id" : "AHI", "count" : 5 }
{ "_id" : "ALO", "count" : 15 }
{ "_id" : "AVR", "count" : 8 }
{ "_id" : "ZHI", "count" : 4 }
{ "_id" : "ZLO", "count" : 11 }
{ "_id" : "ZVR", "count" : 10 }

我无法更改数据库的结构。我一直在使用aggregate来获取信息。这段代码并没有让我得到我想要的东西,但它是我迄今为止所提出的。

db.test.aggregate([
    { $unwind: "$tests" },
    { $unwind: "$tests.evaluation" },
    { $unwind: "$tests.evaluation.aHigh"},
    { $unwind: "$tests.evaluation.aLow"},    
    { $project: {
        "results" : 
    {
        $switch: {
            branches: [
                {
                    case: { $and : [ { $gte : [ { $size : "$tests.evaluation.aHigh" }, 1 ] },
                                { $lt : [ { $size : "$tests.evaluation.aLow" }, 1 ] } 
                                    ] },
                    then: "AHI"
                },
                {
                    case: { $and : [ { $gte : [ { $size : "$tests.evaluation.aLow" }, 1 ] },
                                { $lt : [ { $size : "$tests.evaluation.aHigh" }, 1 ] }] },
                    then: "ALO"
                },
                {
                    case: { $gte : [ {$sum: [ {$size : "$tests.evaluation.aHigh" } , { $size : "$tests.evaluation.aLow" } ] }, 1 ] },
                    then: "AVR"
                }
            ],
            default: ""
        }
    }}}
])

编辑:

我现在能够为az做同样的事情。

1 个答案:

答案 0 :(得分:1)

你有一个$unwind太多了。

更新了您的汇总查询,以删除额外的$unwind阶段,并添加$group以计算results阶段的$project

db.test.aggregate([
    { $unwind: "$tests" },
    { $unwind: "$tests.evaluation" },
    { $project: {
        "results" : {
            $switch: {
                branches: [
                    {
                        case: { $and : [ { $gte : [ { $size : "$tests.evaluation.aHigh" }, 1 ] },
                                    { $lt : [ { $size : "$tests.evaluation.aLow" }, 1 ] } 
                                        ] },
                        then: "AHI"
                    },
                    {
                        case: { $and : [ { $gte : [ { $size : "$tests.evaluation.aLow" }, 1 ] },
                                    { $lt : [ { $size : "$tests.evaluation.aHigh" }, 1 ] }] },
                        then: "ALO"
                    },
                    {
                        case: { $gte : [ {$sum: [ {$size : "$tests.evaluation.aHigh" } , { $size : "$tests.evaluation.aLow" } ] }, 1 ] },
                        then: "AVR"
                    }
                ],
                default: ""
            }
        }}},
    { $group:{_id:"$results", count:{$sum:1}}}  
])