Możesz spróbować $facet
z $addFields
do równoległej agregacji w 3.4
wersja.
Zmniejszy to ogólną złożoność i możesz jednocześnie uruchamiać grupowanie z własnymi pasującymi danymi wejściowymi.
Poniższy kod dynamicznie buduje potok agregacji w oparciu o obiekt żądania.
// Sample request
var request = {
"name":"RINGGO",
"year": 2017,
"month":3,
"week":12
};
// Build initial match document on name
var match1 = {
name: request["name"]
};
// Build project & facet document for date based aggregation
var addFields = {};
var facet = {};
// Add year followed by year facet
if (request["year"]) {
addFields["year"] = { "$year": "$date" },
facet["Yearly"] =
[
{
"$match":{ "year": request["year"] }
},
{
"$group": {
"_id": {
"name": "$name",
"year": "$year"
},
"spend": { "$push":"$amount" },
"total": { "$sum": "$amount" }
}
}
];
}
// Add month followed by month facet
if (request["month"]) {
addFields["month"] = { "$month": "$date" };
facet["Monthly"] =
[
{
"$match":{ "month": request["month"] }
},
{
"$group": {
"_id": {
"name": "$name",
"month": "$month"
},
"spend": { "$push":"$amount" },
"total": { "$sum": "$amount" }
}
}
];
}
// Add week followed by week facet
if (request["week"]) {
addFields["week"] = { "$week": "$date" };
facet["Weekly"] =
[
{
"$match":{ "week": request["week"] }
},
{
"$group": {
"_id": {
"name": "$name",
"week": "$week"
},
"spend": { "$push":"$amount" },
"total": { "$sum": "$amount" }
}
}
];
}
// Use aggregate builder
statements.aggregate()
.match(match1)
.append({"$addFields": addFields}) // No addFields stage in mongoose builder
.facet(facet)
.exec(function(err, data) {});
Zapytanie powłoki Mongo dla name/year/month/week
kryteria.
db.statements.aggregate({
'$match': {
name: 'RINGGO'
}
}, {
'$addFields': {
year: {
'$year': '$date'
},
month: {
'$month': '$date'
},
week: {
'$week': '$date'
}
}
}, {
'$facet': {
Yearly: [{
'$match': {
year: 2017
}
},
{
'$group': {
_id: {
name: '$name',
year: '$year'
},
spend: {
'$push': '$amount'
},
total: {
'$sum': '$amount'
}
}
}
],
Monthly: [{
'$match': {
month: 3
}
},
{
'$group': {
_id: {
name: '$name',
month: '$month'
},
spend: {
'$push': '$amount'
},
total: {
'$sum': '$amount'
}
}
}
],
Weekly: [{
'$match': {
week: 12
}
},
{
'$group': {
_id: {
name: '$name',
week: '$week'
},
spend: {
'$push': '$amount'
},
total: {
'$sum': '$amount'
}
}
}
]
}
})
Przykładowa odpowiedź
{
"Yearly": [{
"_id": {
"name": "RINGGO",
"year": 2017
},
"spend": [-3.3, -6.3, -3.3, -6.3, -3.3, -3.3],
"total": -25.799999999999997
}],
"Monthly": [{
"_id": {
"name": "RINGGO",
"month": 3
},
"spend": [-3.3, -6.3, -3.3, -6.3, -3.3, -3.3],
"total": -25.799999999999997
}],
"Weekly": [{
"_id": {
"name": "RINGGO",
"week": 12
},
"spend": [-6.3, -3.3],
"total": -9.6
}]
}
Możesz uruchomić podobną agregację dla Year/Month
i Year
wartości wejściowe.
Dzieje się tak w $group
1 gdzie $week
agregacja zwija każdą z dwóch dat [15, 16] kwotę w tygodniu 11, a pozostałe dwie daty [22, 23] kwotę w tygodniu 12 później, aby wyświetlić jako zsumowane sumy w MonthySpends
.