MongoDB에서 특정 중첩 속성에 대해 프로젝션(projection)을 수행하려면 aggregate() 메서드를 사용해야 합니다. 일반적인 find()의 프로젝션으로는 깊은 중첩 구조 내부의 특정 키만 선택적으로 필터링하기 어렵기 때문인데, 이때 집계 파이프라인의 $objectToArray, $filter, $arrayToObject 연산자를 조합하면 원하는 결과를 얻을 수 있습니다.
1. 샘플 컬렉션 생성
먼저 중첩된 문서를 포함하는 컬렉션을 생성해 보겠습니다.
> db.demo379.insertOne(
... {
... "details1" : {
... "details2" : {
... "details3" : {
... "10" : "John",
... "50" : "Chris",
... "40" : "David",
... "30":"Mike"
... }
... }
... }
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5e5a94f82ae06a1609a00b10")
}2. 전체 문서 확인
find() 메서드를 사용해 컬렉션의 모든 문서를 조회합니다.
> db.demo379.find().pretty();
위 쿼리는 다음과 같은 출력을 생성합니다.
{
"_id" : ObjectId("5e5a94f82ae06a1609a00b10"),
"details1" : {
"details2" : {
"details3" : {
"10" : "John",
"30" : "Mike",
"40" : "David",
"50" : "Chris"
}
}
}
}3. 특정 중첩 속성에 대한 프로젝션 쿼리
이제 특정 조건(여기서는 키 값이 35 이상 60 이하)에 맞는 중첩 속성만 추출하는 프로젝션 쿼리를 작성해 보겠습니다.
> db.demo379.aggregate([
... { "$addFields": {
... "details1.details2.details3": {
... "$arrayToObject": {
... "$filter": {
... "input": { "$objectToArray": "$details1.details2.details3" },
... "as": "out",
... "cond": {
... "$and": [
... { "$gte": ["$$out.k", "35"] },
... { "$lte": ["$$out.k", "60"] },
... ]
... }
... }
... }
... }
... } }
... ])쿼리 동작 방식
- $objectToArray: details3 객체를 키(key)-값(value) 쌍의 배열로 변환합니다.
- $filter: 변환된 배열에서 조건($gte, $lte)을 만족하는 요소만 걸러냅니다.
- $arrayToObject: 필터링된 배열을 다시 객체 형태로 되돌립니다.
- $addFields: 기존 필드를 새로 계산된 값으로 대체합니다.
위 쿼리는 다음과 같은 출력을 생성합니다.
{ "_id" : ObjectId("5e5a94f82ae06a1609a00b10"), "details1" : { "details2" : { "details3" : { "40" : "David", "50" : "Chris" } } } }출력 결과를 보면 키가 35~60 범위에 해당하는 "40": "David"와 "50": "Chris"만 남고, 나머지 항목들은 제거된 것을 확인할 수 있습니다.