将$ COND和$ EQ与一组对象一起使用

时间:2014-02-28 23:29:01

标签: mongodb mongodb-query aggregation-framework

我希望有人能够回答是否可以使用MongoDB聚合框架完成下面我要完成的任务。

我有一个类似于以下内容的用户数据结构,附近有近100万个文档。

{
    "firstName" : "John",
    "lastName" : "Doe",
    "state" : "NJ",
    "email" : "JOHNDOE@XYZ.COM"
    "source" : [ 
        {
            "type" : "SOURCE-A",
            "data" : {
                "info" : "abc",
                "info2" : "xyz"
            }
        }, 
        {
            "type" : "SOURCE-B",
            "data" : {
                "info3" : "abc"
            }
        }
    ]
}

为了将数据提供给另一个系统,我需要生成一个平面文件结构,其中包含来自先前数据集的有限信息。列需要表示:

firstname, lastname, email, is_source-a, is_source-b

我遇到困难的部分是试图填充“is_source-a”和“is_source-b”的条件代码。我试图使用以下聚合查询,但无法弄清楚如何使它工作,因为与$ COND一起使用的$ EQ运算符似乎不评估数组内的数据(总是为false)。

db.collection.aggregate([
    {
        $project : {
            _id : 0,
            firstName : 1,
            lastName: 1,
            "is_source-a" : {
                $cond : [
                    { $eq: [ "$source.type", "source-a" ] },
                    1,
                    0
                ]
            },
            "is_source-b" : {
                $cond : [
                    { $eq: [ "$source.type", "source-b" ] },
                    1,
                    0
                ]
            }
        }
    }
]);

我可以先对UNWIND数组进行UNWIND,但最后我会查看每个用户文档的多条记录,并且不了解如何将它们合并回来。

在处理对象数组时,是否有一些我缺少如何使用$ EQ(或其他一些运算符)和$ COND?

1 个答案:

答案 0 :(得分:6)

您肯定是在正确的轨道上,如果您使用$unwind跟进,将$group放在一起,使用db.collection.aggregate([ {$unwind: '$source'}, {$project: { _id: 1, firstName: 1, lastName: 1, email: 1, 'is_source-a': {$eq: ['$source.type', 'SOURCE-A']}, 'is_source-b': {$eq: ['$source.type', 'SOURCE-B']} }}, // group the docs that were duplicated in the $unwind back together by _id, // taking the values for most fields from the $first occurrence of the _id, // but the $max of the is_source fields so that if its true in any of the // docs for that _id it will be true in the output for that _id. {$group: { _id: '$_id', firstName: {$first: '$firstName'}, lastName: {$first: '$lastName'}, email: {$first: '$email'}, 'is_source-a': {$max: '$is_source-a'}, 'is_source-b': {$max: '$is_source-b'} }}, // project again to remove _id {$project: { _id: 0, firstName: 1, lastName: 1, email: 1, 'is_source-a': '$is_source-a', 'is_source-b': '$is_source-b' }} ]) 可以帮助您实现目标:

{{1}}