2017-03-17 65 views
0

我困在mongo查詢。我有一個mongo收集結構,目前我無法修改,因爲它是非常大的數據。Mongo Groupby基於「密鑰」不值的聚合

我需要從集合中執行一些結果,所以試着用各種方法來獲得它。

下面是我收集的JSON模式: -

{ 
    "date": "2017-01-01T00:00:00.000Z", 
    "bob":"P", 
    "jacob":"P", 
    "wilson":"A", 
    "dev":"SL" 
}, 
{ 
    "date": "2017-01-02T00:00:00.000Z", 
    "bob":"P", 
    "jacob":"A", 
    "wilson":"A", 
    "dev":"SL" 
}, 
{ 
    "date": "2017-01-03T00:00:00.000Z", 
    "bob":"P", 
    "jacob":"P", 
    "wilson":"A", 
    "dev":"SL" 
}, 
{ 
    "date": "2017-01-04T00:00:00.000Z", 
    "shashikant":"P", 
    "jacob":"P", 
    "wilson":"SL", 
    "dev":"SL" 
} 
.... 

作爲輸出我要尋找以下類型的結構: -

from 1st jan 2017 to 30th jan 2017 

    bob  P  17 
    bob  A  2 
    wilson P  10 
    dev  SL. 1 
    ..... 

我使用環回我的後端,但我仍然可以使用正常的mongodb查詢來獲得輸出。

請幫忙

回答

1

MongoDB只允許$退出陣列。但是你可以用一個簡單的mapReduce達到你想要的東西:

//Define the time frame here 
 
var from = new Date('2015-01-01T00:00:00.000Z'); 
 
var to = new Date('2025-01-01T00:00:00.000Z'); 
 

 
db.getCollection('test').mapReduce(function() { 
 
\t \t var keys = Object.keys(this); 
 

 
\t \t //If there is no date found on a record, simply skip 
 
\t \t if (!this.date) { 
 
\t \t \t return; 
 
\t \t } 
 

 
\t \t var date = new Date(this.date); 
 

 
\t \t //Skip the records that do not fit into [form; to] interval 
 
\t \t if (!(date >= from && date <= to)) { 
 
\t \t \t return; 
 
\t \t } 
 

 
\t \t for (var i = 0; i < keys.length; i++) { 
 
\t \t \t var key = keys[i]; 
 

 
\t \t \t //Emit each combination of key and value 
 
\t \t \t if (key !== 'date' && key !== '_id') { 
 
\t \t \t \t emit({key: key, value: this[key]}, {count: 1}); 
 
\t \t \t } 
 
\t \t } 
 
\t }, 
 

 
\t function (key, values) { 
 
\t \t var reduced = {count: 0}; 
 

 
\t \t for (var i = 0; i < values.length; i++) { 
 
\t \t \t var value = values[i]; 
 

 
\t \t \t //Simply counting the combinations here 
 
\t \t \t reduced.count += value.count; 
 
\t \t } 
 

 
\t \t return reduced; 
 
\t }, 
 
\t { 
 
\t \t //Passing the dates to mongo 
 
\t \t //so 'from' and 'to' will be avail in map, reduce and finalize 
 
\t \t scope: {from: from, to: to}, 
 
\t \t finalize: function (key, reducedValue) { 
 
\t \t \t //Changing the data structure just for a convenience 
 
\t \t \t return { 
 
\t \t \t \t propertyName: key.key, 
 
\t \t \t \t propertyValue: key.value, 
 
\t \t \t \t from: from, 
 
\t \t \t \t to: to, 
 
\t \t \t \t count: reducedValue.count 
 
\t \t \t }; 
 
\t \t }, 
 
\t \t out: {inline: 1} 
 
\t } 
 
);

我在蒙戈控制檯測試這一點,但地圖 - 減少也被蒙戈本地的Node.js和貓鼬所支持好。