可以在查詢彙總中獲得月份,季度和半月的銷售總額,或者我分別執行每個查詢?有可能獲得月份,季度和學期mongodb的查詢銷售額?
無論模型,我的問題是您是否可以在單個查詢中獲得所有信息,還是應該單獨執行。
如果不是,那麼獲取這些信息的最佳方法是什麼?
可以在查詢彙總中獲得月份,季度和半月的銷售總額,或者我分別執行每個查詢?有可能獲得月份,季度和學期mongodb的查詢銷售額?
無論模型,我的問題是您是否可以在單個查詢中獲得所有信息,還是應該單獨執行。
如果不是,那麼獲取這些信息的最佳方法是什麼?
您可以使用aggregation framework做到這一點,如果map-reduce能夠解決您手頭的問題,那麼它是首選,因爲它通常都是可讀的,速度更快。
當然,如何這條管道的樣子取決於你的文檔的形狀(我還不知道),但計算一次所有三個總和應儘可能用$match階段過濾下來的文件和$group階段做總和計算。
在$group
階段中,您可以使用$sum運算符與嵌套$cond運算符有條件地總結月份,季度和半年的值。
假設你有一個銷售收取的是單據,
{ "_id": ObjectId("579d91a4e474b2af2f1ddc65"), "date": ISODate("2015-06-29T22:00:00Z"), "quantity": 1, "price": 30 }
{ "_id": ObjectId("579d9193e474b2af2f1ddc66"), "date": ISODate("2015-07-28T22:00:00Z"), "quantity": 3, "price": 20 }
{ "_id": ObjectId("579d91a4e474b2af2f1ddc67"), "date": ISODate("2015-08-29T22:00:00Z"), "quantity": 2, "price": 10 }
{ "_id": ObjectId("579d91a4e474b2af2f1ddc68"), "date": ISODate("2015-09-29T22:00:00Z"), "quantity": 4, "price": 15 }
{ "_id": ObjectId("579d919ee474b2af2f1ddc69"), "date": ISODate("2015-11-28T22:00:00Z"), "quantity": 2, "price": 20 }
配圖,減少解決方案將
var mapFunc = function() {
date = this.date;
if (new ISODate("2015-06-01T00:00:00Z") <= date && date <= new ISODate("2016-01-01T00:00:00Z")) {
var totalPrice = this.quantity * this.price;
if (new ISODate("2015-11-01T00:00:00Z") <= date) emit ("lastMonth", totalPrice);
if (new ISODate("2015-09-01T00:00:00Z") <= date) emit ("lastQuarter", totalPrice);
emit("lastSemester", totalPrice);
}
}
var reduceFunc = function(key, values) {
return Array.sum(values);
}
db.sales.mapReduce(mapFunc, reduceFunc, { out: { inline : 1 } });
的結果是
"results" : [ { "_id" : "lastSemester", "value" : 210 },
{ "_id" : "lastMonth", "value" : 40 },
{ "_id" : "lastQuarter", "value" : 100 } ]
雖然,我不知道(並希望)知道如何通過聚合來實現此特定集合。
唯一事情,進入初衷是希望通過$group
月
db.corders.aggregate(
{ $match: { $and: [ { date: { $gte: new ISODate("2015-06-01T00:00:00Z") } }, { date : { $lte: new ISODate("2016-01-01T00:00:00Z") } } ] } },
{ $group: { "_id": { "$month": "$date" }, totalPrice: { $sum: { $multiply: [ "$price", "$quantity" ] } } } });
這給結果
{ "_id" : 11, "totalPrice" : 40 }
{ "_id" : 9, "totalPrice" : 60 }
{ "_id" : 8, "totalPrice" : 20 }
{ "_id" : 7, "totalPrice" : 60 }
{ "_id" : 6, "totalPrice" : 30 }
應進一步根據任務本地處理。
根據文檔字段的具體情況,可以通過彙總框架,使用match
,project
和group
階段的組合完成此操作。
舉個例子,我將承擔Sales
文件,以date
場和amount
領域,應當彙總以獲取一定時期內月份,季度和半總銷量(相應日期變量條件也需要事先定義,例如從包含在服務器GET請求中的查詢參數)
Sales.aggregate()
.match(...include general non-date matches here, e.g. company, etc.)
.project({
'month': {
'$cond': { if: {
'$and': [
{ $gte: [ 'date', new Date(monthStartDate) ] },
{ $lte: [ 'date', new Date(monthEndDate) ] },
]}, then: 'amount', else: 0
}
},
'quarter': {
'$cond': { if: {
'$and': [
{ $gte: [ 'date', new Date(quarterStartDate) ] },
{ $lte: [ 'date', new Date(quarterEndDate) ] },
]}, then: 'amount', else: 0
}
},
'half': {
'$cond': { if: {
'$and': [
{ $gte: [ 'date', new Date(halfStartDate) ] },
{ $lte: [ 'date', new Date(halfEndDate) ] },
]}, then: 'amount', else: 0
}
}
})
.group({
_id: '_id',
month: { $sum: '$month' },
quarter: { $sum: '$quarter' },
half: { $sum: '$half' }
})
.exec(function(err, res) {
if (err) { reject(err) }
resolve(res)
})
謝謝,這已澄清了疑問。 –
感謝您提供聚合框架解決方案。 – tarashypka