Если вы не хотите изменять структуру данных, нет способа сгруппировать все данные, так как нам нужно определить общую сумму, потраченную каждым пользователем, хотя для этого потребуется всего один $group
этап и один * На этапе 1002 * это будет выглядеть примерно так:
db.collection.aggregate([
{
$group: {
_id: "$customer_id",
total: {$sum: "$amount"},
rootHolder: {$push: "$$ROOT"}
}
},
{
$unwind: "$rootHolder"
},
{
$project: {
newRoot: {
$mergeObjects: [
"$rootHolder",
{total: "$total"}
]
}
}
},
{
$replaceRoot: {
newRoot: "$newRoot"
}
},
{
$project: {
customer_id: 1,
item: 1,
total: "$amount",
per_customer_spend: {$divide: ["$amount", "$total"]}
}
}
])
С учетом сказанного, особенно при увеличении масштаба, этот конвейер становится очень дорогим, теперь в зависимости от того, насколько велик масштаб и количество уникальных пар costumer_id x item
я бы посоветовал следующее:
учитывая Пн go не любит дублирование данных и предполагая, что пользователь не "покупает" новые элементы слишком часто, возможно, стоит сохранить его как поле в текущая коллекция. (что требует обновления всех предметов пользователя при покупке), я знаю, что это звучит «странно» и дорого, но опять же, в зависимости от частоты покупок, это может стоить. вместо этого создаст новую коллекцию с customer_total
и customer_id
. Имейте в виду, что это поле все еще потребует поддержки, хотя и намного дешевле. С помощью этой коллекции вы можете либо $ lookup всего (что опять же может быть дорого).