mongodb $ filter操作是否适用于嵌套数组?

时间:2015-12-16 11:49:39

标签: mongodb mongodb-query aggregation-framework

我正在尝试在嵌套数组上使用$ filter操作,似乎无法让它正常工作。

$ fliter操作是否适用于嵌套数组?

这是我的MongoDB集合

{
    metrics: [
        {hits: 4 ,data: [
        {"status_Code" : 200, "response_time" : 245 },
        {"status_Code" : 200, "response_time" : 343},
        {"status_Code" : 501, "response_time" : 345 },
        {"status_Code" : 200, "response_time" : 234},
        {"status_Code" : 0, "response_time" : -1, },
    ]
        },
        {hits: 2 ,data: [
        {"status_Code" : 200, "response_time" : 245},
        {"status_Code" : 200, "response_time" : 343},
        {"status_Code" : 0, "response_time" : -1},
        {"status_Code" : 0, "response_time" : -1},
        {"status_Code" : 0, "response_time" : -1},
        ]}
    ],
 }

汇总查询:

db.collection.aggregate([ 
{
    $project: {
        metrics: {
            $filter: {
                input: "$metrics.data",
                as: "mdata",
                cond: {$gt: ["$$mdata.response_time", -1]}
            }
        }
    }
}
]);

期望输出:

{
    metrics: [
        {
            hits: 4 ,
            data: [
                {"status_Code" : 200, "response_time" : 245 },
                {"status_Code" : 200, "response_time" : 343},
                {"status_Code" : 501, "response_time" : 345 },
                {"status_Code" : 200, "response_time" : 234},
            ]
        },
        { 
            hits: 2 ,
            data: [
                { "status_Code" : 200, "response_time" : 245},
                {"status_Code" : 200, "response_time" : 343},
            ] 
        }

    ]
}

1 个答案:

答案 0 :(得分:2)

您无法在此使用$filter运算符,因为没有名为" response_time"的字段在"指标"数组子文档。

要使用$filter,您需要$unwind"指标"阵列。

db.collection.aggregate([ 
    { '$match': { 'metrics.data.response_time': { '$gt': -1 } } },
    { '$unwind': '$metrics' },
    { '$project': {
        'metrics': { 
            '$filter': {
                'input': "$metrics.data", 
                'as': "mdata",                 
                'cond': { '$gt': [ '$$mdata.response_time', -1 ] }               
            }        
         }  
    }} 
])

另一种选择是$redact使用here

db.collection.aggregate([ 
    { '$match': { 'metrics.data.response_time': { '$gt': -1 } } },
    { '$redact': { 
        '$cond': [
            { '$or': [
                { '$gt': [ '$response_time', -1  ] },
                { '$not': '$response_time' } ] 
            }, 
            '$$DESCEND', 
            '$$PRUNE'
        ]
    }}
] )