2015-05-04 87 views
0

假設我有一個學生對象數組字段,例如[{id:foo, name: bar, imageurl:baz}]在課程集合中。並且我想僅返回在學生字段中具有給定學生ID的課程。

如果我使用$elemMatch,我會在課程集合以及我想要的課程中獲得一堆文檔。有沒有辦法解決這個問題,或者我絕對必須做一些後期查詢過濾來只返回一個文檔?

編輯: 例如課程集合:

{ 
_id: 1, 
course: "OOP 101", 
students: [ 
       { name: "ajax", school: 100, age: 7 }, 
       { name: "achilles", school: 100, age: 8 }, 
      ] 
} 
{ 
_id: 2, 
course: "Programming 101", 
students: [ 
       { name: "john", school: 102, age: 10 }, 
       { name: "ajax", school: 100, age: 7 }, 
       { name: "achilles", school: 100, age: 8 }, 
      ] 
} 
{ 
_id: 3, 
course: "Database 101", 
students: [ 
       { name: "john", school: 102, age: 10 }, 
       { name: "jess", school: 102, age: 11 }, 
       { name: "jeff", school: 108, age: 15 } 
      ] 
} 

預計如果我使用$elemMatch找到課程傑夫正在輸出:

{ 
_id: 3, 
course: "Database 101", 
students: [ 
       { name: "john", school: 102, age: 10 }, 
       { name: "jess", school: 102, age: 11 }, 
       { name: "jeff", school: 108, age: 15 } 
      ] 
} 

{ 
_id: 1, 
course: "OOP 101" 
{ 
_id: 2, 
course: "Programming 101" 
} 
{ 
_id: 3, 
course: "Database 101", 
students: [ 
       { name: "john", school: 102, age: 10 }, 
       { name: "jess", school: 102, age: 11 }, 
       { name: "jeff", school: 108, age: 15 } 
      ] 
} 
+1

你能否:

如果你只想要其中的一個,你可能會與$limit階段一起使用聚合框架(在大多數情況下,你應該使用$sort階段$limit前)向我們展示一些樣本文件和預期產出? – chridam

+0

@chridam請參閱編輯? – wemadeit

+2

我編輯了您的問題,根據您提供的一個鏈接顯示樣本集合。你能**顯示預期輸出的例子**嗎? –

回答

2

我想僅返回t他在學生領域中具有給定學生ID的課程

您可以使用$elemMatchin a query根據嵌入文檔中字段的值選擇文檔。然後,使用一個簡單的推算,你可以回到感興趣領域:

> db.test.courses.find(
    {students: {$elemMatch : { name: "john"}}}, // find all courses having 
                // "john" as a student 
    {course:1})         // keep only the course name 
                // and the _id 
{ "_id" : 2, "course" : "Programming 101" } 
{ "_id" : 3, "course" : "Database 101" } 

當然,如果您需要整個文件,不指定任何預測:

> db.test.courses.find(  {students: {$elemMatch : { name: "jeff"}}}).pretty() 
{ 
    "_id" : 3, 
    "course" : "Database 101", 
    "students" : [ 
     { 
      "name" : "john", 
      "school" : 102, 
      "age" : 10 
     }, 
     { 
      "name" : "jess", 
      "school" : 102, 
      "age" : 11 
     }, 
     { 
      "name" : "jeff", 
      "school" : 108, 
      "age" : 15 
     } 
    ] 
} 

請注意,這將返回全部有一個學生與匹配的名稱的課程。在我們的樣本數據中,「jeff」僅與一個課程相關聯。但這會返回兩個文件「john」。至少

> db.test.courses.aggregate([ 
     {$match:{students: {$elemMatch : { name: "john"}}}}, 
     {$limit:1} 
    ]).pretty() 
{ 
    "_id" : 2, 
    "course" : "Programming 101", 
    "students" : [ 
     { 
      "name" : "john", 
      "school" : 102, 
      "age" : 10 
     }, 
     { 
      "name" : "ajax", 
      "school" : 100, 
      "age" : 7 
     }, 
     { 
      "name" : "achilles", 
      "school" : 100, 
      "age" : 8 
     } 
    ] 
} 
+0

嗨,我已經編輯了更具體的問題。 mongodb文檔似乎顯示包含無關課程的回覆(學生字段不匹配它會返回課程,但隱藏了學生字段)。我錯了嗎? – wemadeit

+0

@wemadeit感謝您澄清您的需求。 AFAIKT,正如我所解釋的那樣,使用'elemMatch'應該可以產生你所期望的。我已編輯提供更多細節。使用MongoDB 3.0.2進行測試。 –

+0

這不是mongodb文檔所說的會發生的事情。請查看郵政編碼搜索示例:http://docs.mongodb。org/manual/reference/operator/projection/elemMatch /其中{「_id」:3}作爲結果返回,即使它不匹配 – wemadeit