MongoDB에서 객체(object) 배열을 검색하려면 $elemMatch 연산자를 사용해야 합니다. 이 연산자는 배열 내부의 요소 중 여러 개의 필드 조건을 동시에 만족하는 문서를 조회할 수 있도록 도와줍니다.
테스트용 컬렉션 생성하기
개념을 이해하기 위해 먼저 문서가 포함된 컬렉션을 생성해 보겠습니다. 아래 명령어로 컬렉션과 문서를 생성합니다.
> db.searchArrayDemo.insertOne({"EmployeeFirstName":"Adam","EmployeeLastName":"Smith","EmployeeDateOfBirth":new ISODate("1992-01-31 13:45:10"),
... "EmployeeSkills":["Spring and Hibernate Framework","Machine Learning"],
... "EmployeeDetails":[
... {
... "EmployeePerformanceArea":"Java",
... "Year":2001
... },
... {
... "EmployeePerformanceArea":"Python",
... "Year":2005
... }
... ]
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5c77b3812386c62d05142a6a")
}
> db.searchArrayDemo.insertOne({"EmployeeFirstName":"Carol","EmployeeLastName":"Taylor",
"EmployeeDateOfBirth":new ISODate("1993-04-21 11:10:20"),
"EmployeeSkills":["C++","Cloud Computing"], "EmployeeDetails":[ {
"EmployeePerformanceArea":"C++", "Year":1998 }, { "EmployeePerformanceArea":"C++
Game Developer", "Year":2007 } ] } );
{
"acknowledged" : true,
"insertedId" : ObjectId("5c77b58f2386c62d05142a6b")
}이제 find() 메서드를 사용하여 컬렉션의 모든 문서를 출력해 보겠습니다.
> db.searchArrayDemo.find().pretty();
실행 결과는 다음과 같습니다.
{
"_id" : ObjectId("5c77b3812386c62d05142a6a"),
"EmployeeFirstName" : "Adam",
"EmployeeLastName" : "Smith",
"EmployeeDateOfBirth" : ISODate("1992-01-31T13:45:10Z"),
"EmployeeSkills" : [
"Spring and Hibernate Framework",
"Machine Learning"
],
"EmployeeDetails" : [
{
"EmployeePerformanceArea" : "Java",
"Year" : 2001
},
{
"EmployeePerformanceArea" : "Python",
"Year" : 2005
}
]
}
{
"_id" : ObjectId("5c77b58f2386c62d05142a6b"),
"EmployeeFirstName" : "Carol",
"EmployeeLastName" : "Taylor",
"EmployeeDateOfBirth" : ISODate("1993-04-21T11:10:20Z"),
"EmployeeSkills" : [
"C++",
"Cloud Computing"
],
"EmployeeDetails" : [
{
"EmployeePerformanceArea" : "C++",
"Year" : 1998
},
{
"EmployeePerformanceArea" : "C++ Game Developer",
"Year" : 2007
}
]
}위 데이터를 기준으로 MongoDB에서 객체 배열을 검색하는 방법을 두 가지 경우로 나누어 살펴보겠습니다.
케이스 1: 조건에 맞는 요소가 존재하는 경우
배열 안에서 주어진 요소를 찾은 경우입니다. 다음 쿼리를 실행해 보겠습니다.
> db.searchArrayDemo.find({EmployeeDetails:{$elemMatch:{EmployeePerformanceArea : "C++", Year : 1998}}}).pretty();EmployeePerformanceArea가 "C++"이면서 Year가 1998인 요소를 하나의 객체 안에서 동시에 만족하는 문서만 반환됩니다. 실행 결과는 다음과 같습니다.
{
"_id" : ObjectId("5c77b58f2386c62d05142a6b"),
"EmployeeFirstName" : "Carol",
"EmployeeLastName" : "Taylor",
"EmployeeDateOfBirth" : ISODate("1993-04-21T11:10:20Z"),
"EmployeeSkills" : [
"C++",
"Cloud Computing"
],
"EmployeeDetails" : [
{
"EmployeePerformanceArea" : "C++",
"Year" : 1998
},
{
"EmployeePerformanceArea" : "C++ Game Developer",
"Year" : 2007
}
]
}케이스 2: 조건에 맞는 요소가 존재하지 않는 경우
반대로 배열 안에서 주어진 요소를 찾지 못한 경우입니다. 다음 쿼리를 실행해 보겠습니다.
> db.searchArrayDemo.find({EmployeeDetails:{$elemMatch:{EmployeePerformanceArea : "C", Year : 1996}}}).pretty();조건에 맞는 요소가 존재하지 않으면 아무런 결과도 반환되지 않습니다.
정리
$elemMatch 연산자는 배열 내 단일 객체가 여러 조건을 모두 충족하는지 확인할 때 유용합니다. 만약 각 조건이 서로 다른 배열 요소에 걸쳐 매칭되어도 괜찮다면, 점 표기법(dot notation)으로도 배열 필드를 조회할 수 있습니다. 하지만 하나의 배열 요소가 여러 조건을 동시에 만족해야 하는 경우에는 반드시 $elemMatch를 사용해야 정확한 결과를 얻을 수 있습니다.