2015-05-04 59 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