MongoDB:如何从$ elemMatch

时间:2015-05-04 16:29:11

标签: mongodb mongodb-query

假设我有一个学生对象数组字段,例如[{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 个答案:

答案 0 :(得分:2)

  

我想只返回学生字段中具有给定学生ID的课程

您可以使用$elemMatch in 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”的两个文件。

如果您只想要其中一个,则可以将聚合框架与$limit阶段一起使用(对于大多数情况, 应该在$sort阶段之前使用$limit阶段{1}}):

> 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
        }
    ]
}