【问题标题】:Use of $COND and $EQ with a array of objects将 $COND 和 $EQ 与对象数组一起使用
【发布时间】:2014-02-28 23:29:00
【问题描述】:

我希望有人能够回答我在下面尝试完成的工作是否可以使用 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 运算符似乎不会评估数组内的数据(总是错误的)。

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 数组,但后来我为每个用户文档获得了多条记录,不知道如何将它们合并回来。

在处理对象数组时,如何使用 $EQ(或其他运算符)和 $COND 有什么我遗漏的地方吗?

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    你肯定走在正确的轨道上,如果你用 $group 跟进它,使用 $unwind 可以让你到达那里:

    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'
        }}
    ])
    

    【讨论】:

    • 这完全符合我的需要,但我试图了解您在 $GROUP 语句中对 $FIRST 和 $MAX 的使用。是否可以防止出现 NULL 值情况?
    • @Joe-IV 太好了。有关 $group 中发生的事情的详细信息,请参阅我的更新答案。
    • 完美! - 除了这个答案,我发现这个blog post 有助于在我的脑海中将这些碎片拼凑在一起。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-24
    • 2012-12-13
    • 2016-04-17
    • 1970-01-01
    相关资源
    最近更新 更多