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

MongoDBを集約して更新します

    特に大規模なコレクションを処理する場合のパフォーマンスを向上させるには、 を使用してください。 Bulk() バッチでサーバーに操作を送信するための一括更新用のAPI(たとえば、バッチサイズ1000)。これにより、サーバーにすべてのリクエストを送信するわけではないため、パフォーマンスが大幅に向上します(現在のように) forEach() ループ)が、1000リクエストごとに1回だけであるため、更新が現在よりも効率的かつ迅速になります。

    次の例はこのアプローチを示しています。最初の例では、 Bulk() MongoDBバージョン>= 2.6 and < 3.2で利用可能なAPI 。 clients内のすべてのドキュメントを更新します nb_orders_1yearを変更してコレクションを作成する 集計結果の値を持つフィールド。

    aggregate() メソッドは、 cursorを返します。 集計出力コレクションの forEach() それを繰り返して各ドキュメントにアクセスし、一括更新操作をバッチで設定して、APIを使用してサーバー全体に効率的に送信する方法:

    var bulk = db.clients.initializeUnorderedBulkOp(),
        pipeline = [
            {
                "$match": { "date_order": { "$gt": v_date1year } }
            },
            {
                "$group": {
                    "_id": "$id_client", 
                    "count": { "$sum" : 1 }
                }
            },
            { "$out": "tmp_indicators" }        
        ],
        counter = 0;
    
    db.orders.aggregate(pipeline);  
    db.tmp_indicators.find().forEach(function (doc) {       
        bulk.find({ "_id": doc._id }).updateOne({ 
            "$set": { "nb_orders_1year": doc.count }
        });
    
        counter++;
        if (counter % 1000 == 0) {
            bulk.execute(); // Execute per 1000 operations and re-initialize every 1000 update statements
            bulk = db.clients.initializeUnorderedBulkOp();
        }
    });
    // Clean up remaining operations in queue
    if (counter % 1000 != 0) { bulk.execute(); }
    

    次の例は、新しいMongoDBバージョン3.2に適用されます は、バルクを廃止しました。 API bulkWrite()

    上記と同じカーソルを使用しますが、結果を繰り返す代わりに、 map() 方法:

     var pipeline = [
            {
                "$match": { "date_order": { "$gt": v_date1year } }
            },
            {
                "$group": {
                    "_id": "$id_client", 
                    "count": { "$sum" : 1 }
                }
            },
            { "$out": "tmp_indicators" }        
        ];
    db.orders.aggregate(pipeline);
    var bulkOps = db.tmp_indicators.find().map(function (doc) { 
            return { 
                "updateOne": { 
                    "filter": { "_id": doc._id } ,              
                    "update": { "$set": { "nb_orders_1year": doc.count } } 
                }         
            };
        });
    
    db.clients.bulkWrite(bulkOps, { "ordered": true });
    



    1. aws-elasticacheでmemcachedまたはRedisを使用する

    2. MongoDBにドキュメントを埋め込むタイミング

    3. Logstashを使用してmongoDBからelasticsearchにデータを同期する

    4. MongoDBObjectがrrdforeachループの内部に追加されていないcasbahscalaapache spark