2011-07-15 24 views
3

1部分:在mongoDb中查詢和分組?

我已經(學生)收集:

{ 
    sname : "", 
    studentId: "123" 
    age: "", 
    gpa: "", 
} 

即時通訊試圖從中得到的只有兩個鍵:

{ 
    sname : "", 
    studentId: "123" 
} 

,所以我需要消除年齡和GPA只有名字和studentId,我怎麼能這樣做?

第2部分:

然後,我有「主題」集合:

{ 
    subjectName : "Math" 
    studentId : "123" 
    teacherName: "" 
} 

我需要匹配/結合前面的鍵(在第1部分)用正確的studentId所以我將結束這樣的事情:

{ 
    sname : "", 
    studentId: "123", 
    subjectName : "Math" 

} 

我怎麼能這樣做,是正確的方式來想想得到的結果?我試圖閱讀關於組和mapReduce,但我沒有找到一個明確的例子。

回答

4

要回答你的第一個問題,你可以這樣做:

db.student.find({}, {"sname":1, "studentId":1}); 

第{}在是限制的查詢,在這種情況下,包括整個集合。後半部分指定帶1或0的鍵,具體取決於您是否希望返回鍵。不要在一個查詢中混用include和exclude。除了一些特殊情況,mongo不會接受它。

你的第二個問題比較困難。你要求的是一個連接,mongo不支持這個。沒有辦法連接studentId上的兩個集合。你需要找到你想要的所有學生,然後使用這些studentIds來找到所有匹配的科目。然後,您需要將兩個結果合併到您自己的代碼中。你可以通過你使用的任何驅動程序來完成這個任務,或者你可以在shell中使用javascript來完成,但無論如何,你必須將它們與自己的代碼合併。

編輯: 下面是一個如何在shell中執行此操作的示例,其輸出將轉到名爲「out」的集合。

db.student.find({}, {"sname":1, "studentId":1}).forEach(
    function (st) { 
    db.subject.find({"studentId":st.studentId}, {"subjectName":1}).forEach(
     function (sub) { 
     db.out.insert({"sname":st.sname, "studentId":st.studentId, "subjectName":sub.subjectName}); 
     } 
    ); 
    } 
); 

如果不經常更改的所有數據,你可能只是下降的「走出去」的收集和使用此shell腳本定期重新填充它。然後你的代碼可以直接從「out」查詢。如果數據確實頻繁更改,那麼您將需要在代碼中進行合併。

另一種可能更好的選擇是將「主題」數據包含在「學生」集合中,反之亦然。這將導致更多的mongodb友好結構。如果你經常遇到這個連接問題,mongo可能不會走,關係數據庫可能更適合你的需求。

+1

你也可以使用[$在運營商(http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24in),以減少查詢的數量需要生成'out'表。這在高負載下尤其重要,或者在通過網絡查詢往返時間可能成爲大量學生的因素時尤爲重要。 – dcrosta

1

蒙戈的find()運算符,可以包含或從結果

退房Field Selection在文檔的更多信息排除某些字段。你可以這樣做既:

db.users.find({}, { 'sname': 1, 'studentId': 1 }); 
db.users.find({}, { 'age': 0, 'gpa': 0 }); 

對於與你的學生和主題一起,你既可以查找該科目一學生有獨立,就像這樣:

db.subjects.find({ studentId: 123 }); 

或嵌入實驗數據與每個學生,與學生一起文件檢索:

{ 
    sname : "Roland Browning", 
    studentId: "123" 
    age: 14, 
    gpa: "B", 
    subjects: [ { name : "French", teacher: "Mr Bronson" }, ... ] 
}