MongoDB에서 여러 배열을 하나의 배열로 합치기
여러 개의 배열을 하나의 배열로 통합하려면 MongoDB의 $project 연산자를 활용하면 됩니다. 먼저 문서를 포함하는 컬렉션을 생성해 보겠습니다.
> db.demo119.insertOne(
... {
... "_id": 101,
... "WebDetails": [
... {
... "ImagePath": "/all/image1",
... "isCorrect": "false"
... },
... {
... "ImagePath": "/all/image2",
... "isCorrect": "true"
... }
... ],
... "ClientDetails": [
... {
... "Name": "Chris",
... "isCorrect": "false"
... },
... {
... "Name": "David",
... "isCorrect": "true"
... }
... ]
... }
... );
{ "acknowledged" : true, "insertedId" : 101 }
find() 메서드를 사용하면 컬렉션의 모든 문서를 확인할 수 있습니다.
> db.demo119.find();
위 쿼리는 다음과 같은 결과를 출력합니다.
{
"_id" : 101, "WebDetails" : [
{ "ImagePath" : "/all/image1", "isCorrect" : "false" },
{ "ImagePath" : "/all/image2", "isCorrect" : "true" } ], "ClientDetails" : [
{ "Name" : "Chris", "isCorrect" : "false" }, { "Name" : "David", "isCorrect" : "true" }
]
}다음은 MongoDB에서 여러 배열을 하나의 배열로 집계하는 쿼리입니다.
>
> db.demo119.aggregate([
... { "$project": {
... "AllDetails": {
... "$filter": {
... "input": {
... "$setUnion": [
... { "$ifNull": [ "$WebDetails", [] ] },
... { "$ifNull": [ "$ClientDetails", [] ] }
... ]
... },
... "as": "out",
... "cond": { "$eq": [ "$$out.isCorrect", "false" ] }
... }
... }
... }},
... { "$match": { "AllDetails.0": { "$exists": true } } }
... ])
실행 결과는 다음과 같습니다.
{ "_id" : 101, "AllDetails" : [ { "ImagePath" : "/all/image1", "isCorrect" : "false" }, { "Name" : "Chris", "isCorrect" : "false" } ] }쿼리 동작 원리 살펴보기
위 집계 파이프라인이 어떻게 동작하는지 단계별로 정리하면 다음과 같습니다.
$setUnion: WebDetails와 ClientDetails 두 배열을 중복 없이 하나로 병합합니다.
$ifNull: 해당 필드가 문서에 존재하지 않을 경우 빈 배열([])로 대체하여 오류를 방지합니다.
$filter: 병합된 배열에서 isCorrect 값이 "false"인 요소만 골라냅니다.
$match: AllDetails 배열에 최소 한 개 이상의 요소가 존재하는 문서만 최종 결과로 반환합니다.
이처럼 $project와 함께 $setUnion, $filter 등의 연산자를 조합하면 서로 다른 배열 필드를 손쉽게 하나의 배열로 통합하고, 원하는 조건에 맞는 데이터만 효율적으로 추출할 수 있습니다.