我正在使用 Mongo,我需要聚合以下時間序列,分組account_id并獲取每個嵌套值的總和。為了舉例,我只用pub物件保持資料集簡單,但在我的真實集合中,我還有其他物件和值要聚合
[
{
"account_id": 1,
"pub": {
"cpm": NumberDecimal("1"),
"monthly": NumberDecimal("1.5")
},
"time": ISODate("2022-01-01T01:00:00.000"),
},
{
"account_id": 2,
"pub": {
"cpm": NumberDecimal("3"),
"monthly": NumberDecimal("3.5")
},
"time": ISODate("2022-01-01T01:00:00.000"),
},
{
"account_id": 1,
"pub": {
"cpm": NumberDecimal("2"),
"monthly": NumberDecimal("2.5")
},
"time": ISODate("2022-01-01T02:00:00.000"),
},
{
"account_id": 2,
"pub": {
"cpm": NumberDecimal("4"),
"monthly": NumberDecimal("4.5")
},
"time": ISODate("2022-01-01T02:00:00.000"),
}
]
預期產出
[
{
"_id": 1, // account_id
"pub": {
"cpm": 3,
"monthly": 4
}
},
{
"_id": 2, // account_id
"pub": {
"cpm": 7,
"monthly": 8
}
}
]
我發現以下兩種方法可以按預期作業,但它們對我來說似乎非常冗長,尤其是第一種。考慮到在實際集合中還有許多其他物件和值。
方法一
db.collection.aggregate([
{
$group: {
_id: '$account_id',
pub: {
$accumulator: {
init: function () {
return {
cpm: 0,
monthly: 0,
};
},
accumulate: function (state, cpm, monthly) {
return {
cpm: state.cpm cpm,
monthly: state.monthly monthly,
};
},
accumulateArgs: [
{ $toDouble: '$pub.cpm' },
{ $toDouble: '$pub.monthly' },
],
merge: function (state1, state2) {
return {
cpm: state1.cpm state2.cpm,
monthly: state1.monthly state2.monthly,
};
},
finalize: function (state) {
return {
cpm: state.cpm,
monthly: state.monthly,
};
},
lang: 'js',
},
},
},
}
])
方法二
db.collection.aggregate([
{
"$group": {
"_id": "$account_id",
"pub__cpm": {
$sum: "$pub.cpm"
},
"pub__monthly": {
$sum: "$pub.monthly"
}
}
},
{
$set: {
pub: {
cpm: {
"$toDouble": "$pub__cpm"
},
monthly: {
"$toDouble": "$pub__monthly"
}
},
},
},
{
$unset: [
"pub__cpm",
"pub__monthly"
]
}
)]
它會像這樣
{
"$group": {
"_id": "$account_id",
pub: {
cpm: { $sum: "$pub.cpm" },
monthly: { $sum: "$pub.monthly" },
},
}
}
但它拋出“欄位“$pub”必須是一個累加器物件”,這就是我最終使用第一種方法的原因。
有更好的方法來達到相同的結果嗎?如果不是,哪種方法更快?謝謝
uj5u.com熱心網友回復:
你可以使用$project來格式化你的輸出,而不是像$set這樣$unset使用$project
mongoplayground
db.collection.aggregate([
{
"$group": {
"_id": "$account_id",
"pub__cpm": { $sum: "$pub.cpm" },
"pub__monthly": { $sum: "$pub.monthly" }
}
},
{
"$project": {
"pub": {
"cpm": "$pub__cpm",
"monthly": "$pub__monthly"
}
}
}
])
uj5u.com熱心網友回復:
在小組賽階段之后,您可以將變數 cpm 和每月的累積總和投射到pubusingproject操作中。
db.collection.aggregate([
{
"$group": {
"_id": "$account_id",
cpm: {
$sum: "$pub.cpm"
},
monthly: {
$sum: "$pub.monthly"
},
}
},
{
"$project": {
pub: {
cpm: "$cpm",
monthly: "$monthly"
}
}
}
])
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/433626.html
