Вы действительно задаете 2 совершенно разных вопроса:
- Как написать этот запрос агрегации
- Как представить / запустить агрегацию с помощью Spring Boot
Вы, вероятно, найдете гораздо больше людей, способных ответить # 1, чем # 2.Я также хотел бы предложить, чтобы вы подходили к проблеме аналогично, чтобы ваше агрегирование работало сначала в оболочке mongo, а затем кодифицировало конвейер агрегации в ваше приложение.
Поскольку у вас есть 2 вложенных массива, вам необходимо использовать $ unwind , чтобы раскрутить их, чтобы вы могли использовать $ group для подсчета на основе вашей составной группировки id
и respostas
.
Что-то подобное должноwork:
db.foo.aggregate([
{$unwind:"$destinatarios"},
{$unwind:{path:"$destinatarios.respostas", preserveNullAndEmptyArrays:true}},
{$project:{_id:0,id:1,resp:{$ifNull:["$destinatarios.respostas.positiva", "null"]}}},
{$group: {_id:{id:"$id", resp:"$resp"}, count: { $sum: 1 }}},
{$sort:{"_id.id":1}},
{$project:{_id:0,id:"$_id.id",resp:"$_id.resp",count:1}}
])
Я бы посоветовал вам запустить агрегацию, добавляя один этап за раз, чтобы лучше понять, что делает каждый этап.Так будет понятнее.
Что касается второго вопроса о том, как сделать это с помощью Spring Boot (возможно, с использованием Spring Data MongoDB), есть несколько способов, которыми это можно сделать. Spring Data MongoDB docs предоставит подробную информацию и примеры о предоставляемом API-интерфейсе, похожем на свободное владение.
Один "прием", который вы могли бы рассмотреть для сложных агрегаций, - написать агрегациюкак обычный JSON, а затем проанализировать его.Вы даже можете поместить его в файл и прочитать конвейер из файла.Вот основной пример:
String stage1Json = "{$unwind:\"$destinatarios\"}";
Document stage1 = Document.parse(stage1Json);
List<Document> pipeline = new ArrayList<Document>();
pipeline.add(stage1);
AggregateIterable<Document> results = template.getDb().getCollection("foo").aggregate(pipeline);
for (Document result : results) {
System.out.println(result);
}