使用 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
以在展开 sections
和 sections.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"
}
}
}
])
我正在尝试使用 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
以在展开 sections
和 sections.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"
}
}
}
])