MongoDB:如何确定数组字段是否包含元素? [英] MongoDB: How to find out if an array field contains an element?

查看:1188
本文介绍了MongoDB:如何确定数组字段是否包含元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个收藏.第一个集合包含学生:

I have two collections. The first collection contains students:

{ "_id" : ObjectId("51780f796ec4051a536015cf"), "name" : "John" }
{ "_id" : ObjectId("51780f796ec4051a536015d0"), "name" : "Sam" }
{ "_id" : ObjectId("51780f796ec4051a536015d1"), "name" : "Chris" }
{ "_id" : ObjectId("51780f796ec4051a536015d2"), "name" : "Joe" }

第二个集合包含课程:

{
        "_id" : ObjectId("51780fb5c9c41825e3e21fc4"),
        "name" : "CS 101",
        "students" : [
                ObjectId("51780f796ec4051a536015cf"),
                ObjectId("51780f796ec4051a536015d0"),
                ObjectId("51780f796ec4051a536015d2")
        ]
}
{
        "_id" : ObjectId("51780fb5c9c41825e3e21fc5"),
        "name" : "Literature",
        "students" : [
                ObjectId("51780f796ec4051a536015d0"),
                ObjectId("51780f796ec4051a536015d0"),
                ObjectId("51780f796ec4051a536015d2")
        ]
}
{
        "_id" : ObjectId("51780fb5c9c41825e3e21fc6"),
        "name" : "Physics",
        "students" : [
                ObjectId("51780f796ec4051a536015cf"),
                ObjectId("51780f796ec4051a536015d0")
        ]
}

每个课程文档都包含students数组,该数组具有为该课程注册的学生的列表.当学生在网页上查看课程时,他需要查看他是否已经注册了该课程.为此,当代表学生查询courses集合时,我们需要找出students数组是否已经包含学生的ObjectId.是否可以在查找查询的投影中指定一种方法,以仅从students数组中检索学生ObjectId?

Each course document contains students array which has a list of students registered for the course. When a student views a course on a web page he needs to see if he has already registered for the course or not. In order to do that, when the courses collection gets queried on the student's behalf, we need to find out if students array already contains the student's ObjectId. Is there a way to specify in the projection of a find query to retrieve student ObjectId from students array only if it is there?

我试图看看是否可以使用$ elemMatch运算符,但是它适用于一系列子文档.我知道我可以使用聚合框架,但是在这种情况下,这样做似乎有些过头了.聚合框架可能不会像单个查找查询那样快.有没有一种方法可以查询课程集,以便返回的文档可以采用与此类似的形式?

I tried to see if I could $elemMatch operator but it is geared towards an array of sub-documents. I understand that I could use aggregation framework but it seems that it would be on overkill in this case. Aggregation framework would probably not be as fast as a single find query. Is there a way to query course collection to so that the returned document could be in a form similar to this?

{
        "_id" : ObjectId("51780fb5c9c41825e3e21fc4"),
        "name" : "CS 101",
        "students" : [
                ObjectId("51780f796ec4051a536015d0"),
        ]
}

推荐答案

[编辑基于此,在最新版本中可能会出现]

[edit based on this now being possible in recent versions]

[更新后的答案]您可以通过以下方式查询班级名称和学生ID,前提是它们已经被注册.

[Updated Answer] You can query the following way to get back the name of class and the student id only if they are already enrolled.

db.student.find({},
 {_id:0, name:1, students:{$elemMatch:{$eq:ObjectId("51780f796ec4051a536015cf")}}})

您将获得预期的结果:

{ "name" : "CS 101", "students" : [ ObjectId("51780f796ec4051a536015cf") ] }
{ "name" : "Literature" }
{ "name" : "Physics", "students" : [ ObjectId("51780f796ec4051a536015cf") ] }

[原始回答]目前无法做您想做的事情.不幸的是,如果将学生作为对象存储在数组中,您将能够执行此操作.实际上,让您感到惊讶的是,您仅使用ObjectId(),因为如果您想显示已注册特定课程的学生列表,它会始终要求您查找学生.首先列出Id的列表,然后在学生集合中查找名称-两个查询而不是一个查询!)

[Original Answer] It's not possible to do what you want to do currently. This is unfortunate because you would be able to do this if the student was stored in the array as an object. In fact, I'm a little surprised you are using just ObjectId() as that will always require you to look up the students if you want to display a list of students enrolled in a particular course (look up list of Id's first then look up names in the students collection - two queries instead of one!)

如果您要像这样在课程数组中存储一个ID和名称(例如):

If you were storing (as an example) an Id and name in the course array like this:

{
        "_id" : ObjectId("51780fb5c9c41825e3e21fc6"),
        "name" : "Physics",
        "students" : [
                {id: ObjectId("51780f796ec4051a536015cf"), name: "John"},
                {id: ObjectId("51780f796ec4051a536015d0"), name: "Sam"}
        ]
}

您的查询将简单地是:

db.course.find( { }, 
                { students : 
                    { $elemMatch : 
                       { id : ObjectId("51780f796ec4051a536015d0"), 
                         name : "Sam" 
                       } 
                    } 
                } 
);

如果该学生仅参加过CS 101,您会回来:

If that student was only enrolled in CS 101 you'd get back:

{ "name" : "Literature" }
{ "name" : "Physics" }
{
    "name" : "CS 101",
    "students" : [
        {
            "id" : ObjectId("51780f796ec4051a536015cf"),
            "name" : "John"
        }
    ]
}

这篇关于MongoDB:如何确定数组字段是否包含元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