MongoDB分别展开2个嵌入式阵列

时间:2017-03-07 13:54:59

标签: mongodb

我有一个关于MongoDB聚合查询的问题,它与$unwind 2 fields separately in mongodb query几乎相似。

这是文件:

{
    "_id" : "1",
    "details" : {
        "phonenumber" : [
            "1",
            "2"
        ],
        "name" : [
            "a",
            "b"
        ]
    }
}

我正在尝试构建一个查询,它将返回以下结果:

{ "_id" : "1", "phonenumber" : "1", "name" : null },
{ "_id" : "1", "phonenumber" : "2", "name" : null },
{ "_id" : "1", "phonenumber" : null, "name" : "a" },
{ "_id" : "1", "phonenumber" : null, "name" : "b" }

有人可以帮助我吗?

我能想出的最近的解决方案是通过以下查询:

db.document.aggregate( [ { $unwind: { path: "$details.name"} }, { $unwind: { path: "$details.phonenumber" } }, { $project: { _id: 1, name: "$details.name", phonenumber: "$details.phonenumber" } } ] )

以上查询的输出是:

{ "_id" : "1", "phonenumber" : "1", "name" : "a" },
{ "_id" : "1", "phonenumber" : "1", "name" : "b" },
{ "_id" : "1", "phonenumber" : "2", "name" : "a" },
{ "_id" : "1", "phonenumber" : "2", "name" : "b" }

2 个答案:

答案 0 :(得分:1)

使用MongoDB v3.4,可能的解决方案之一是,

db.document.aggregate({
    '$facet': {
        'phonenumber': [{
            '$unwind': '$details.phonenumber'
        }, {
            '$project': {
                phonenumber: '$details.phonenumber',
                name: null
            }
        }],
        'name': [{
            '$unwind': '$details.name'
        }, {
            '$project': {
                name: '$details.name',
                phonenumber: null
            }
        }]
    }
}, {
    '$project': {
        'combined': {
            '$setUnion': ['$phonenumber', '$name']
        }
    }
}, {
    '$unwind': '$combined'
}, {
    '$replaceRoot': {
        'newRoot': '$combined'
    }
})

facet允许我们在单个阶段中包含多个聚合管道,可从3.4版本中获取

答案 1 :(得分:1)

早期版本的mongodb的替代解决方案,

    db.document.aggregate([{
        $unwind: {
            path: "$details.name"
        }
    }, {
        $group: {
            _id: "$_id",
            nameArr: {
                $push: {
                    name: "$details.name",
                    phonenumber: {
                        $ifNull: ["$description", null]
                    }
                }
            },
            "details": {
                $first: "$details"
            }
        }
    }, {
        $unwind: "$details.phonenumber"
    }, {
        $group: {
            _id: "$_id",
            phoneArr: {
                $push: {
                    phonenumber: "$details.phonenumber",
                    name: {
                        $ifNull: ["$description", null]
                    }
                }
            },
            "nameArr": {
                $first: "$nameArr"
            }
        }
    }, {
        $project: {
            _id: 1,
            value: {
                $setUnion: ["$nameArr", "$phoneArr"]
            }
        }
    }, {
        $unwind: "$value"
    }, {
        $project: {
            name: "$value.name",
            phonenumber: "$value.phonenumber"
        }
    }])