Spring 使用mongoDBtemplate创建嵌套文档

Spring 使用mongoDBtemplate创建嵌套文档,spring,mongodb,aggregation-framework,spring-mongodb,Spring,Mongodb,Aggregation Framework,Spring Mongodb,我正在尝试使用SpringMongoDB模板使用Agregation。必须在第三级文档上进行分组。输入文档是 { "_id": "59036b0fa036cc28c8e07db6", "sections": [{ "srcName": "test1", "data": [{ "srcKey": "", "rowIdx": 0, "values": [{

我正在尝试使用SpringMongoDB模板使用Agregation。必须在第三级文档上进行分组。输入文档是

{
    "_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<>();
  }
private MatchOperation getMatchOPeration(String sectionName){
Criteria criteira=标准。其中(“sectionName”)。在(sectionName)中;
返回匹配(criteira);
}
私有组操作getGroupOperaion(){
返回组(“srcDesc”).last(“srcDesc”).as(“srcDesc”);
}
私有ProjectOnOperation GetProjectOnOperation(){
返回项目(“srcDesc”)和(“srcDesc”).previousOperation();
}
公共列表findAllSourceNamesBySection(字符串节名){
List sourceNameList=新建ArrayList();
MatchOperation MatchOperation=getMatchOPeration(sectionName);
GroupOperation GroupOperation=getGroupOperaion();
ProjectOnOperation ProjectOnOperation=GetProjectOnOperation();
聚合结果聚合结果=
mongoTemplate.aggregate(Aggregation.newAggregation(
匹配操作,
展开(“节.数据.值”),
集团经营,,
projectionOperation),StatDocument.class,SectionsDocument.class);
sourceNameList=aggregationResults.getMappedResults();
返回新的ArrayList();
}

您可以将代码更新到以下位置

在展开
节.数据.值之前,添加了
$unwind
以展开
节.数据

使用
$addToSet
运算符更新了
$group
获取不同的
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"
            }
        }
    }
])
删除了
$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");
}

你的mongo服务器和spring mongo版本是什么?@veeram,我使用的是org.springframework.boot-spring-boot-starter数据mongodb 1.5.1.RELEASEorg.springframework.boot-spring-boot-starter数据mongodb 1.5.1.release你的mongo服务器版本是什么?@veeram,谢谢。我今天要试试这个。而且,我对这一切都是陌生的。你有什么好的文档链接,可以帮助我在这些放松概念或addtoSet概念。欢迎你。这里是链接&。如果您使用的是mongo server 3.4版本,则可以改进聚合管道。让我知道你的版本,我可以更新答案。是的。我们的数据库版本是v3.4.3。谢谢你在这方面的帮助,不客气。请尝试测试当前更改,并尝试更新3.4的更改。不幸的是,结果确实为我提供了独特的结果。也许我们错过了什么。下面是我的答案