2012-04-03 2 views
2

어떻게 현재 플레이어의 순위와 주변 플레이어 순위를 얻는 쿼리를 작성합니까? 예를 들어, 내가 이름을 가진 리더 수집을했고, 경우주변 플레이어와 mongo의 순위표

{name: 'John', pts: 123} 

요한 23 위치에 있다면, 나뿐만 아니라 22 및 24 대신에 사용자의 이름을 표시 할 것이 포인트.

John의 순위를 얻기 위해 pts가 123보다 큰 리더 보드 항목 수를 쿼리 할 수 ​​있지만, 현재 플레이어 바로 위와 아래에서 한 명의 플레이어를 효율적으로 얻으려면 어떻게해야합니까? 색인 위치만으로 항목을 얻을 수 있습니까?

나는 내가 먼저 수를 사용자, 다음 스킵 제한 쿼리의 순위 위치를 얻기 위해,이 쿼리를 만들 수 있다고 생각하지만 비효율적 인 것 같습니다 인덱스

의 효율적인 사용을하지 않는 것
db.leaderboards.find({pts:{$gt:123}}).count(); 
-> 23 

db.leaderboards.find().skip(21).limit(3) 

마지막 쿼리는 해당 인덱스를 사용하여 24 개의 레코드를 스캔하는 것처럼 보이지만 합리적으로 범위 쿼리 또는 이와 비슷한 방식으로 수행 할 수있는 방법이 있습니까? 사용자가 5 만 번째 순위와 같이 매우 낮은 순위 인 경우 문제가되는 것을 볼 수 있습니다.

답변

2

세 가지 쿼리를 수행해야합니다 :

var john = db.players.findOne({name: 'John'}) 
var next_player = db.players.find(
    {_id: {$ne: john._id}, pts: {$gte: john.pts}}).sort({pts:1,name:1}).limit(-1)[0] 
var previous_player = db.players.find(
    {_id: {$ne: john._id}, pts: {$lte: john.pts}}).sort({pts:-1,name:-1}).limit(-1)[0] 

는 이름과 점에 인덱스를 만듭니다.

+0

감사합니다. 어떻게 정렬했는지 알 수 없으므로이 레코드가 인접 레코드인지, 크거나 작은 레코드가 아닌지 어떻게 확인할 수 있습니까? 또한, explain()을 사용하여 쿼리 실행을 살펴 보았습니다. findOne과 작동하지 않는 것 같습니다. 내가 사용하는 색인을 어떻게 볼 수 있습니까? – MonkeyBonkey

+0

colleciton.find ({... query ...}). limit (-1) .explain()은 findOne()을 설명하는 것과 같습니다. –

+0

next_player 쿼리에서 현재 플레이어보다 높은 순위가 아닌 다음 인접 순위인지 어떻게 확인할 수 있습니까? – MonkeyBonkey