2015-08-18 116 views
0

鑑於以下結構的文檔:MongoDB的tabularize嵌套陣列

{ 
    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"}] 
+0

你想使用像Java一樣的編程語言或直接試圖查詢? –

+0

@PrasadKharkar我正在使用JavaScript與Mongoose。 – Sawyer

回答

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() 
0

對於這一點,你需要一個簡單的彙總查詢:

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

假設主題數組很大,並且我有大量文檔,'$ unwind'會導致性能問題嗎? – Sawyer