Как применить группу к вложенному документу в MongoDB с помощью MongoTemplate?

db.students.aggregate([
  { $unwind: "$details" },
  {
    $group: {
      _id: {
        sid: "$details.student._id",
        statuscode: "$details.studentStatus.statusCode"
      },
      total: { $sum: 1 }
    }
  }
]);

Запрос работает нормально, и его необходимо преобразовать в шаблон mongo.

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

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

person vishal.saini    schedule 08.01.2020    source источник
comment
Пожалуйста, предоставьте образец документа в формате JSON в сообщении.   -  person prasad_    schedule 08.01.2020
comment
{ _id: 59, сведения: [ {студент: { _id: 5d3145a8523a2e602e5e0200, }, studentStatus: {statusCode: 1}, } ] }   -  person vishal.saini    schedule 08.01.2020


Ответы (1)


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

Обратите внимание, что я добавил этап проект перед группой. Этот проект обязателен; если вложенные поля ("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);
person prasad_    schedule 09.01.2020
comment
Но если мне нужен Aggregation.ROOT (весь объект), проект не позволяет мне получить это - person Achyut; 25.03.2021
comment
В таком случае используйте $addFields вместо $project - оба являются этапами проекции для разных целей. По умолчанию addFields включает все поля. - person prasad_; 25.03.2021