将子文档数组聚合为单个文档

时间:2016-11-27 22:47:54

标签: mongodb mongodb-query aggregation-framework

我的文档如下所示(忽略此问题的时间点):

{
    "_id": "xyz-800",
    "site": "xyz",
    "user": 800,
    "timepoints": [
        {"timepoint": 0, "a": 1500, "b": 700},
        {"timepoint": 2, "a": 1000, "b": 200},
        {"timepoint": 4, "a": 3500, "b": 1500}
    ],
    "groupings": [
        {"type": "MNO", "group": "<10%", "raw": "1"},
        {"type": "IJK", "group": "Moderate", "raw": "23"}
    ]
}

我可以展平(可能不是正确的术语),因此groupings位于单个文档中。我希望结果看起来像:

{
    "id": "xyz-800", 
    "site": "xyz", 
    "user": 800, 
    "mnoGroup": "<10%", 
    "mnoRaw": "1", 
    "ijkGroup": "Moderate", 
    "ijkRaw": "23"
}

实际上,无论属性mnoGroup是否存在,我都希望创建mnoRawgroupings.type = "MNO"属性。与ijk属性相同。

1 个答案:

答案 0 :(得分:1)

您可以使用 $arrayElemAt 在第一个项目阶段按索引读取分组数组, $ifNull < / em> 在最终项目阶段投影可选值。 Litte详细,但会看到我能做什么。

db.groupmore.aggregate({
    "$project": {
        _id: 1,
        site: 1,
        user: 1,
        mnoGroup: {
            $arrayElemAt: ["$groupings", 0]
        },
        ijkGroup: {
            $arrayElemAt: ["$groupings", -1]
        }
    }
}, {
    "$project": {
        _id: 1,
        site: 1,
        user: 1,
        mnoGroup: {
            $ifNull: ["$mnoGroup.group", "Unspecified"]
        },
        mnoRaw: {
            $ifNull: ["$mnoGroup.raw", "Unspecified"]
        },
        ijkGroup: {
            $ifNull: ["$ijkGroup.group", "Unspecified"]
        },
        ijkRaw: {
            $ifNull: ["$ijkGroup.raw", "Unspecified"]
        }
    }
})

示例输出

{ "_id" : "xyz-800", "site" : "xyz", "user" : 800, "mnoGroup" : "<10%", "mnoRaw" : "1", "ijkGroup" : "Moderate", "ijkRaw" : "23" }
{ "_id" : "ert-600", "site" : "ert", "user" : 8600, "mnoGroup" : "Unspecified", "mnoRaw" : "Unspecified", "ijkGroup" : "Unspecified", "ijkRaw" : "Unspecified" }