2016-02-20 44 views
1

我有一個集合tickets包含與方案的文檔:MongoDB3.2。聚合,取出處理的文檔

{_id: ObjectID, date: ISODate, cost: Number} 

下面聚集在收集完成:

db.tickets.aggregate([ 
    {$match: {date: {$gte: ISODate("2016-02-01")}}}, 
    {$group:{ _id:"$date", totalCost: {$sum: "$cost"}, totalTickets: {$sum: 1}}} 
], function(err,result) { 
// ... 
} 

我想隨機除去20%的來自聚合的文檔意味着模擬票據收集包含的文檔少於現實的20%的情況。

我該怎麼辦?

+0

您正在使用哪個MongoDB服務器版本?如果是3.2,則可以使用['$ sample'](https://docs.mongodb.org/manual/reference/operator/aggregation/sample/)運算符從其輸入中隨機選擇指定數量的文檔 – chridam

+1

感謝您的快速重播。你可以發佈這個答案。 – rlib

+0

這個解決方案非常好,但是我想從2016-02-10開始的文檔中有80%是在聚合中指定的日期之後。有沒有辦法做到這一點? – rlib

回答

1

要想從2016-02-10開始文檔是在聚集中規定的日期之後,你可以使用一個async包編寫計算從2016-02-10開始的文檔數另一項任務的80%,並使用$sample運營商與此計數。類似以下內容:

var locals = {}, 
    filter = {"date": {"$gte": ISODate("2016-02-01")}}; 
async.series([ 
    // Get count 
    function(callback) { 
     db.collection("tickets").count(filter, function (err, result){ 
      if (err) return callback(err);    
      locals.count = result; //Set the count here 
      callback(); 
     });   
    },  
    // Run aggregation 
    function(callback) { 
     var pipeline = [ 
      {"$match": filter}, 
      {"$sample": {"size": {"$multiply": [locals.count, 0.8]}} 
      {"$group":{ "_id": "$date", "totalCost": {"$sum": "$cost"}, "totalTickets": {"$sum": 1}}} 
     ]; 
     db.collection("tickets").aggregate(pipeline, function(err, result) { 
      if (err) return callback(err); 
      locals.docs = result; 
      callback(); 
     }); 
    } 
], function(err) { //This function gets called after the two tasks have called their "task callbacks" 
    if (err) return next(err); 
    // Here locals will be populated with 'count' and 'docs' 
    res.json({ 
     count: locals.count, 
     data: locals.docs 
    }); 
});