20. MongoDB Query Part 10. - 기타 쿼리 연산자들

이번 포스팅에서는 기타 쿼리(Query) 연산자들에 대해 알아 보도록 하겠습니다.

다음과 같은 도큐먼트를 생성합니다:

for(i = 1; i < 101; i++) {
    var myRandom = Math.floor(100 * Math.random());

    if(myRandom < 21)
        db.myCollection.insert({name: "dog", random: Math.floor(Math.random()*100)})
    else if(myRandom < 41)
        db.myCollection.insert({name: "cat", random: Math.floor(Math.random()*100)})
    else if(myRandom < 61)
        db.myCollection.insert({name: "pig", random: Math.floor(Math.random()*100)})
    else if(myRandom < 81)
        db.myCollection.insert({name: "horse", random: Math.floor(Math.random()*100)})
    else if(myRandom < 101)
        db.myCollection.insert({name: "cow", random: Math.floor(Math.random()*100)})
}

위의 JavaScript 코드내용은 다음과 같습니다:

(1) 100개의 도큐먼트를 생성하고 myCollection 컬렉션에 저장합니다.

(2) 루프를 반복할 때마다 랜덤수(0과 1사이 임의의 수)를 하나 발생하고 100을 곱한 후 소수이하를 제거하여,

  • 1에서 20사이인 경우: name을 "dog"로 지정하고 랜덤수를 하나 더 발생하여 random 키 값으로 저장,
  • 21에서 40사이인 경우: name을 "cat"로 지정하고 랜덤수를 하나 더 발생하여 random 키 값으로 저장,
  • 41에서 60사이인 경우: name을 "pig"로 지정하고 랜덤수를 하나 더 발생하여 random 키 값으로 저장,
  • 61에서 80사이인 경우: name을 "horse"로 지정하고 랜덤수를 하나 더 발생하여 random 키 값으로 저장,
  • 81에서 100사이인 경우: name을 "cow"로 지정하고 랜덤수를 하나 더 발생하여 random 키 값으로 저장합니다.

myCollection 내용을 살펴보면,

> db.myCollection.find()
{ "_id" : ObjectId("52f55a3cf96da4a35bad07ac"), "name" : "cat", "random" : 42 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07ad"), "name" : "cow", "random" : 29 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07ae"), "name" : "cow", "random" : 48 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07af"), "name" : "pig", "random" : 38 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07b0"), "name" : "pig", "random" : 49 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07b1"), "name" : "horse", "random" : 54 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07b2"), "name" : "horse", "random" : 81 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07b3"), "name" : "dog", "random" : 87 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07b4"), "name" : "pig", "random" : 69 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07b5"), "name" : "pig", "random" : 19 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07b6"), "name" : "horse", "random" : 45 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07b7"), "name" : "cow", "random" : 45 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07b8"), "name" : "dog", "random" : 8 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07b9"), "name" : "cow", "random" : 5 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07ba"), "name" : "horse", "random" : 14 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07bb"), "name" : "horse", "random" : 44 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07bc"), "name" : "cat", "random" : 99 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07bd"), "name" : "horse", "random" : 72 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07be"), "name" : "cow", "random" : 57 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07bf"), "name" : "dog", "random" : 99 }
Type "it" for more

도큐먼트들은 name의 키 값이 "dog", "cat", "horse", "pig", "cat"로 섞여있음을 볼 수 있습니다.

name의 키 값이 "pig"인 도큐먼트들을 추출하여 random 키 값을 오름차순 또는 내림차순 정렬해 보도록 하겠습니다.

우선 오름차순에 대한 명령은 다음과 같이 sort({key: 1})를 이용합니다:

