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

MongoDBによる高速ページング

    データのページングは​​、MongoDBで最も一般的な操作の1つです。典型的なシナリオは、UIに結果をチャンクで表示する必要があることです。データをバッチ処理する場合は、データ処理を拡張できるように、ページング戦略を正しくすることも重要です。

    例を見て、MongoDBのデータをページングするさまざまな方法を見てみましょう。この例では、一度に10人のユーザーをページスルーして表示する必要があるユーザーデータのCRMデータベースがあります。したがって、実際には、ページサイズは10です。ユーザードキュメントの構造は次のとおりです。

    {
        _id,
        name,
        company,
        state
    }
    

    アプローチ1:skip()とlimit()を使用する

    MongoDBは、skip()およびlimit()コマンドを使用したページング操作をネイティブにサポートします。 skip(n)ディレクティブはMongoDBに「n」の結果をスキップするように指示し、limit(n)ディレクティブはMongoDBに結果の長さを「n」の結果に制限するように指示します。通常、カーソルでskip()およびlimit()ディレクティブを使用しますが、シナリオを説明するために、同じ結果を達成するコンソールコマンドを提供します。また、コードを簡潔にするために、制限チェックコードも除外されています:

    //Page 1
    db.users.find().limit (10)
    //Page 2
    db.users.find().skip(10).limit(10)
    //Page 3
    db.users.find().skip(20).limit(10)
    ........
    

    あなたはその考えを理解します。一般に、ページ「n」を取得するためのコードは次のようになります。

    db.users.find().skip(pagesize*(n-1)).limit(pagesize)
    

    ただし、データのサイズが大きくなると、このアプローチには深刻なパフォーマンスの問題が発生します。その理由は、クエリが実行されるたびに完全な結果セットが構築され、サーバーはコレクションの先頭から指定されたオフセットまで移動する必要があるためです。オフセットが大きくなると、このプロセスはどんどん遅くなります。また、このプロセスではインデックスを効率的に使用できません。したがって、通常、「skip()」および「limit()」アプローチは、データセットが小さい場合に役立ちます。データセットが大きい場合は、他のアプローチを検討する必要があります。

    アプローチ2:find()とlimit()を使用する

    前のアプローチがうまくスケーリングしない理由はskip()コマンドであり、このセクションの目標は、「skip()」コマンドを使用せずにページングを実装することです。このために、タイムスタンプやドキュメントに保存されているIDなど、保存されているデータの自然な順序を活用します。この例では、各ドキュメントに保存されている「_id」を使用します。 「_id」は、タイムスタンプ、machined、processid、counterなどを含む12バイトの構造体であるMongoDBObjectID構造体です。全体的な考え方は次のとおりです。

    1.現在のページの最後のドキュメントの_idを取得します
    2。次のページでこの「_id」より大きいドキュメントを取得する

    //Page 1
    db.users.find().limit(pageSize);
    //Find the id of the last document in this page
    last_id = ...
    
    //Page 2
    users = db.users.find({'_id'> last_id}). limit(10);
    //Update the last id with the id of the last document in this page
    last_id = ...
    
    

    このアプローチは、「_id」フィールドに存在する固有の順序を利用します。また、「_ id」フィールドにはデフォルトでインデックスが付けられているため、検索操作のパフォーマンスは非常に良好です。使用しているフィールドがインデックスに登録されていない場合、パフォーマンスが低下するため、フィールドがインデックスに登録されていることを確認することが重要です。

    さらに、ページングのためにデータを特定の順序で並べ替える場合は、上記の手法でsort()句を使用することもできます。最高のパフォーマンスを得るには、並べ替えプロセスでインデックスを活用していることを確認することが重要です。クエリに.explain()サフィックスを使用して、これを判別できます。

    users = db.users.find({'_id'> last_id}). sort(..).limit(10);
    //Update the last id with the id of the last document in this page
    last_id = ...
    
    

    ご不明な点やご意見がございましたら、[email protected]までお気軽にお問い合わせください。


    1. MySQLおよびPostgreSQLの新しいバックアップ管理およびセキュリティ機能:ClusterControlリリース1.6.2

    2. Redisに代わる埋め込み可能なJavaはありますか?

    3. Hiredis Redisライブラリは非同期コールバック用の独自のスレッドを作成しますか?

    4. MongoDBインスタンスまたはレプリカセットのクローン作成