sql >> データベース >  >> NoSQL >> MongoDB

mongodbでのページネーションの実装

    あなたが話している概念は「フォワードページング」と呼ぶことができます。その理由は、.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を評価して破棄します コンテンツなので、あまり成長しません。

    これが、練習と学習のための「フォワードページング」の基本概念です。



    1. ハウツー:ClouderaManagerを使用してClouderaSearchをクラスターに追加する

    2. NodeJsアプリケーションとモジュール間でMongodbへの接続を適切に再利用する方法

    3. MongoDBインデックス交差

    4. Redisは複数のIPにバインドします