2013-01-10 16 views
6

大規模なMongoDBコレクションでrange based paginationのベストプラクティスに精通していますが、ソート値が非固有フィールドにあるコレクションのページを設定する方法を考え出すのに苦労しています。MongoDB - ユニークでないフィールドに基づくページ設定

たとえば、私は大量のユーザーを集めており、何回か何回か作業した回数のフィールドがあります。このフィールドは基本的に一意ではなく、同じ値を持つ大きな文書グループを持つことができます。

「numTimesDoneSomething」フィールドでソートされた結果を返したいと思います。ここで

は、サンプルデータセットである:

{_id: ObjectId("50c480d81ff137e805000003"), numTimesDoneSomething: 12} 
{_id: ObjectId("50c480d81ff137e805000005"), numTimesDoneSomething: 9} 
{_id: ObjectId("50c480d81ff137e805000006"), numTimesDoneSomething: 7} 
{_id: ObjectId("50c480d81ff137e805000007"), numTimesDoneSomething: 1} 
{_id: ObjectId("50c480d81ff137e805000002"), numTimesDoneSomething: 15} 
{_id: ObjectId("50c480d81ff137e805000008"), numTimesDoneSomething: 1} 
{_id: ObjectId("50c480d81ff137e805000009"), numTimesDoneSomething: 1} 
{_id: ObjectId("50c480d81ff137e805000004"), numTimesDoneSomething: 12} 
{_id: ObjectId("50c480d81ff137e805000010"), numTimesDoneSomething: 1} 
{_id: ObjectId("50c480d81ff137e805000011"), numTimesDoneSomething: 1} 

どのように私は、ページあたり2つのレコードを持つ「numTimesDoneSomething」でソートされた、このデータセットを返すでしょうか?

答えて

5

@cubbukはoffsetskip)を使用して、良い例を示していますが、また、彼は、同様の範囲であったページネーションのために示したクエリ成形することができます:ここ_idが一意になり、あなたがしているので

db.collection.find().sort({numTimesDoneSomething:-1, _id:1}) 

を実際には_idの範囲になり、numTimesDoneSomething12の2つのレコードの間であっても、結果が1つのページにあるべきかどうかについて一貫していなければなりません。

ので

var q = db.collection.find({_id: {$gt: last_id}}).sort({numTimesDoneSomething:-1, _id:1}).limit(2) 

があったページネーションのために非常に良い動作するはずのような単純なものをやって。

+0

「find({_ id:last_id})」は1つのレコードのみを返しますか? –

+1

検索クエリがlast_idより大きい必要がありますか?あなたの解決策は、新しい挿入のケースもカバーしています+) – cubbuk

+1

@cubbukああ本当の笑: – Sammaye

2

この場合、複数のフィールドを並べ替えることができます。並べ替えはnumTimesDoneSomethingidフィールドです。 id_ fieldは既に挿入タイムスタンプに従って昇順になっているので、反復処理中に新しいデータが挿入されない限り、重複データを反復処理せずにコレクション内をページ付けすることができます。

db.collection.find().sort({numTimesDoneSomething:-1, _id:1}).offset(index).limit(2)