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

ソートされたページングの特定のレコードのスキップ値を計算します

    これは「フォワードページング」と呼ばれ、「ソートされた」結果を使用するときに、結果を「フォワード」方向に「効率的にページング」するために使用できる概念です。

    JavaScriptロジックが含まれていますが(シェルで機能するため)、変換するのは難しくありません。

    一般的な概念:

    { "_id": 1, "a": 3 },
    { "_id": 2, "a": 3 },
    { "_id": 3, "a": 3 },
    { "_id": 4, "a": 2 },
    { "_id": 5, "a": 1 },
    { "_id": 6, "a": 0 }
    

    1ページに「2」個のアイテムで「ページ」したい結果の例として、これらの「すでにソートされた」ドキュメント(便宜上)を考えてみてください。

    最初に、次のようなことを行います:

    var lastVal = null,
        lastSeen = [];
    
    db.collection.find().sort({ "a": -1 }).limit(2).forEach(function(doc) {
        if ( lastVal != doc.a ) {
            lastSeen = [];
        }
        lastVal = doc.a;
        lastSeen.push( doc._id );
        // do something useful with each document matched
    });
    

    今、それらのlastVal およびlastSeen 「セッション変数」のようなものに保存するものであり、Webアプリケーションに関して次のリクエストでアクセスできるもの、またはそうでない場合は同様のものです。

    ただし、それらに含まれるべきものは、ソートした最後の値と「一意の」_idのリストです。 その値以降に見られた値は変化しませんでした。したがって:

    lastVal = 3,
    lastSeen = [1,2];
    

    重要なのは、「次のページ」のリクエストが来たら、これらの変数を次のようなものに使用したいということです。

    var lastVal = 3,
        lastSeen = [1,2];
    
    db.collection.find({ 
        "_id": { "$nin": lastSeen }, 
        "a": { "$lte": lastVal }
    }).sort({ "a": -1 }).limit(2).forEach(function(doc) {
        if ( lastVal != doc.a ) {
            lastSeen = [];
        }
        lastVal = doc.a;
        lastSeen.push( doc._id );
        // do something useful with each document matched
    });
    

    これは、_idのすべての値を「除外」することです。 lastSeenに記録されている 結果のリストから、すべての結果がlastValの「以下」(降順)である必要があることを確認します。 ソートフィールド「a」に記録されます。

    これにより、コレクションに次の2つの結果が生成されます。

    { "_id": 3, "a": 3 },
    { "_id": 4, "a": 2 },
    

    しかし、処理後の値は次のようになります:

    lastVal = 2,
    lastSeen = [4];
    

    したがって、他の_idを除外する必要がないというロジックが続きます。 lastValよりも「以下」の「a」の値のみを実際に探しているために以前に表示された値 _idは「1つ」しかなかったので その値で見られる値は、その値のみを除外します。

    もちろん、これにより、上記と同じコードの使用に関する次のページが表示されます。

    { "_id": 5, "a": 1 },
    { "_id": 6, "a": 0 }
    

    これは、一般的に結果を「ページを転送」するための最も効率的な方法であり、「ソートされた」結果の効率的なページングに特に役立ちます。

    ただし、20ページに「ジャンプ」したい場合 または任意の段階で同様のアクションを実行すると、これはあなたのためではありません。従来の.skip()に固執しています および.limit() これを「計算」する他の合理的な方法がないため、「ページ番号」でこれを実行できるようにするアプローチ。

    したがって、それはすべて、アプリケーションが「ページング」をどのように実装しているか、および何を使用できるかに依存します。 .skip() および.limit() このアプローチは「スキップ」のパフォーマンスを低下させるため、ここでのアプローチを使用することで回避できます。

    一方、「ページにジャンプ」したい場合は、結果の「キャッシュ」を作成したい場合を除いて、「スキップ」が唯一の現実的なオプションです。しかし、それはまったく別の問題です。




    1. jedis forJavaを使用してDockerRedisクラスターインスタンスに接続するにはどうすればよいですか?

    2. mongoose.modelでコレクション名を変更するにはどうすればよいですか?

    3. ノードRedisの保護

    4. Redis-メモリ使用量の監視