Computer >> 컴퓨터 >  >> 프로그래밍 >> MongoDB

MongoDB 배열에서 여러 조건(범위)으로 값 찾기 – $gt, $lt, $elemMatch 활용법

개요

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를 사용하는 것이 좋습니다.