あなたが話している概念は「フォワードページング」と呼ぶことができます。その理由は、.skip()
を使用する場合とは異なります。 および.limit()
修飾子これを使用して前のページに「戻る」ことや、実際に特定のページに「スキップ」することはできません。少なくとも、「表示」または「検出」ページを保存するために多大な労力を費やすことはありません。したがって、そのタイプの「ページへのリンク」ページングが必要な場合は、.skip()
および.limit()
パフォーマンスの欠点にもかかわらず、アプローチ。
「前進」するだけで実行可能なオプションである場合、基本的な概念は次のとおりです。
db.junk.find().limit(3)
{ "_id" : ObjectId("54c03f0c2f63310180151877"), "a" : 1, "b" : 1 }
{ "_id" : ObjectId("54c03f0c2f63310180151878"), "a" : 4, "b" : 4 }
{ "_id" : ObjectId("54c03f0c2f63310180151879"), "a" : 10, "b" : 10 }
もちろん、これが最初のページで、アイテム数は3つに制限されています。カーソルを反復するコードを使用して、次のことを検討してください。
var lastSeen = null;
var cursor = db.junk.find().limit(3);
while (cursor.hasNext()) {
var doc = cursor.next();
printjson(doc);
if (!cursor.hasNext())
lastSeen = doc._id;
}
カーソルを繰り返して何かを実行し、カーソルの最後の項目に到達したことがtrueの場合、lastSeen
を保存します。 現在の_id
の値 :
ObjectId("54c03f0c2f63310180151879")
以降の反復では、その_id
をフィードするだけです。 クエリに対して(セッション中などに)保持する値:
var cursor = db.junk.find({ "_id": { "$gt": lastSeen } }).limit(3);
while (cursor.hasNext()) {
var doc = cursor.next();
printjson(doc);
if (!cursor.hasNext())
lastSeen = doc._id;
}
{ "_id" : ObjectId("54c03f0c2f6331018015187a"), "a" : 1, "b" : 1 }
{ "_id" : ObjectId("54c03f0c2f6331018015187b"), "a" : 6, "b" : 6 }
{ "_id" : ObjectId("54c03f0c2f6331018015187c"), "a" : 7, "b" : 7 }
そして、これ以上結果が得られなくなるまで、このプロセスが何度も繰り返されます。
これが、_id
などの自然な順序の基本的なプロセスです。 。他の何かのために、それはもう少し複雑になります。次のことを考慮してください:
{ "_id": 4, "rank": 3 }
{ "_id": 8, "rank": 3 }
{ "_id": 1, "rank": 3 }
{ "_id": 3, "rank": 2 }
それをランクでソートされた2つのページに分割するには、基本的に知っておく必要があるのは、「すでに見た」ものであり、それらの結果を除外します。したがって、最初のページを見てください:
var lastSeen = null;
var seenIds = [];
var cursor = db.junk.find().sort({ "rank": -1 }).limit(2);
while (cursor.hasNext()) {
var doc = cursor.next();
printjson(doc);
if ( lastSeen != null && doc.rank != lastSeen )
seenIds = [];
seenIds.push(doc._id);
if (!cursor.hasNext() || lastSeen == null)
lastSeen = doc.rank;
}
{ "_id": 4, "rank": 3 }
{ "_id": 8, "rank": 3 }
次の反復では、lastSeenの「ランク」スコア以下にする必要がありますが、すでに表示されているドキュメントも除外します。これは、 $nin
を使用して行います 演算子:
var cursor = db.junk.find(
{ "_id": { "$nin": seenIds }, "rank": "$lte": lastSeen }
).sort({ "rank": -1 }).limit(2);
while (cursor.hasNext()) {
var doc = cursor.next();
printjson(doc);
if ( lastSeen != null && doc.rank != lastSeen )
seenIds = [];
seenIds.push(doc._id);
if (!cursor.hasNext() || lastSeen == null)
lastSeen = doc.rank;
}
{ "_id": 1, "rank": 3 }
{ "_id": 3, "rank": 2 }
実際に保持する「seenIds」の数は、その値が変化する可能性が高い結果がどれだけ「きめ細かい」かによって異なります。この場合、現在の「ランク」スコアがlastSeen
と等しくないかどうかを確認できます。 現在のseenIds
を評価して破棄します コンテンツなので、あまり成長しません。
これが、練習と学習のための「フォワードページング」の基本概念です。