MongoDB:如何找出一个数组字段是否包含一个元素?
我有两个集合。 第一个集合包含学生:
{ "_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。 有没有一种方法来指定一个查询查询的投影来检索student数组的学生ObjectId
只有当它在那里?
我试图看看是否可以使用elemMatch操作符,但是它是面向一系列子文档的。 我明白,我可以使用聚合框架,但在这种情况下,似乎是在矫枉过正。 聚合框架可能不会像单个查找查询那么快。 有没有办法查询课程收集,以便返回的文档可以在一个类似的forms?
{ "_id" : ObjectId("51780fb5c9c41825e3e21fc4"), "name" : "CS 101", "students" : [ ObjectId("51780f796ec4051a536015d0"), ] }
[现在可以在最近版本的基础上编辑 ]
[已更新的答案]您可以查询以下方法来取回类和学生ID的名称,只有当他们已经注册。
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的列表然后看学生收集中的姓名 – 两个查询,而不是一个!)
如果您正在存储(作为示例)课程数组中的Id和名称,如下所示:
{ "_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注册,你会回来:
{ "name" : "Literature" } { "name" : "Physics" } { "name" : "CS 101", "students" : [ { "id" : ObjectId("51780f796ec4051a536015cf"), "name" : "John" } ] }
好像$in
操作符可以满足你的要求。
你可以做这样的事情(伪查询):
if (db.courses.find({"students" : {"$in" : [studentId]}, "course" : courseId }).count() > 0) { // student is enrolled in class }
或者,您可以删除"course" : courseId
子句并获取一组学生注册的所有课程。