MongoDB表格化嵌套数组

时间:2015-08-18 05:56:39

标签: mongodb mongoose nosql

鉴于以下结构的文件:

{
    username: "John",
    subjects: [
        {subjectName: "subjectA", status : "PASSED" },
        {subjectName: "subjectB", status : "PASSED" },
        {subjectName: "subjectC", status : "FAILED" }
    ]
},
{
    username: "Jason",
    subjects: [
        {subjectName: "subjectA", status : "PASSED" },
        {subjectName: "subjectB", status : "PASSED" },
        {subjectName: "subjectC", status : "FAILED" }
    ]
}

如何以下列格式获取所有传递的科目?

[{username: "John", subjectName: "subjectA", status : "PASSED"},
{username: "John", subjectName: "subjectB", status : "PASSED"},
{username: "Jason", subjectName: "subjectA", status : "PASSED"},
{username: "Jason", subjectName: "subjectB", status : "PASSED"}]

2 个答案:

答案 0 :(得分:1)

您可以使用aggregation这样执行此操作:

db.collectionName.aggregate({
    "$unwind": "$subjects"
}, {
    "$match": {
        "subjects.status": "PASSED"
    }
}, {
    "$group": {
        "_id": "$username"
        , "subjects": {
            "$push": "$subjects"
        }
    }
}, {
    "$unwind": "$subjects"
}, {
    "$project": {
        "_id": 0
        , "username": "$_id"
        , "subjectName": "$subjects.subjectName"
        , "status": "$subjects.status"
    }
})

但是在这个聚合中unwind创建了一个多个文档,并且在大数组中它会产生问题所以你应该像这样使用redact

db.collectionName.aggregate({
"$match": {
    "subjects.status": "PASSED"
}
}, {
"$redact": {
    "$cond": {
        "if": {
            "$eq": [{
                "$ifNull": ["$status", "PASSED"]
            }, "PASSED"]
        },
        "then": "$$DESCEND",
        "else": "$$PRUNE"
    }
}
}).pretty()

答案 1 :(得分:0)

为此,您需要一个简单的聚合查询:

db.collection.aggregate([
    {$unwind: "$subjects"},
    {$match: {"subjects.status": "PASSED"}},
    {$project: {username: 1, subjectName: "$subjects.subjectName", status: "$subjects.status"}}
]);