MongoDB에서 배열 안에 포함된 중첩 필드(nested field)를 조건으로 검색하려면 $elemMatch 연산자를 사용해야 합니다. 이 연산자는 배열의 각 요소가 주어진 조건을 만족하는지 개별적으로 확인할 수 있어서, 객체 배열 형태로 저장된 데이터를 다룰 때 매우 유용합니다.
아래 예제를 통해 배열 내 중첩 필드를 쿼리하는 전체 과정을 단계별로 살펴보겠습니다.
1. 샘플 컬렉션 생성하기
먼저 클라이언트 정보를 담은 문서 두 개를 삽입해 테스트용 컬렉션을 만들겠습니다. 각 문서는 ClientDetails라는 배열 필드를 가지며, 배열의 각 요소는 클라이언트 이름(ClientName)과 프로젝트 이름(ClientProject)으로 구성되어 있습니다.
> db.demo153.insertOne({"ClientDetails":[{"ClientName":"Chris","ClientProject":"Online Banking System"},{"ClientName":"David","ClientProject":"Online School Management"}]});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e351957fdf09dd6d08539df")
}
> db.demo153.insertOne({"ClientDetails":[{"ClientName":"Carol","ClientProject":"Online Book System"},{"ClientName":"Mike","ClientProject":"Game Development"}]});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e3519c9fdf09dd6d08539e0")
}2. find()로 전체 문서 확인하기
find() 메서드를 호출하면 컬렉션에 저장된 모든 문서를 조회할 수 있습니다.
> db.demo153.find();
위 명령을 실행하면 다음과 같은 결과가 출력됩니다.
{
"_id" : ObjectId("5e351957fdf09dd6d08539df"), "ClientDetails" : [
{ "ClientName" : "Chris", "ClientProject" : "Online Banking System" },
{ "ClientName" : "David", "ClientProject" : "Online School Management" }
]
}
{
"_id" : ObjectId("5e3519c9fdf09dd6d08539e0"), "ClientDetails" : [
{ "ClientName" : "Carol", "ClientProject" : "Online Book System" },
{ "ClientName" : "Mike", "ClientProject" : "Game Development" }
]
}3. $elemMatch로 배열 내 중첩 필드 쿼리하기
이제 핵심인 배열 내 중첩 필드 쿼리 방법입니다. $elemMatch와 $in 연산자를 함께 사용하면, ClientDetails 배열의 요소 중 ClientProject 값이 "Online Banking System"인 문서만 정확하게 찾아낼 수 있습니다.
> db.demo153.find({"ClientDetails": { "$elemMatch" : {"ClientProject": { "$in": ["Online Banking System"] } } } });쿼리를 실행하면 해당 프로젝트를 포함하고 있는 첫 번째 문서만 반환됩니다.
{ "_id" : ObjectId("5e351957fdf09dd6d08539df"), "ClientDetails" : [ { "ClientName" : "Chris", "ClientProject" : "Online Banking System" }, { "ClientName" : "David", "ClientProject" : "Online School Management" } ] }$elemMatch를 사용해야 하는 이유
점 표기법(dot notation)으로 ClientDetails.ClientProject를 직접 조회하는 것도 가능하지만, 이 경우 배열의 서로 다른 요소들이 조건을 나누어 만족해도 문서가 반환될 수 있습니다. 반면 $elemMatch는 하나의 배열 요소가 모든 조건을 동시에 만족해야 한다는 점을 보장하므로, 여러 조건을 결합하는 복잡한 쿼리에서 훨씬 정확한 결과를 얻을 수 있습니다.