Поиск MongoTemplate по полю во вложенном списке

У меня есть list из MainItem объектов, как показано ниже

[
   {
      "_id":"5ee40defc4b47b54a223120f",
      "name":"Item 1",
      "subItems":[
         {
            "_id":"111",
            "name":"cat One name",
            "description":"cat item description"
         },
         {
            "_id":"222",
            "name":"cat Two name",
            "description":"cat item description"
         }
      ]
   },
   {
      "_id":"5ee40defc4b47b54a223120f",
      "name":"Item 1",
      "subItems":[
         {
            "_id":"333",
            "name":"cat Three name",
            "description":"cat item description"
         },
         {
            "_id":"222",
            "name":"cat Two name",
            "description":"cat item description"
         }
      ]
   },
   {
      "_id":"5ee40defc4b47b54a223120f",
      "name":"Item 1",
      "subItems":[
         {
            "_id":"333",
            "name":"cat Three name",
            "description":"cat item description"
         },
         {
            "_id":"111",
            "name":"cat One name",
            "description":"cat item description"
         }
      ]
   }
]

То, что я пытаюсь сделать, это поиск по имени subItem. Итак, если выполнить поиск типа «кошка Th», мой результат должен быть таким, как показано ниже (должен возвращать список из SubItem списков, соответствующих имени),

[
    {
        "_id":"333",
        "name":"cat Three name",
        "description":"cat item description"
    }
]

Мне нужно сделать это с помощью mongoTemplate, и это тот, который я использую для получения результата,

mongoTemplate.getCollection(mongoTemplate.getCollectionName(MainItem.class)).distinct("subItems", new BasicDBObject("subItems.name", new BasicDBObject("$regex", "^cat Th")), BasicBSONObject.class).into(new ArrayList<>())

Вместо того, чтобы получить соответствующий подэлемент в списке, я получаю все отдельные подэлементы. Что я здесь делаю неправильно?

(Один и тот же подэлемент может находиться в разных списках основных элементов, в этих сценариях должны быть разные подэлементы с соответствующим именем)


person Sandeepa    schedule 13.06.2020    source источник
comment
Отвечает ли это на ваш вопрос? Как запрашивать поля массива объектов в монгодб?   -  person Buzz Moschetti    schedule 13.06.2020
comment
@BuzzMoschetti Я не знаком с агрегатом. Можем ли мы добиться чего-то подобного, используя mongotemplate?   -  person Sandeepa    schedule 13.06.2020
comment
Также согласно этому примеру я хочу получить список объектов ответа, а не родительские объекты со списком. А также в моем случае. Один и тот же SubItem может быть в двух разных MainItem. Таким образом, в подобных сценариях в списке должны быть только отдельные подэлементы.   -  person Sandeepa    schedule 13.06.2020
comment
Вы можете получить желаемые результаты, используя метод MongoTemplate#aggregate. Агрегация будет иметь $project для фильтрации ($filter оператора массива агрегации) массива subItems и $group для получения отдельных значений. Это ссылка на документацию для данных Spring. Платформа агрегации MongoDB.   -  person prasad_    schedule 13.06.2020
comment
@prasad_ Если это достойный ответ, скопируйте и вставьте его в раздел ответов ниже.   -  person Buzz Moschetti    schedule 14.06.2020


Ответы (1)


Проведя некоторые исследования в области агрегации и используя метод агрегации в MongoTemplate, я придумал это решение, чтобы решить мою проблему.

final UnwindOperation unwind = unwind("subItems");
final GroupOperation group = Aggregation.group("subItems");
final ReplaceRootOperation replaceRoot = replaceRoot("_id");
final MatchOperation matchName = match(Criteria.where("name").regex("^" + name, "i"));
final Aggregation aggregation = newAggregation(unwind, group, replaceRoot, matchName);

mongoTemplate
  .aggregate(aggregation, mongoTemplate.getCollectionName(MenuItem.class), SubItem.class)
  .getMappedResults();
person Sandeepa    schedule 13.06.2020