MongoDB에서 배열 필드를 해제(unwind)하려면 $unwind 연산자를 사용합니다. $unwind는 입력 문서의 배열 필드를 분해하여 각 요소마다 하나의 문서를 출력해 줍니다. 이 글에서는 두 개의 배열을 동시에 해제하고, 인덱스를 기준으로 요소들을 짝지어 조회하는 방법을 살펴보겠습니다.
1. 샘플 컬렉션 생성
먼저 데모용 컬렉션을 만들고 문서를 삽입합니다.
> db.demo515.insertOne(
... {
... "details1": [
... "4700100004"
... ],
... "details2": [
... "Not Given"
... ],
... "Value1": [
... "56",
... "45",
... "35"
... ],
... "Value2": [
... "35",
... "45",
... "56"
... ]}
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5e889e51987b6e0e9d18f590")
}2. find() 메서드로 문서 확인
find() 메서드를 사용하면 컬렉션의 모든 문서를 조회할 수 있습니다.
> db.demo515.find();
위 쿼리는 다음과 같은 결과를 출력합니다.
{ "_id" : ObjectId("5e889e51987b6e0e9d18f590"), "details1" : [ "4700100004" ], "details2" : [ "Not Given" ], "Value1" : [ "56", "45", "35" ], "Value2" : [ "35", "45", "56" ] }3. 두 개의 배열을 해제하는 쿼리
두 배열(Value1, Value2)을 해제하려면 애그리게이션 파이프라인에서 $unwind를 두 번 사용합니다. 이때 includeArrayIndex 옵션을 활용하면 각 요소의 인덱스를 별도 필드로 저장할 수 있고, $project와 $match를 조합하면 두 배열에서 같은 위치(인덱스)에 있는 요소들만 매칭시킬 수 있습니다.
> db.demo515.aggregate([
... { $unwind: { path: "$Value1", includeArrayIndex : "index1" } },
... { $unwind: { path: "$Value2", includeArrayIndex : "index2" } },
... { $project: {
... _id : 1,
... details1: 1,
... details2: 1,
... Value1: 1,
... Value2: 1,
... valid: { $eq: ["$index1", "$index2"] } }
... },
... { $match: { valid: true } }
... ]);4. 실행 결과
위 애그리게이션은 다음과 같은 출력을 생성합니다.
{ "_id" : ObjectId("5e889e51987b6e0e9d18f590"), "details1" : [ "4700100004" ], "details2" : [ "Not Given" ], "Value1" : "56", "Value2" : "35", "valid" : true }
{ "_id" : ObjectId("5e889e51987b6e0e9d18f590"), "details1" : [ "4700100004" ], "details2" : [ "Not Given" ], "Value1" : "45", "Value2" : "45", "valid" : true }
{ "_id" : ObjectId("5e889e51987b6e0e9d18f590"), "details1" : [ "4700100004" ], "details2" : [ "Not Given" ], "Value1" : "35", "Value2" : "56", "valid" : true }동작 원리 정리
이 쿼리의 핵심은 다음과 같습니다.
$unwind 단계: Value1과 Value2 배열을 각각 해제하여 모든 요소 조합의 카티션 곱(cartesian product)을 생성합니다. includeArrayIndex 옵션이 index1, index2 필드에 각 요소의 원래 배열 위치를 기록합니다.
$project 단계: 필요한 필드만 선택하고, $eq 연산자로 index1과 index2가 같은지 비교한 결과를 valid 필드에 저장합니다.
$match 단계: valid가 true인 문서, 즉 두 배열에서 동일한 인덱스 위치에 있는 요소들의 쌍만 최종 결과로 남깁니다.
이 패턴은 두 배열의 요소를 위치 기준으로 짝지어야 하는 경우, 예를 들어 키-값 쌍이 서로 다른 배열에 나뉘어 저장된 데이터를 처리할 때 특히 유용합니다.