0

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

{
    "_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<>();
  }
4

1 回答 1

0

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

添加$unwind到 unwind sections& sections.databefore unwinding sections.data.values

更新与运营商$group不同 。srcDesc$addToSet

移除了$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用输入过滤sections元素,srcName然后映射以转换输出。$reduce将使用 map 阶段内 filter 阶段的输出在 each中的所有内容中提取和合并($concatArrays部分)。srcDescvaluesdata

$unwind + $groupsrcDesc$addToSet运营商区别开 来。

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"
            }
        }
    }
])
于 2017-05-08T01:48:35.123 回答