Я был немного озадачен в отношении List1 / List2, однако я думаю, что это даст вам большую часть пути к вашему необходимому запросу агрегации.
db.test.aggregate([
{
$match: {
"List1": "X",
"Answers.SelectedList": "1"
}
},
{
"$unwind" : "$rating"
},
{
$group:{
_id: {
id: "$rating.ObjectId",
list: "$rating.List"
},
maxRatedDate: { $max: "$rating.RatedDate" },
ratings: { $push: "$rating" }
}
},{
$addFields: {
ratings: {
$filter: {
input: "$ratings",
as: "item",
cond: { $eq: [ "$$item.RatedDate", "$maxRatedDate" ] }
}
}
}
},
{
$unwind: "$ratings"
},
{
$group:{
_id: "$ratings.List",
sum : {
$sum : "$ratings.Rate"
}
}
}
])
Это выведет следующее
{ "_id" : "List 1", "sum" : 8 }
{ "_id" : "List 2", "sum" : 10 }
Однако давайте попробуем разбить его.
Для начала у нас есть простое совпадение, такое же, как у вас в вашем вопросе. это просто ограничивает количество документов, которые мы передаем обратно
$match: {
"List1": "X",
"Answers.SelectedList": "1"
}
Затем мы раскручиваем все элементы массива, чтобы получить документ для каждого рейтинга, это позволяет нам делать некоторые дополнительные запросы к данным.
{
"$unwind" : "$rating"
}
Далее, у нас есть группа, здесь мы группа по ObjectId рейтинга, поэтому мы можем позже удалить дубликаты, мы также узнаем в группе, какой рейтинг у нас есть группа имеет самую высокую дату, поэтому мы можем принять ее позже в прогнозе. затем мы отодвигаем все оценки обратно в массиве на потом.
$group:{
_id: {
id: "$rating.ObjectId",
list: "$rating.List"
},
maxRatedDate: { $max: "$rating.RatedDate" },
ratings: { $push: "$rating" }
}
Далее мы хотим спроецировать массив оценок на один элемент, в котором он содержит только самый последний рейтинг, для этого мы используем $ filter в массиве и отфильтровываем их все, которые не соответствуют нашей максимальной дате, которую мы вычислили на предыдущем шаге.
$addFields: {
ratings: {
$filter: {
input: "$ratings",
as: "item",
cond: { $eq: [ "$$item.RatedDate", "$maxRatedDate" ] }
}
}
}
Следующие два шага довольно просты и просто снова разматывают массив ( у нас есть только один элемент, затем группируем их, чтобы получить общую сумму для списков.
{
$unwind: "$ratings"
},
{
$group:{
_id: "$ratings.List",
sum : {
$sum : "$ratings.Rate"
}
}
}