> var cursor = db.myCollection.find({name : "pig"}).sort({random : 1})
> cursor
{ "_id" : ObjectId("52f55a3cf96da4a35bad07c7"), "name" : "pig", "random" : 5 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07ef"), "name" : "pig", "random" : 9 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad080a"), "name" : "pig", "random" : 12 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07b5"), "name" : "pig", "random" : 19 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07db"), "name" : "pig", "random" : 19 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07c4"), "name" : "pig", "random" : 34 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07af"), "name" : "pig", "random" : 38 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07c0"), "name" : "pig", "random" : 41 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad0805"), "name" : "pig", "random" : 42 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07b0"), "name" : "pig", "random" : 49 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad080f"), "name" : "pig", "random" : 50 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07e6"), "name" : "pig", "random" : 53 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07de"), "name" : "pig", "random" : 59 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07cb"), "name" : "pig", "random" : 65 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07d7"), "name" : "pig", "random" : 65 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07b4"), "name" : "pig", "random" : 69 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07fe"), "name" : "pig", "random" : 69 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07fd"), "name" : "pig", "random" : 76 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07d1"), "name" : "pig", "random" : 81 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07fb"), "name" : "pig", "random" : 90 }

내림차순에 대한 명령은 sort({key: -1})를 이용합니다:

> var cursor = db.myCollection.find({name : "pig"}).sort({random : -1})
> cursor
{ "_id" : ObjectId("52f55a3cf96da4a35bad07fb"), "name" : "pig", "random" : 90 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07d1"), "name" : "pig", "random" : 81 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07fd"), "name" : "pig", "random" : 76 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07b4"), "name" : "pig", "random" : 69 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07fe"), "name" : "pig", "random" : 69 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07cb"), "name" : "pig", "random" : 65 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07d7"), "name" : "pig", "random" : 65 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07de"), "name" : "pig", "random" : 59 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07e6"), "name" : "pig", "random" : 53 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad080f"), "name" : "pig", "random" : 50 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07b0"), "name" : "pig", "random" : 49 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad0805"), "name" : "pig", "random" : 42 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07c0"), "name" : "pig", "random" : 41 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07af"), "name" : "pig", "random" : 38 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07c4"), "name" : "pig", "random" : 34 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07b5"), "name" : "pig", "random" : 19 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07db"), "name" : "pig", "random" : 19 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad080a"), "name" : "pig", "random" : 12 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07ef"), "name" : "pig", "random" : 9 }
{ "_id" : ObjectId("52f55a3cf96da4a35bad07c7"), "name" : "pig", "random" : 5 }

다음은 기타 유용한 쿼리 옵션에 대하여 정리한 것입니다:

  • $maxScan : integer

    • 쿼리에 대해 스캔할 최대 도큐먼트 수 명시
    • 예: db.collection.find( { } )._addSpecial( "$maxScan" , )
  • $min : document

    • 쿼리에 대한 시작 조건 - min의 키 값보다 크거나 같은 값 검색
    • 예: db.collection.find( { } ).min( { field1: , ... fieldN: } )
  • $max : document

    • 쿼리에 대한 끝 조건 - max의 키 값보다 작거나 같은 값 검색
    • 예: db.collection.find( { } ).max( { field1: , ... fieldN: } )
  • $hint : document

    • 쿼리에 대해 어느 인덱스를 사용할 지 서버에 알려줌
    • 예: db.users.find( { $query: {}, $hint: { key : keyValue } } )
  • $explain : boolean

    • 실제 쿼리를 수행하는 대신 쿼가 수행될 내용(사용 인덱스, 결과 개수, 소요 시간 등) 명시
> db.myCollection.find( { $query: {}, $explain: 1 } ).pretty()
{
    "cursor" : "BasicCursor",
    "isMultiKey" : false,
    "n" : 100,
    "nscannedObjects" : 100,
    "nscanned" : 100,
    "nscannedObjectsAllPlans" : 100,
    "nscannedAllPlans" : 100,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "millis" : 0,
    "indexBounds" : {

    },
    "allPlans" : [
        {
            "cursor" : "BasicCursor",
            "n" : 100,
            "nscannedObjects" : 100,
            "nscanned" : 100,
            "indexBounds" : {

            }
        }
    ],
    "server" : "h002259.mongolab.com:30827"
}
  • $snapshot : boolean
    • 쿼리가 시행되는 시점으로부터 쿼리의 결과가 일정정한 스냅샷이 되도록 함.
    • 이에 대한 자세한 설명은 다음 글에 별도로 다루도록 하겠습니다.
    • db.collection.find().snapshot() 또는 다음 용법도 사용가능.
    • db.collection.find( { $query: {}, $snapshot: true } )