MongoDB에서 필드 값을 비교하는 방법
일반적인 MongoDB 쿼리는 필드와 상수 값을 비교하지만, 때로는 같은 문서 내의 두 필드 값을 서로 비교해야 하는 경우가 있습니다. 예를 들어 'Value1이 Value2보다 큰 문서만 찾고 싶다'와 같은 요구 사항이 있을 수 있습니다.
이럴 때 $where 연산자를 사용하면 JavaScript 표현식을 통해 문서 내부의 필드 값들을 자유롭게 비교할 수 있습니다. 이번 글에서는 실제 예제를 통해 $where 연산자의 사용 방법을 단계별로 살펴보겠습니다.
1. 샘플 컬렉션 생성 및 문서 삽입
먼저 insertOne() 메서드를 사용해 비교 실습용 컬렉션을 만들고 문서를 삽입합니다.
> db.comparingFieldDemo.insertOne({"Value1":30,"Value2":40});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c9c99ed2d6669774125246e")
}
> db.comparingFieldDemo.insertOne({"Value1":60,"Value2":70});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c9c99f62d6669774125246f")
}
> db.comparingFieldDemo.insertOne({"Value1":160,"Value2":190});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c9c99ff2d66697741252470")
}
> db.comparingFieldDemo.insertOne({"Value1":200,"Value2":160});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c9c9a0b2d66697741252471")
}2. 저장된 전체 문서 확인하기
find() 메서드에 pretty()를 함께 사용하면 컬렉션의 모든 문서를 보기 좋게 출력할 수 있습니다.
> db.comparingFieldDemo.find().pretty();
위 쿼리를 실행하면 다음과 같은 결과가 출력됩니다.
{
"_id" : ObjectId("5c9c99ed2d6669774125246e"),
"Value1" : 30,
"Value2" : 40
}
{
"_id" : ObjectId("5c9c99f62d6669774125246f"),
"Value1" : 60,
"Value2" : 70
}
{
"_id" : ObjectId("5c9c99ff2d66697741252470"),
"Value1" : 160,
"Value2" : 190
}
{
"_id" : ObjectId("5c9c9a0b2d66697741252471"),
"Value1" : 200,
"Value2" : 160
}3. $where 연산자로 두 필드 값 비교하기
이제 핵심인 $where 연산자를 사용해 보겠습니다. this.Value1 > this.Value2라는 JavaScript 조건식을 전달하면, Value1이 Value2보다 큰 문서만 조회됩니다.
> db.comparingFieldDemo.find({ $where: "this.Value1 > this.Value2" } );실행 결과는 다음과 같습니다. 네 개의 문서 중 Value1(200)이 Value2(160)보다 큰 마지막 문서 하나만 반환된 것을 확인할 수 있습니다.
{ "_id" : ObjectId("5c9c9a0b2d66697741252471"), "Value1" : 200, "Value2" : 160 }4. 반대 조건으로 비교하기
비교 연산자를 반대로 바꾸면 Value1이 Value2보다 작은 문서들을 조회할 수도 있습니다.
> db.comparingFieldDemo.find({ $where: "this.Value1 < this.Value2" } );실행 결과, 세 개의 문서가 조건에 해당하여 반환됩니다.
{ "_id" : ObjectId("5c9c99ed2d6669774125246e"), "Value1" : 30, "Value2" : 40 }
{ "_id" : ObjectId("5c9c99f62d6669774125246f"), "Value1" : 60, "Value2" : 70 }
{ "_id" : ObjectId("5c9c99ff2d66697741252470"), "Value1" : 160, "Value2" : 190 }참고: $expr 연산자라는 더 나은 대안
MongoDB 3.6 이상을 사용한다면 $expr 연산자와 집계 표현식($gt, $lt 등)을 조합하는 방식을 권장합니다. $expr은 인덱스를 활용할 수 있어 $where보다 성능 면에서 유리합니다.
> db.comparingFieldDemo.find({ $expr: { $gt: ["$Value1", "$Value2"] } });정리
- $where 연산자: JavaScript 문자열 또는 함수를 사용해 문서 내 필드 값을 유연하게 비교할 수 있습니다.
- this 키워드: 현재 처리 중인 문서를 가리키며,
this.Value1 > this.Value2형태로 조건을 작성합니다. - 성능 주의:
$where는 각 문서마다 JavaScript를 실행하므로 대용량 컬렉션에서는 속도가 느릴 수 있으며, 가능하면$expr사용을 고려하는 것이 좋습니다.