使用 mongotemplate 聚合嵌套文档

Agrregation using mongoDBtemplate for Nested document

我正在尝试使用 spring mongodb 模板进行聚合。必须在文档的第三级进行分组。输入文档是

{
    "_id": "59036b0fa036cc28c8e07db6",
    "sections": [{
        "srcName": "test1",
        "data": [{
                "srcKey": "",
                "rowIdx": 0,
                "values": [{
                        "srcDesc": "Assets"
                    },
                    {
                        "srcDesc": "NonAssets"
                    },
                    {
                        "srcDesc": "liabilities"
                    }
                ]
            },
            {
                "srcKey": "01",
                "rowIdx": 1,
                "values": [{
                    "srcDesc": "NonAssets"
                }]
            }
        ]
    }]
}

基本上我想运行查询

select distinct(srcdesc) from document where srcName="test1"; 

请注意 srcDesc 是第三层嵌套。我正在尝试下面的 java 代码

  private MatchOperation getMatchOPeration(String sectionName){
      Criteria criteira=Criteria.where("sectionName").in(sectionName);
      return match(criteira);
  }

  private GroupOperation getGroupOperaion(){
      return  group("srcDesc").last("srcDesc").as("srcDesc"); 
  }

 private ProjectionOperation  getProjectionOPeration(){
      return project("srcDesc").and("srcDesc").previousOperation();
  }

 public List<SourceName> findAllSourceNamesBySection(String sectionName){
       List<SectionsDocument> sourceNameList=new ArrayList<>();
       MatchOperation matchOPeration=getMatchOPeration(sectionName);
       GroupOperation groupOperation=getGroupOperaion();
       ProjectionOperation projectionOperation=getProjectionOPeration();
       AggregationResults<SectionsDocument> aggregationResults=
       mongoTemplate.aggregate(Aggregation.newAggregation(
            matchOPeration,
            unwind("sections.data.values"),
            groupOperation,
            projectionOperation),StatDocument.class,SectionsDocument.class);
            sourceNameList=aggregationResults.getMappedResults();   
       return new ArrayList<>();
  }

您可以将您的代码更新到下面。

添加 $unwind 以在展开 sectionssections.data 之前展开 sections.data.values

已更新 $group 使用 $addToSet 运算符得到不同的 srcDesc

删除了 $project 阶段。

private  MatchOperation getMatchOperation(String sectionName){
    Criteria criteira=Criteria.where("sections.srcName").in(sectionName);
    return match(criteira);
}

private  GroupOperation getGroupOperaion(){
    return  group().addToSet("sections.data.values.srcDesc").as("srcDescs");
}

public List<String> findAllSrcDescBySection(String sectionName){
    MatchOperation matchOperation=getMatchOperation(sectionName);
    GroupOperation groupOperation=getGroupOperaion();
    BasicDBObject aggregationResults=
               mongoTemplate.aggregate(Aggregation.newAggregation(
                       matchOperation,
                       unwind("sections"),
                       unwind("sections.data"),
                       unwind("sections.data.values"),
                       matchOperation,
                       groupOperation), collectionname, BasicDBObject.class).getUniqueMappedResult();
   return (ArrayList)aggregationResults.get("srcDescs");
}

更新 3.4 版本:

这与上面类似,但不是 $unwind'ing,我们从每个文档中 $reduce'ing$project srcDescs

$map + $filter 用输入 srcName 过滤 sections 元素,然后用 map 转换输出。 $reduce 将使用映射阶段内过滤阶段的输出来提取和合并($concatArrays 部分)srcDesc 在每个 data 中的所有 values

$unwind + $group 使用 $addToSet 运算符获得不同的 srcDesc

aggregate([{
        $project: {
            srcDescs: {
                $arrayElemAt: [{
                    $map: {
                        input: {
                            $filter: {
                                input: "$sections",
                                as: "sectionsf",
                                cond: {
                                    $eq: ["$$sectionsf.srcName", "test1"]
                                }
                            }
                        },
                        as: "sectionsm",
                        in: {
                            $reduce: {
                                input: "$$sectionsm.data",
                                initialValue: [],
                                in: {
                                    $concatArrays: ["$$value", "$$this.values.srcDesc"]
                                }
                            }
                        }
                    }
                }, 0]
            }
        }
    },
    {
        $unwind: "$srcDescs"
    },
    {
        $group: {
            _id: null,
            srcDescs: {
                $addToSet: "$srcDescs"
            }
        }
    }
])