2014-09-27 76 views
2

我有一個集合的MongoDB用這種文檔的:MongoDB的時間序列操作和代

{ 
"_id" : ObjectId("53cb898bed4bd6c24ae07a9f"), 
"account" : "C1" 
"created_on" : ISODate("2014-10-01T01:23:00.000Z") 
"value" : 253 
} 

{ 
"_id" : ObjectId("52cb898bed4bd6c24ae06a9e"), 
"account" : "C2" 
"created_on" : ISODate("2014-10-01T01:23:00.000Z") 
"value" : 9381 
} 

有每分鐘爲C1和C2的文檔。

我想爲另一個帳戶「C0」生成數據,它將等於:(C2 - C1)* 0.25 所以我們的目標是爲集合中的每個分鐘生成數據。

根據你,是否有可能在mongo shell中做到這一點?

非常感謝你:)

+0

如何生成這兩個文檔(C1,C2)? – Wizard 2014-09-27 06:26:12

+0

我不生成它們,我只是下載了一個完全由層級系統管理的數據庫。 – user3163545 2014-09-27 07:09:36

回答

2

的邏輯來解決這個問題,是如下:

a) group all the records by created_on date. 
b) get the value of both the documents in each group. 
c) calculate the difference the C2 and C1 documents for each group. 
d) In case one of the documents is missing difference 
    would be the value of the existing document. 
d) project a document with value as (difference*.25) in each group. 
e) insert the projected document to the collection. 

我想提出兩個解決辦法,第一個是你的假設,

C1和C2每隔一分鐘就有一個文件。

所以for every created_on時間,會有only two文件,C1C2

db.time.aggregate([ { 
    $match : { 
     "account" : { 
      $in : [ "C1", "C2" ] 
     } 
    } 
}, { 
    $group : { 
     "_id" : "$created_on", 
     "first" : { 
      $first : "$value" 
     }, 
     "second" : { 
      $last : "$value" 
     }, 
     "count" : { 
      $sum : 1 
     } 
    } 
}, { 
    $project : { 
     "_id" : 0, 
     "value" : { 
      $multiply : [ { 
       $cond : [ { 
        $lte : [ "$count", 1 ] 
       }, "$first", { 
        $subtract : [ "$first", "$second" ] 
       } ] 
      }, 0.25 ] 
     }, 
     "created_on" : "$_id", 
     "account" : { 
      $literal : "C0" 
     } 
    } 
} ]).forEach(function(doc) { 
    doc.value = Math.abs(doc.value); 
    db.time.insert(doc); 
}); 

第二種解決方案基於實時場景。對於特定的created_on時間,可以有'n'個C1文件和'm'個數C2個文件具有不同的值,但我們只需要one'C0'文件代表差異,即爲該特定created_on時間。您需要額外的$group流水線操作員,如下所示:

db.time.aggregate([ { 
    $match : { 
     "account" : { 
      $in : [ "C1", "C2" ] 
     } 
    } 
}, { 
    $group : { 
     "_id" : { 
      "created_on" : "$created_on", 
      "account" : "$account" 
     }, 
     "created_on" : { 
      $first : "$created_on" 
     }, 
     "values" : { 
      $sum : "$value" 
     } 
    } 
}, { 
    $group : { 
     "_id" : "$created_on", 
     "first" : { 
      $first : "$values" 
     }, 
     "second" : { 
      $last : "$values" 
     }, 
     "count" : { 
      $sum : 1 
     } 
    } 
}, { 
    $project : { 
     "_id" : 0, 
     "value" : { 
      $multiply : [ { 
       $cond : [ { 
        $lte : [ "$count", 1 ] 
       }, "$first", { 
        $subtract : [ "$first", "$second" ] 
       } ] 
      }, 0.25 ] 
     }, 
     "created_on" : "$_id", 
     "account" : { 
      $literal : "C0" 
     } 
    } 
} ]).forEach(function(doc) { 
    doc.value = Math.abs(doc.value); 
    db.time.insert(doc); 
});