MongoTemplate 按嵌套列表中的字段搜索

MongoTemplate search by a field in a nested list

我有 listMainItem 个对象,如下所示

[
   {
      "_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 名称进行搜索。因此,如果像 "cat Th" 这样搜索,我的结果应该如下所示(应该 return 列表 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<>())

我没有在列表中获取匹配的子项,而是获取了所有不同的子项,我在这里做错了什么?

(相同的 SubItem 可以在不同的 MainItem 列表中,在这些情况下应该有不同的 SubItems 匹配名称)

在对聚合框架进行一些研究并在 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();