2016-12-26 83 views
0

我的目標是獲得屬於「班級」 的所有'學生'文檔,其中至少有一個「藍色」級別的學生和至少一個「紅色」級別的 。MongoDB分組任務 - 多個組,條件

我傾向於在Python(pymongo)中簡單地執行一系列查詢,直接處理任務。

我不知道是否有一些聰明的聚合管道,我可以使用!

考慮:

類集合:

{ class_id: 'a' } 
{ class_id: 'b' } 

學生集合:

{ class_id: 'a', 
grade: 'blue' } 

{class_id: 'a', 
grade: 'red' } 

回答

0

你可以使用:

  • 一個$group到組由class_id$push所有等級都在一個數組中,因此我們可以在下一步輕鬆推導出哪個類包含blue。保存當前文檔與$$ROOT,因爲我們需要匹配class_id

  • 一個$match,學生只匹配有blue年級它

  • $unwind類刪除學生的先前產生的陣列$$ROOT

  • 一個$project重組文檔很好

查詢將是:

db.students.aggregate([{ 
    "$group": { 
     "_id": "$class_id", 
     "grades": { "$push": "$grade" }, 
     "students": { "$push": "$$ROOT" } 
    } 
}, { 
    "$match": { 
     "grades": { "$all": ["blue","red"] } 
    } 
}, { 
    "$unwind": "$students" 
}, { 
    "$project": { 
     "_id": "$students._id", 
     "class_id": "$students.class_id", 
     "grade": "$students.grade", 
    } 
}]) 

如果需要搭配其他顏色比[「藍」,「紅」]你可以在$match聚集($in: ["blue","red","yellow"]

添加更多對於PyMongo實現它,這是非常簡單的:

from pymongo import MongoClient 
import pprint 

db = MongoClient().testDB 

pipeline = [ <the_aggregation_query_here> ] 

pprint.pprint(list(db.students.aggregate(pipeline))) 

Additionnaly,只匹配屬於classes收集學生,執行$lookup並匹配那些不爲空。在聚合查詢中添加以下內容:

{ 
    $lookup: { 
     from: "classes", 
     localField: "class_id", 
     foreignField: "class_id", 
     as: "class" 
    } 
}, { 
    $match: { 
     "class": { $not: { $size: 0 } } 
    } 
}