使用聚合将文档的一个字段与同一文档的数组大小相匹配

时间:2016-11-15 12:32:29

标签: node.js mongodb mongodb-query aggregation-framework

我正在使用nodejs和mongodb,我在我的数据库中有下面的文档

{
arr: ["abc", "def", "ghi", "jkl"],
ctr: 0
},
{
arr: ["aeiop"],
ctr: 0
}

现在我想写一个聚合查询,如果ctr小于数组arr的大小,那么我想返回该文档。

以下是我写的查询

areamodel.aggregate(
            { $match : { ctr:{$lt : {$size: "$arr"} } },
            {$sort:{time_posted: -1}},
            function(err, docs) {
                if (err) {
                    console.log(err);
                } else {

                }
            }
        );

但我没有得到任何回应,因为没有查询匹配。

任何人都可以告诉我mognodb如何执行聚合查询。

1 个答案:

答案 0 :(得分:2)

考虑操纵 comparison operators 管道中的$project以及后续 $match 管道,根据附加字段过滤文档使用 $cmp 表达式:

couponmodel.aggregate([
    {
        "$project": {
            "arr": 1,
            "ctr": 1,
            "time_posted": 1,
            "comparer": { 
                "$cmp": [ "$ctr", { "$size": "$arr" } ]
            }
        }
    },
    { "$match": { "comparer": -1 } }
    { "$sort": { "time_posted": -1 } },
], function(err, docs) {
    if (err) {
        console.log(err);
    } else {
        console.log(docs);
    }
});

此方法的唯一缺点是您需要投影所需的字段以及创建您可能不需要的其他字段。

绕过上述内容的另一个选择是使用带有 $redact 运算符的单个管道,其中包含 $project {的功能如上所述{3}} 并使用 $match 系统变量返回符合指定条件的所有文档,并使用 {丢弃那些不匹配的文档{3}} 系统变量。请记住,此运算符执行集合扫描,因此在给定适当的索引技术的情况下,第一个管道选项可能是最佳的:

couponmodel.aggregate([
    {
        "$redact": {
            "$cond": [
                { 
                    "$eq": [
                        { "$cmp": [ "$ctr", { "$size": "$arr" } ] }, 
                        -1
                    ]
                }, 
                "$$KEEP", 
                "$$PRUNE"
            ]
        }
    },
    { "$sort": { "time_posted": -1 } },
], function(err, docs) {
    if (err) {
        console.log(err);
    } else {
        console.log(docs);
    }
});