MongoDB 중첩 배열에서 특정 요소 추출하기
MongoDB에서 중첩된 배열 구조 안에 있는 특정 요소를 추출하려면 $elemMatch 연산자를 사용하면 됩니다. $elemMatch는 배열 내에서 지정한 조건과 일치하는 요소만 매칭해 주는 강력한 쿼리 연산자로, 여러 단계로 중첩된 배열을 다룰 때 특히 유용합니다.
이 글에서는 실제 예제를 통해 중첩 배열에서 원하는 데이터를 조회하는 방법을 단계별로 살펴보겠습니다.
1. 샘플 컬렉션 생성하기
먼저 테스트용 컬렉션을 만들고 문서를 삽입합니다. 아래 예제는 그룹 정보, 사용자 상세 정보, 친구 목록이 3단계로 중첩된 구조입니다.
> db.particularElementDemo.insertOne(
{
"GroupId" :"Group-1",
"UserDetails" : [
{
"UserName" : "John",
"UserOtherDetails" : [
{
"UserEmailId" : "John123@gmail.com",
"UserFriendName" : [
{
"Name" : "Chris"
}
]
},
{
"UserEmailId" : "John22@hotmail.com",
"UserFriendName" : [
{
"Name" : "Robert"
}
]
}
]
}
]
}
);
{ "acknowledged" : true, "insertedId" : 100 }2. 저장된 문서 확인하기
find() 메서드에 pretty()를 함께 사용하면 컬렉션의 모든 문서를 보기 좋게 출력할 수 있습니다.
> db.particularElementDemo.find().pretty();
위 명령을 실행하면 다음과 같은 결과가 출력됩니다.
{
"_id" : 100,
"GroupId" : "Group-1",
"UserDetails" : [
{
"UserName" : "John",
"UserOtherDetails" : [
{
"UserEmailId" : "John123@gmail.com",
"UserFriendName" : [
{
"Name" : "Chris"
}
]
},
{
"UserEmailId" : "John22@hotmail.com",
"UserFriendName" : [
{
"Name" : "Robert"
}
]
}
]
}
]
}3. $elemMatch로 중첩 배열의 특정 요소 조회하기
이제 핵심 부분입니다. 아래 쿼리는 세 단계로 중첩된 배열(UserDetails → UserOtherDetails → UserFriendName)에서 이름이 "Robert"인 친구가 포함된 문서를 찾고, 프로젝션을 통해 필요한 필드만 반환합니다.
> db.particularElementDemo.find(
{
'UserDetails':{
$elemMatch:{
'UserOtherDetails':{
$elemMatch:{
'UserFriendName':{ $elemMatch: {"Name" : "Robert"} }
}
}
}
}
},{"UserDetails.UserOtherDetails.UserFriendName.Name":1}
);쿼리 실행 결과는 다음과 같습니다.
{ "_id" : 100, "UserDetails" : [ { "UserOtherDetails" : [ { "UserFriendName" : [ { "Name" : "Chris" } ] }, { "UserFriendName" : [ { "Name" : "Robert" } ] } ] } ] }정리
$elemMatch 연산자를 중첩해서 사용하면 몇 단계든 깊은 배열 구조에서도 원하는 조건의 요소를 정확하게 매칭할 수 있습니다. 또한 두 번째 인자인 프로젝션(projection)을 활용하면 전체 문서 대신 필요한 필드만 효율적으로 가져올 수 있어, 대용량 데이터를 다루는 애플리케이션에서 응답 크기를 줄이고 성능을 개선하는 데 도움이 됩니다.