개요
MongoDB에서 배열 안에 저장된 값이 특정 범위(예: 600 초과, 900 미만)에 속하는지 확인하려면 비교 연산자인 $gt와 $lt를 사용합니다. 특히 배열의 같은 요소 하나가 모든 조건을 동시에 만족해야 하는 경우에는 $elemMatch 연산자를 함께 사용하는 것이 정확한 결과를 얻는 핵심입니다.
1. 테스트용 컬렉션 생성
먼저 실습에 사용할 문서들을 담은 컬렉션을 생성해 보겠습니다. 각 문서는 이름(Name)과 상품 가격 정보를 담고 있는 productDetails 배열로 구성됩니다.
> db.demo341.insertOne({
... "Name": "Chris",
... "productDetails" : [
... {
... "ProductPrice" : {
... "Price" : 800
... }
... },
... {
... "ProductPrice" : {
... "Price" : 400
... }
... },
... {
... "ProductPrice" : {
... "Price" : 300
... }
... }
... ]
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5e53ed5cf8647eb59e5620a7")
}
> db.demo341.insertOne({
... "Name": "Chris",
... "productDetails" : [
... {
... "ProductPrice" : {
... "Price" : 1000
... }
... },
... {
... "ProductPrice" : {
... "Price" : 1200
... }
... },
... {
... "ProductPrice" : {
... "Price" : 1300
... }
... }
... ]
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5e53edc1f8647eb59e5620a8")
}첫 번째 문서에는 가격이 800, 400, 300인 상품이, 두 번째 문서에는 가격이 1000, 1200, 1300인 상품이 각각 포함되어 있습니다.
2. 저장된 전체 문서 조회
find() 메서드를 사용하면 컬렉션의 모든 문서를 확인할 수 있습니다.
> db.demo341.find();
실행 결과는 다음과 같습니다.
{
"_id" : ObjectId("5e53ed5cf8647eb59e5620a7"), "Name" : "Chris", "productDetails" : [
{ "ProductPrice" : { "Price" : 800 } }, { "ProductPrice" : { "Price" : 400 } },
{ "ProductPrice" : { "Price" : 300 } }
]
}
{
"_id" : ObjectId("5e53edc1f8647eb59e5620a8"), "Name" : "Chris", "productDetails" : [
{ "ProductPrice" : { "Price" : 1000 } }, { "ProductPrice" : { "Price" : 1200 } },
{ "ProductPrice" : { "Price" : 1300 } }
]
}3. $elemMatch로 범위 조건 쿼리 작성하기
이제 배열 요소 중 600 초과이면서 900 미만인 가격을 가진 문서를 찾는 집계(aggregation) 쿼리를 살펴보겠습니다.
> db.demo341.aggregate([
... { "$match": {
"productDetails": {
"$elemMatch": {
"ProductPrice.Price": {
"$gt": 600,
"$lt": 900
}
}
}
}}
... ]).pretty();
위 쿼리의 실행 결과는 다음과 같습니다.
{
"_id" : ObjectId("5e53ed5cf8647eb59e5620a7"),
"Name" : "Chris",
"productDetails" : [
{
"ProductPrice" : {
"Price" : 800
}
},
{
"ProductPrice" : {
"Price" : 400
}
},
{
"ProductPrice" : {
"Price" : 300
}
}
]
}결과 분석 및 주의 사항
첫 번째 문서의 productDetails 배열에는 가격이 800인 상품이 포함되어 있어 '600 초과, 900 미만' 조건을 동시에 만족하므로 결과에 반환되었습니다. 반면 두 번째 문서의 가격은 모두 1000 이상이어서 조건에 해당하지 않아 제외된 것을 확인할 수 있습니다.
$elemMatch는 배열 내 동일한 요소 하나가 모든 조건을 충족하는지 검사합니다. 만약 $elemMatch 없이 "ProductPrice.Price": { "$gt": 600, "$lt": 900 }처럼 단순하게 작성하면, 서로 다른 배열 요소가 각각 다른 조건을 부분적으로 만족하는 경우에도 매칭되어 의도치 않은 결과가 나올 수 있습니다. 따라서 배열 필드에 여러 조건을 동시에 적용할 때는 반드시 $elemMatch를 사용하는 것이 좋습니다.