MongoDB에서 배열로 중첩된 특정 내장 문서(embedded document)를 조회하려면 집계 파이프라인(aggregation pipeline)에서 $unwind 연산자를 두 번 사용하면 됩니다. 이 방법은 다차원 배열 구조를 개별 문서로 분해한 뒤, 원하는 조건에 맞는 데이터만 필터링할 수 있게 해줍니다.
1. 샘플 컬렉션 생성
먼저 중첩된 배열 구조를 가진 문서를 포함하는 컬렉션을 생성해 보겠습니다.
> db.demo631.insert(
... {
... id: "101",
... Info1: [
... {
... CountryName : "US",
... Info2 : [
... {
... Name:"Chris",
... Age:24
... },{
...
... Name:"Bob",
... Age:22
... }
... ]
... }
... ]
... }
... );
WriteResult({ "nInserted" : 1 })위 문서는 Info1 배열 안에 국가 정보가 있고, 그 안의 Info2 배열에 사람별 이름과 나이가 저장된 2단계 중첩 구조입니다.
2. find() 메서드로 전체 문서 확인
find() 메서드를 사용해 컬렉션의 모든 문서를 출력합니다.
> db.demo631.find();
실행 결과는 다음과 같습니다.
{ "_id" : ObjectId("5e9b0eb16c954c74be91e6bf"), "id" : "101", "Info1" : [ { "CountryName" : "US", "Info2" : [ { "Name" : "Chris", "Age" : 24 }, { "Name" : "Bob", "Age" : 22 } ] } ] }3. $unwind와 $match로 특정 내장 문서 반환
이제 집계 파이프라인에서 $unwind를 두 번 적용해 각각의 배열을 분해한 후, $match로 조건에 맞는 문서만 필터링합니다. 아래 예제는 나이(Age)가 22인 내장 문서를 반환하는 쿼리입니다.
> db.demo631.aggregate([
... { "$unwind": "$Info1" },
... { "$unwind": "$Info1.Info2" },
... { "$match": { "Info1.Info2.Age": 22 } }
... ])쿼리 실행 결과는 다음과 같습니다.
{ "_id" : ObjectId("5e9b0eb16c954c74be91e6bf"), "id" : "101", "Info1" : { "CountryName" : "US", "Info2" : { "Name" : "Bob", "Age" : 22 } } }동작 원리 정리
- 첫 번째 $unwind: Info1 배열을 분해하여 각 요소(국가 정보)를 개별 문서로 만듭니다.
- 두 번째 $unwind: Info1.Info2 배열을 분해하여 각 사람 정보를 개별 문서로 만듭니다.
- $match: 분해된 문서 중 Age가 22인 문서만 필터링하여 최종 결과로 반환합니다.
이처럼 $unwind를 단계적으로 적용하면 깊게 중첩된 배열 구조에서도 원하는 특정 내장 문서를 손쉽게 추출할 수 있습니다.