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가 이미 포함되어 있는지 확인해야합니다 . 배열 ObjectId에서 학생을 검색하기 위해 찾기 쿼리의 프로젝션에서 지정하는 방법 students이 있습니까?
$ elemMatch 연산자를 사용할 수 있는지 확인하려고했지만 하위 문서 배열에 맞춰져 있습니다. 집계 프레임 워크를 사용할 수 있다는 것을 이해하지만이 경우 과도하게 사용되는 것 같습니다. 집계 프레임 워크는 단일 찾기 쿼리만큼 빠르지 않을 것입니다. 반환 된 문서가 이와 유사한 형식이되도록 코스 컬렉션을 쿼리하는 방법이 있습니까?
{
"_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") ] }
[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!)
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"}
]
}
Your query then would simply be:
db.course.find( { },
{ students :
{ $elemMatch :
{ id : ObjectId("51780f796ec4051a536015d0"),
name : "Sam"
}
}
}
);
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"
}
]
}
It seems like the $in operator would serve your purposes just fine.
You could do something like this (pseudo-query):
if (db.courses.find({"students" : {"$in" : [studentId]}, "course" : courseId }).count() > 0) {
// student is enrolled in class
}
Alternatively, you could remove the "course" : courseId clause and get back a set of all classes the student is enrolled in.
I am trying to explain by putting problem statement and solution to it. I hope it will help
Problem Statement:
Find all the published products, whose name like ABC Product or PQR Product, and price should be less than 15/-
Solution:
Below are the conditions that need to be taken care of
- Product price should be less than 15
- Product name should be either ABC Product or PQR Product
- Product should be in published state.
Below is the statement that applies above criterion to create query and fetch data.
$elements = $collection->find(
Array(
[price] => Array( [$lt] => 15 ),
[$or] => Array(
[0]=>Array(
[product_name]=>Array(
[$in]=>Array(
[0] => ABC Product,
[1]=> PQR Product
)
)
)
),
[state]=>Published
)
);
'IT박스' 카테고리의 다른 글
| UDP를 사용하는 JavaScript WebSocket? (0) | 2020.11.12 |
|---|---|
| Reactive와 Functional-Reactive 프로그래밍의 차이점 (0) | 2020.11.12 |
| 주어진 키가 사전에 없습니다. (0) | 2020.11.12 |
| Binary Space Partitioning, Quadtree, Octree를 언제 사용합니까? (0) | 2020.11.12 |
| "정적 컨텍스트에서 비 정적 메서드를 참조 할 수 없습니다."오류 (0) | 2020.11.12 |