MongoDB에서 $and 대신 $in을 사용해야 하는 이유
배열 형태의 하위 컬렉션(내장 배열) 안에서 특정 조건에 맞는 문서를 조회할 때는 $and 연산자보다 $in 연산자를 사용하는 것이 효과적입니다. 특히 $elemMatch와 함께 사용하면 동일한 배열 요소 내에서 여러 조건이 모두 일치하는 문서만 정확하게 필터링할 수 있습니다.
테스트용 컬렉션 생성하기
먼저 예제로 사용할 컬렉션을 만들고 문서를 삽입하겠습니다.
> db.demo83.insertOne(
... {
... "Details":[
... {
... "Name":"Chris",
... "Subject":[
... "MySQL",
... "MongoDB"
... ]
... },
... {
... "Name":"David",
... "Subject":[
... "Java",
... "C"
... ]
... }
... ]
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5e2bfd2271bf0181ecc422a3")
}
> db.demo83.insertOne(
... {
... "Details":[
... {
... "Name":"Bob",
... "Subject":[
... "C++",
... "Python"
... ]
... },
... {
... "Name":"John",
... "Subject":[
... "Spring",
... "Hibernate"
... ]
... }
... ]
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5e2bfd4571bf0181ecc422a4")
}위 명령은 각각 두 개의 사람 정보(Name)와 과목 목록(Subject)을 담고 있는 Details 배열을 가진 문서 두 개를 demo83 컬렉션에 추가합니다.
find() 메서드로 전체 문서 확인하기
삽입된 모든 문서를 확인하려면 find() 메서드를 사용합니다.
> db.demo83.find();
실행 결과는 다음과 같습니다.
{
"_id" : ObjectId("5e2bfd2271bf0181ecc422a3"), "Details" : [
{ "Name" : "Chris", "Subject" : [ "MySQL", "MongoDB" ] },
{ "Name" : "David", "Subject" : [ "Java", "C" ] }
]
}
{
"_id" : ObjectId("5e2bfd4571bf0181ecc422a4"), "Details" : [
{ "Name" : "Bob", "Subject" : [ "C++", "Python" ] },
{ "Name" : "John", "Subject" : [ "Spring", "Hibernate" ] }
]
}$elemMatch와 $in을 조합한 조회 쿼리
이제 이름이 "Chris"이면서 과목 목록에 "MongoDB"가 포함된 문서를 찾아보겠습니다. 아래처럼 $elemMatch 안에서 $in 연산자를 사용하면 됩니다.
> db.demo83.find({ "Details" : { "$elemMatch" : {"Name" :"Chris" , "Subject":{"$in":["MongoDB"]}}}});쿼리 실행 결과는 다음과 같습니다.
{
"_id" : ObjectId("5e2bfd2271bf0181ecc422a3"), "Details" : [
{ "Name" : "Chris", "Subject" : [ "MySQL", "MongoDB" ] },
{ "Name" : "David", "Subject" : [ "Java", "C" ] }
]
}정리
배열 요소 내부의 여러 필드 조건을 동시에 검사할 때는 $elemMatch가 필수적입니다. 그리고 단일 필드에서 여러 값 중 하나라도 일치하는지 확인할 때는 $in 연산자가 가장 적합합니다. 이렇게 두 연산자를 조합하면 하위 컬렉션(배열) 구조의 문서도 정확하고 효율적으로 조회할 수 있습니다.