Как применить группирование по нескольким вложенным документам в MongoDB с использованием MongoTemplate - PullRequest
1 голос
/ 08 января 2020
db.students.aggregate([
  { $unwind: "$details" },
  {
    $group: {
      _id: {
        sid: "$details.student._id",
        statuscode: "$details.studentStatus.statusCode"
      },
      total: { $sum: 1 }
    }
  }
]);

Запрос работает нормально и его необходимо преобразовать в mon go template .

Образец документа:

{
        "_id" : 59,
        "details" : [
                {
                        "student" : {
                                "_id" : "5d3145a8523a2e602e5e0200"
                        },
                        "studentStatus" : {
                                "statusCode" : 1
                        }
                }
        ]
}

1 Ответ

0 голосов
/ 09 января 2020

Код Spring Data MongoTemplate для данного агрегата выглядит следующим образом.

Обратите внимание, что я добавил этап project перед группой . Этот проект обязателен; если вложенные поля ("details.student._id" и "details.studentStatus.statusCode") используются непосредственно в рамках этапа group , возникают ошибки "FieldPath field names may not contain '.'.", которые не могут быть разрешены (и это только происходит когда вы используете более одного поля в группировке).

Результат такой же, как и у предоставленной вами агрегации. Я использовал последние версии драйверов Spring и MongoDB с Java 8.

MongoOperations mongoOps = new MongoTemplate(MongoClients.create(), "spr_test");

Aggregation agg = newAggregation(
                                unwind("details"),    
                                project("_id")
                                    .and("details.student._id").as("sid")
                                    .and("details.studentStatus.statusCode").as("statuscode"),
                                group("sid", "statuscode")
                                    .count().as("total")
);

AggregationResults<Document> aggResults = mongoOps.aggregate(agg, "students", Document.class);
aggResults.forEach(System.out::println);
...