본문으로 바로가기

내장 document 조회

하나의 field 에 document 로 저장된 경우 조회 시 다음과 같은 번거로움이 있다

db.sales.findOne({
    customer: {
        gender: 'F',
        age: 39,
        email: 'beecho@wic.be',
        satisfaction: 3
    }
})

위 처럼 하나의 조건을 document 기준으로 조회하려면 전부다 명시해야하며 1개라도 순서가 다른 경우 조회되지 않는다.

db.sales.findOne({
    customer: {
        satisfaction: 3, // <- 순서를 바꿈
        gender: 'F',
        age: 39,
        email: 'beecho@wic.be'
    }
})

결과는 null로 나타남

그래서 field 단위로 조회하기 위해서는 property 로 접근하듯 작성하면 된다

db.sales.findOne({
    "customer.email" : "beecho@wic.be"
})

db.sales.findOne({
    "customer.age" : { $lt: 20 }
})

배열 조회

아래 테스트 collections inventory 를 삽입하자

db.inventory.insertMany([
   { item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] },
   { item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] },
   { item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] },
   { item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] },
   { item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] },
   { item: "postcard", qty: 45, tags: ["blue", "red"], dim_cm: [ 13, 14 ] }
])

그리고 다음을 조회

db.inventory.find({
    tags: ["red", "blank"] // 순서 및 동일한 값만 조회된다
})

결과적으로 notebook 만 조회된다

만약 모두 포함하는 것을 조회하려면 all 을 사용한다 (and 처리)

db.inventory.find({
    tags: { $all: ["red", "blank"] } 
})

in 을 사용하면 or 처리 된다

db.inventory.find({
    tags: { $in: ["red", "blank"] } 
})

배열 인자 중 1개라도 일치하면 결과를 반환해주는 쿼리는 다음과 같다

db.inventory.find({
    tags: 'blue'
})

조건절에 비교 연산자를 사용하면 다음과 같다

db.inventory.find({
    dim_cm: { $gt: 15 }
})

다음과 같이 하면 between 의 결과를 예상할 수 있지만 결과는 다르게 나온다

db.inventory.find({
    dim_cm: { $gt: 15, $lt: 20 } // 15보다 크고 20보다 작은 것을 예상
})

결과에는 21의 값도 나옴. 그 이유는 조건에 해당하는 field 가 모두 존재하면 그 값을 반환하기 때문이다
예를 들어 14, 21 이면 15보다 큰 21의 값도 맞고 20보다 작은 14도 맞기 때문에 조회된다.
이를 풀어서 and 연산자로 사용해도 결과는 같고 or 연산자를 이용하면 하나라도 일치하는 경우로 22.85 값을 들고있는 planner 도 조회된다

db.inventory.find({
    $and: [
        { dim_cm: { $gt: 15 } },
        { dim_cm: { $lt: 20 } },
    ]
})

db.inventory.find({
    $or: [
        { dim_cm: { $gt: 15 } },
        { dim_cm: { $lt: 20 } },
    ]
})

elemMatch 연산자는 배열 요소 중 하나라도 모든 조건을 충족하는 것을 반환 시켜준다.

db.inventory.find({
    dim_cm: { $elemMatch: { $gt: 15, $lt: 20 } }
})

특정 요소 기준으로 조회하는 경우 property 처럼 접근하여 실행

db.inventory.find({
    "dim_cm.1" : { $lt: 20 }
})

배열 크기를 조회하는 경우 size 연산자 사용

db.inventory.find({
    tags: { $size: 3 }
})

다시 sample_supplies 로 이동하여 다음을 수행

db.sales.find({
    "items.name" : "binder",
    "items.quantity" : { $lte: 6 }
})

위를 실행하면 둘 중 1개라도 만족하는 조건의 document 를 반환한다.
따라서 둘다 만족하는 것을 조회하려면 elemMatch 를 사용해야한다

db.sales.find({
    items: {
        $elemMatch: {
            name: "binder",
            quantity: { $lte: 6 }
        }
    }
})

그런데 위의 쿼리는 또 모든 데이터를 조회하므로 필요한 것만 조회하려면 position 연산자를 사용한다

db.sales.find(
    {
        items: {
            $elemMatch: {
                name: "binder",
                quantity: { $lte: 6 }
            }
        }
    },
    {
        saleDate: 1,
        "items.$": 1,
        storeLocation: 1,
        customer: 1
    }
)

'Database > Mongo' 카테고리의 다른 글

자주 사용되는 Aggregation Stage  (0) 2023.03.14
배열과 내장 document 를 다루는 방법 (Update)  (0) 2023.03.06
유용한 Query 함수들  (0) 2023.03.06
MongoDB - 기본 CRUD 예제 2  (0) 2023.03.06
MongoDB - 기본 CRUD 예제 1  (0) 2023.03.06