18. MongoDB Query Part 8. - cursors
이번 포스팅에서는 Cursors
에 대해 알아보도록 하겠습니다.
Cursors
는 MongoDB가 find()
메써드를 통해 넘겨주는 결과의 집합입니다.
Cursors
를 통해 클라이언트-사이드에서는 반복 처리 등 다양한 처리가 가능합니다. DB가 넘겨주는 결과수를 제한할 수 있으며, 결과의 개수를 건너뛸 수 있으며, key 조합을 통해 결과를 분류하거나 검색 방향을 제어할 수 있는 등 기타 강력한 오퍼레이션을 구성할 수 있습니다.
우선 간단한 예로써, 각 도큐먼트에 1에서 100까지의 정수를 저장하는 JavaScript를 작성해 보도록 하겠습니다:
for(i=1; i<101; i++) {
db.count.insert({cnt : i});
}
var myCursor = db.count.find();
Shell에서 다음과 같이 cursor
를 입력하면, 도큐먼트가 20개까지 출력되는 것을 확인할 수 있을 것입니다.
> myCursor
{ "_id" : ObjectId("52f381cc2d911bccacf21963"), "cnt" : 1 }
{ "_id" : ObjectId("52f381cc2d911bccacf21964"), "cnt" : 2 }
{ "_id" : ObjectId("52f381cc2d911bccacf21965"), "cnt" : 3 }
{ "_id" : ObjectId("52f381cc2d911bccacf21966"), "cnt" : 4 }
{ "_id" : ObjectId("52f381cc2d911bccacf21967"), "cnt" : 5 }
{ "_id" : ObjectId("52f381cc2d911bccacf21968"), "cnt" : 6 }
{ "_id" : ObjectId("52f381cc2d911bccacf21969"), "cnt" : 7 }
{ "_id" : ObjectId("52f381cc2d911bccacf2196a"), "cnt" : 8 }
{ "_id" : ObjectId("52f381cc2d911bccacf2196b"), "cnt" : 9 }
{ "_id" : ObjectId("52f381cc2d911bccacf2196c"), "cnt" : 10 }
{ "_id" : ObjectId("52f381cc2d911bccacf2196d"), "cnt" : 11 }
{ "_id" : ObjectId("52f381cc2d911bccacf2196e"), "cnt" : 12 }
{ "_id" : ObjectId("52f381cc2d911bccacf2196f"), "cnt" : 13 }
{ "_id" : ObjectId("52f381cc2d911bccacf21970"), "cnt" : 14 }
{ "_id" : ObjectId("52f381cc2d911bccacf21971"), "cnt" : 15 }
{ "_id" : ObjectId("52f381cc2d911bccacf21972"), "cnt" : 16 }
{ "_id" : ObjectId("52f381cc2d911bccacf21973"), "cnt" : 17 }
{ "_id" : ObjectId("52f381cc2d911bccacf21974"), "cnt" : 18 }
{ "_id" : ObjectId("52f381cc2d911bccacf21975"), "cnt" : 19 }
{ "_id" : ObjectId("52f381cc2d911bccacf21976"), "cnt" : 20 }
Type "it" for more
위의 Shell에 출력된 부분의 가장 아래 라인에서 보는 것처럼 it
를 입력하면 계속해서 20개씩 도큐먼트를 출력할 수 있습니다.
만약 it
를 입력하여 다음 20개의 도큐먼트를 출력하지 않았다면, 현재 커서의 위치는 20번째 도큐먼트에 있을 것입니다. 만약 커서를 다음 도큐먼트(cnt: 21
)로 이동하려면 다음 명령을 수행합니다:
> var myDocument = myCursor.hasNext() ? myCursor.next() : null;
> myDocument
{ "_id" : ObjectId("52f381cc2d911bccacf21977"), "cnt" : 21 }
myCusor.hasNext()
는 다음 도큐먼트가 있는지 검사합니다. 있다면 true
를, 없다면 false
를 반환한다. 만약 myCusor.hasNext()
가 true
이라면, 커서는 다음 도큐먼트로 이동(myCursor.next()
)하고 없으면 null
을 변수 myDocument
에 저장합니다.
앞서 myCursor가 20번째 도큐먼트에 있었다면 myDocument는 21번째 도큐먼트를 가리키고 있을 것입니다.
각각의 도큐먼트에 대해 무엇인가를 처리하고자 한다면 다음과 같이 while
문을 사용합니다:
while (myCursor.hasNext()) {
obj = myCursor.next();
// do something you want
}
만약 처음 10개의 도큐먼트를 건너뛴 후 다음 5개의 도큐먼트를 출력하려면 다음과 같이 입력합니다:
> var myCursor = db.count.find().sort({cnt : 1}).limit(5).skip(10);
> myCursor
{ "_id" : ObjectId("52f381cc2d911bccacf2196d"), "cnt" : 11 }
{ "_id" : ObjectId("52f381cc2d911bccacf2196e"), "cnt" : 12 }
{ "_id" : ObjectId("52f381cc2d911bccacf2196f"), "cnt" : 13 }
{ "_id" : ObjectId("52f381cc2d911bccacf21970"), "cnt" : 14 }
{ "_id" : ObjectId("52f381cc2d911bccacf21971"), "cnt" : 15 }
skip(x)
는 x
개 만큼을 건너뛰고, limit(y)
는 y
개 만큼을 출력하라는 의미입니다.
위의 명령어는 다음 명령어와도 동일합니다:
var myCursor = db.count.find().limit(5).sort({cnt : 1}).skip(10);
var myCursor = db.count.find().skip(10).limit(5).sort({cnt : 1});