2016-02-13 45 views
0

想象Mongo 3.2中的兩個集合叫做student和class。什麼是查詢將返回特定類中的所有學生文檔。Mongo 3.2加入特定項目

帶有$ lookup的聚合似乎想要對集合中的所有文檔進行操作。例如,將每個班級的所有學生退回而不是特定的班級。

我該如何申請由id = 23945647b27e7e652a9aeb65的特定班級生成的學生文件?

類:

{ 
    "_id" : ObjectId("23945647b27e7e652a9aeb65"), // Given this 
    "name" : "Algebra", 
    "students" : [ "13945647b27e7e65869aeb65", "03945647b27e7e65029aeb65" ] 
} 

學生://返回此

{ 
    "_id" : ObjectId("13945647b27e7e65869aeb65"), 
    "name" : "foo" 
} 
{ 
    "_id" : ObjectId("03945647b27e7e65029aeb65"), 
    "name" : "bar" 
} 

一些失敗的嘗試:

db.student.aggregate([{$match:{"$ref": "class", "_id": ObjectId("23945647b27e7e652a9aeb65")}},{$lookup:{from: "class",localField:"students",foreignField: "_id", as: "stuffFromRight"}}}]) 


db.student.aggregate([{$lookup:{from: {"$ref": "class", "_id": ObjectId("23945647b27e7e652a9aeb65")},localField:"students",foreignField: "_id", as: "stuffFromRight"}}]) 

這一個獲得部分信用爲它做了正確的查詢。但是,它不會將結果限制到我想要的特定班級。

db.student.aggregate([{$lookup:{from: "class",localField:"students",foreignField: "_id", as: "stuffFromRight"}}]) 

回答

0

這個例子有幾個問題。

  1. 類中的數組和學生對象本身之間的類型不一樣。您將無法將字符串與ObjectId進行比較,並期望獲得所需的結果。
  2. $ lookup在兩個字段上執行$ eq。在該示例中,這意味着,該查找是試圖比較:

    [ 「13945647b27e7e65869aeb65」, 「03945647b27e7e65029aeb65」] ==的ObjectId( 「13945647b27e7e65869aeb65」)

由於上述兩種點的,這個查詢會失敗,最終會搜索所有文檔。

爲了使用來自類端的學生數組,您需要首先修復數組以匹配類型,那麼在執行查找之前,您必須首先展開數組。這裏有一個例子:

db.class.aggregate([ 
    {$match:{ "_id": ObjectId("23945647b27e7e652a9aeb65")}}, 
    {$unwind: "$students"}, 
    {$lookup: { from: "student", localField: "students", foreignField: "_id", as: "stuffFromRight"}} 
]) 

隨着上述結果,然後你可以使用一個項目,以減少它,如果你想,只顯示學生的記錄,但它也可能是值得拉班和學生在一起,因爲您可能需要在輸出中查詢該類。

+0

學生是一個十六進制字符串,它等於「新的ObjectId(hexStr)」,但在最後的查找階段導致空的結果。展開產生類對象的幾個副本,但是具有空的「stuffFromRight」字段。 需要的是一個String-> ObjectId轉換。 – redboy

+0

@redboy聚合中沒有選項可將字符串轉換爲ObjectId,反之亦然。最終,數據需要修正,以便它不會丟失它的類型。您可能需要將學生數組拖到您的應用程序中,然後在學生標識數組中的每個元素上正確設置類型後查詢學生。 – uadrive