[英]How to create a query in Mongoose/Mongodb to obtain this json?
我試圖從我的mongodb獲取這樣的對象,每月計算一次操作系統:
{January: {Android: 30, iOS: 10, winPhone: 5}, February: {Android: 4, iOS: 40}, etc}.
這是我的貓鼬模式:
var MySchema = new Schema({
date: {type: Date, default: Date.now},
os: String
});
能給我一個想法嗎? 有沒有一種方法可以創建一個查詢以返回整個對象,還是應該將多個查詢統一地逐個構建?
謝謝!
由於您希望將值投影為輸出中的鍵 ,因此無法使用聚合管道來實現此目的。 沒有任何管道運算符接受值作為鍵。 您需要編寫map reduce函數。 map
功能根據年份對記錄進行分組。 因此, year
被emitted
的關鍵。 該值是每個os
名稱和銷售的“月份”。
map
功能:
var map = function(){
emit(this.date.getFullYear(),
{"month":this.date.getMonth(),"os":this.os});
}
現在,每個組的reduce
函數匯總該年一個月內售出的不同types
os
的count
。
var reduce = function(id,osArr){
var result = {};
var osCount = {};
var monthNames = [ "January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December" ];
for(var i=0;i<osArr.length;i++)
{
var mon = monthNames[(osArr[i].month)-1];
if(!osCount.hasOwnProperty(mon))
{
osCount[mon] = {};
}
if(osCount[mon].hasOwnProperty(osArr[i].os))
{
osCount[mon][osArr[i].os]++;
}
else
{
osCount[mon][osArr[i].os] = 1;
}
}
result[id] = osCount;
return result;
}
在集合上調用map reduce函數,並將其轉儲到名為“ temp”的新集合中。
var o = {};
o.map = map;
o.reduce = reduce;
o.out = { replace: 'temp' }
o.verbose = true;
ModelName.mapReduce(o, function (err, results) {
console.log(results)
})
這將產生以下示例結果:
> db.temp.find({},{"value":1,"_id":0})
{ "value" : { "2013" : { "November" : { "Android" : 2, "ios" : 2, "blackberry" :
1 } } } }
{ "value" : { "2014" : { "October" : { "Android" : 3, "ios" : 2 } } } }
您可能最好使用對MongoDB更自然的輸出結構,其中鍵是靜態的,並且值包含數據。 然后,您可以使用聚合管道來執行以下操作:
MyModel.aggregate([
// Group the docs by month & os
{$group: {_id: {month: {$month: '$date'}, os: '$os'}, count: {$sum: 1}}},
// Group again by just month
{$group: {_id: '$_id.month', counts: {$push: {os: '$_id.os', count: '$count'}}}},
// Rename _id to month
{$project: {month: '$_id', counts: 1, _id: 0}}
], callback);
生成如下輸出:
{
"result" : [
{
"counts" : [
{
"os" : "winPhone",
"count" : 2
},
{
"os" : "iOS",
"count" : 1
},
{
"os" : "Android",
"count" : 2
}
],
"month" : 1
},
{
"counts" : [
{
"os" : "iOS",
"count" : 2
},
{
"os" : "Android",
"count" : 1
}
],
"month" : 2
}
],
"ok" : 1
}
如果您確實想要原始格式,則可以對結果進行后處理,以根據需要調整形狀。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.