MongoDB에서 배열 내부의 요소를 문서의 다른 필드 값과 비교하려면 aggregate() 메서드와 함께 $filter 연산자를 사용하면 됩니다. 이 글에서는 실제 예제를 통해 두 필드를 비교하여 조건에 맞는 배열 요소만 추출하는 방법을 단계별로 살펴보겠습니다.
1. 샘플 컬렉션 생성
먼저 테스트용 문서가 포함된 컬렉션을 생성합니다.
> db.demo137.insertOne(
{
Name1:"Chris",
Name2:"David",
Detail1:[
{_id:"John", Name3:"Chris"},
{_id:"Chris", Name3:"Chris"},
],
Detail2:[{_id:"David", Name3:"Chris"},
{_id:"Carol", Name3:"Chris"},
{_id:"John", Name3:"Chris"}]
}
);
{
"acknowledged" : true,
"insertedId" : ObjectId("5e31b4cefdf09dd6d08539a0")
}2. 저장된 문서 확인하기
find() 메서드를 사용하면 컬렉션의 모든 문서를 조회할 수 있습니다.
> db.demo137.find();
위 쿼리를 실행하면 다음과 같은 결과가 출력됩니다.
{
"_id" : ObjectId("5e31b4cefdf09dd6d08539a0"), "Name1" : "Chris", "Name2" : "David", "Detail1" : [
{ "_id" : "John", "Name3" : "Chris" },
{ "_id" : "Chris", "Name3" : "Chris" } ], "Detail2" : [ { "_id" : "David", "Name3" : "Chris" },
{ "_id" : "Carol", "Name3" : "Chris" }, { "_id" : "John", "Name3" : "Chris" }
]
}3. 집계 파이프라인에서 $filter로 두 필드 비교하기
이제 핵심 부분입니다. $project 단계 안에서 $filter를 사용하여 배열 요소의 _id 값과 문서의 최상위 필드(Name1, Name2)를 $eq 연산자로 비교합니다. 조건이 일치하는 요소만 결과 배열에 남게 됩니다.
> db.demo137.aggregate([
{
$project: {
_id: 0,
Name1: 1,
Name2: 2,
Detail1: {
$filter: {
input: "$Detail1",
as: "out",
cond: {
$eq: ["$$out._id", "$Name1" ]
}
}
},
Detail2: {
$filter: {
input: "$Detail2",
as: "out",
cond: {
$eq: ["$$out._id", "$Name2" ]
}
}
}
}
}
])4. 실행 결과 확인
쿼리 실행 후 출력되는 결과는 다음과 같습니다.
{
"Name1" : "Chris", "Name2" : "David", "Detail1" : [
{ "_id" : "Chris", "Name3" : "Chris" } ], "Detail2" : [ { "_id" : "David", "Name3" : "Chris" }
]
}결과 분석
결과를 보면 Detail1 배열에서는 _id가 Name1 필드 값("Chris")과 일치하는 요소만 남았고, Detail2 배열에서는 _id가 Name2 필드 값("David")과 일치하는 요소만 추출되었습니다.
핵심 포인트 정리
- input: 필터링할 대상 배열을 지정합니다.
- as: 각 배열 요소를 참조할 변수 이름을 정의합니다. 쿼리 내에서
$$변수명형태로 접근합니다. - cond: 각 요소가 결과에 포함될지 결정하는 조건식입니다. 여기서는
$eq로 배열 요소의 값과 문서의 다른 필드 값을 비교했습니다.
이처럼 $filter와 $project를 조합하면 배열 데이터를 유연하게 가공할 수 있으며, 특히 배열 내부 값과 문서의 다른 필드를 동적으로 비교해야 하는 상황에서 매우 유용합니다.