我正在使用AngularJS前端和Java后端进行JHipster项目。我在MongoDB数据库中使用Spring Data。
我对名为budgetCode
的字符串字段进行了分组操作。因此,对于每个budgetCode
,都有一个链接的taskCodes
列表,该列表是另一个String字段。我在另一个Stackoverflow帖子中成功做到了这一点:“对字段进行分组操作并将喜欢的字段的列表放入数组中”
在这里,方法aggregateAllTaskCode进行分组操作:
储存库层
public class ClarityResourceAffectationRepositoryImpl implements ClarityResourceAffectationRepositoryCustom {
@Autowired
MongoTemplate mongoTemplate;
@Override
public List<ClarityResourceAffectationReport> aggregateAllTaskCode() {
AggregationOperation project = new AggregationOperation() {
@Override
public DBObject toDBObject(AggregationOperationContext aggregationOperationContext) {
return new BasicDBObject("$project", new BasicDBObject("budget_code", "$budget_code").append("task_code", Arrays.asList("$task_code")));
}
};
Aggregation aggregation = newAggregation(project,
group("budgetCode").addToSet("budgetCode").as("budgetCode").addToSet("taskCode").as("taskCode"),
sort(Sort.Direction.ASC, previousOperation(),"budgetCode"));
AggregationResults groupResults = mongoTemplate.aggregate(aggregation, ClarityResourceAffectation.class,
ClarityResourceAffectationReport.class);
List<ClarityResourceAffectationReport> clarityResourceAffectationReports = groupResults.getMappedResults();
return clarityResourceAffectationReports;
}
}
服务层
public class ClarityResourceAffectationServiceImpl implements ClarityResourceAffectationService{
@Override
public List<ClarityResourceAffectationReport> aggregateAllTaskCodes() {
log.debug("Request to aggregateAllTaskCodes: {}");
List<ClarityResourceAffectationReport> result = clarityResourceAffectationRepository
.aggregateAllTaskCodes();
return result;
}
}
REST API层
public class ClarityResourceAffectationResource {
@GetMapping("/clarity-resource-affectations/list-task-codes")
@Timed
public ResponseEntity<List<ClarityResourceAffectationReport>> aggregateTabAllTaskCodes() {
log.debug("REST request to get aggregateTabAllTaskCodes : {}");
List<ClarityResourceAffectationReport> result = clarityResourceAffectationService.aggregateAllTaskCodes();
return new ResponseEntity<>(result, HttpStatus.OK);
}
}
在这里,ClarityResourceAffectation和ClarityResourceAffectationReport文件:
清晰度资源影响
@Document(collection = "clarity_resource_affectation")
public class ClarityResourceAffectation implements Serializable {
@Id
private String id;
@Field("budget_code")
private String budgetCode;
@Field("task_code")
private String taskCode;
@Field("action_code")
private String actionCode;
public String getBudgetCode() {
return budgetCode;
}
public void setBudgetCode(String budgetCode) {
this.budgetCode = budgetCode;
}
public String getTaskCode() {
return taskCode;
}
public void setTaskCode(String taskCode) {
this.taskCode = taskCode;
}
public String getActionCode() {
return actionCode;
}
public void setActionCode(String actionCode) {
this.actionCode = actionCode;
}
}
ClarityResourceAffectationReport
public class ClarityResourceAffectationReport implements Serializable {
private static final long serialVersionUID = 1L;
private String[] budgetCodes;
private String[][] taskCodes;
private String[][][] actionCodes;
public String[] getBudgetCodes() {
return budgetCodes;
}
public void setBudgetCodes(String[] budgetCodes) {
this.budgetCodes = budgetCodes;
}
public String[][] getTaskCodes() {
return taskCodes;
}
public void setTaskCodes(String[][] taskCodes) {
this.taskCodes = taskCodes;
}
public String[][][] getActionCodes() {
return actionCodes;
}
public void setActionCodes(String[][][] actionCodes) {
this.actionCodes = actionCodes;
}
}
我在数据库中拥有的样本示例
/* 0 */
{
"_class": "fr.bpce.kpi.clarity.domain.ClarityResourceAffectation",
"budget_code": "P24DCDSA01",
"task_code": "61427",
"action_code": "354"
}
/* 1 */
{
"_class": "fr.bpce.kpi.clarity.domain.ClarityResourceAffectation",
"budget_code": "P24DCDSA01",
"task_code": "61427",
"action_code": "121"
}
/* 2 */
{
"_class": "fr.bpce.kpi.clarity.domain.ClarityResourceAffectation",
"budget_code": "P24DCDSA01",
"task_code": "65434",
"action_code": "143"
}
/* 3 */
{
"_class": "fr.bpce.kpi.clarity.domain.ClarityResourceAffectation",
"budget_code": "P24DCDSA01",
"task_code": "65434",
"action_code": "463"
}
/* 4 */
{
"_class": "fr.bpce.kpi.clarity.domain.ClarityResourceAffectation",
"budget_code": "P24PR00",
"task_code": "60298",
"action_code": "255"
}
/* 5 */
{
"_class": "fr.bpce.kpi.clarity.domain.ClarityResourceAffectation",
"budget_code": "P24PR00",
"task_code": "60298",
"action_code": "127"
}
/* 6 */
{
"_class": "fr.bpce.kpi.clarity.domain.ClarityResourceAffectation",
"budget_code": "P24PR00",
"task_code": "67875",
"action_code": "348"
}
/* 7 */
{
"_class": "fr.bpce.kpi.clarity.domain.ClarityResourceAffectation",
"budget_code": "P24PR00",
"task_code": "67875",
"action_code": "654"
}
目前,对于budgetCode
["P221P00"]
,我有一个链接的taskCodes [["2630"],["61297"],["61296"],["61299"]]
的列表。我想在ClarityResourceAffectationReport文件String[][][]actionCode
中添加第三个字段,以进行另一个分组级别。这样,taskCodes
列表的每个元素都将链接到actionCode
列表。在另一个Stackoverflow帖子中,Veeram建议我做两个小组,一个小组在budgetCode
和taskCodes
上推actionCode
,另一小组在budgetCode
上并推上一个小组的taskCodes
和actionCode
。因此,我开发了一种具有两个项目操作和两个聚合操作的方法。我不确定是不是这样。另外,我不知道如何形成分组结果,因为现在我们有两个聚合操作。另外,我认为现在在ClarityResourceAffectationReport中,我有三个数组:
String[] budgetCodes, String[][] taskCodes, String[][][] actionCodes
。@Override
public List<ClarityResourceAffectationReport> aggregateAllBudgetCode() {
//I did two projects instantiations
AggregationOperation projectBudgetTask = new AggregationOperation() {
@Override
public DBObject toDBObject(AggregationOperationContext aggregationOperationContext) {
return new BasicDBObject("$project", new BasicDBObject("budget_code", "$budget_code").append("task_code", Arrays.asList("$task_code")));
}
};
AggregationOperation projectTaskAction = new AggregationOperation() {
@Override
public DBObject toDBObject(AggregationOperationContext aggregationOperationContext) {
return new BasicDBObject("$project", new BasicDBObject("task_code", "$task_code").append("action_code", Arrays.asList("$action_code")));
}
};
//I did two aggregation methods
Aggregation aggregationBudgetTask = newAggregation(projectBudgetTask,
group("budgetCode", "taskCode").addToSet("budgetCodeTaskCode").as("budgetCodeTaskCode").addToSet("actionCode").as("actionCode"),
sort(Sort.Direction.ASC, previousOperation(),"budgetCode", "taskCode"));
Aggregation aggregationTaskAction = newAggregation(projectTaskAction,
group("budgetCode").addToSet("budgetCode").as("budgetCode").addToSet("taskCodes").as("taskCodes").addToSet("actionCode").as("actionCode"),
sort(Sort.Direction.ASC, previousOperation(),"budgetCode"));
//Here, how can I put the two aggregation methods?
AggregationResults groupResults = mongoTemplate.aggregate(aggregation, clarityResourceAffectation.class,
ClarityResourceAffectationReport.class);
List<ClarityResourceAffectationReport> clarityResourceAffectationReport = groupResults.getMappedResults();
return clarityResourceAffectationReport ;
}
在第一个聚合操作中,我做了一个
group("budgetCode", "taskCode")
,然后放了一个addToSet("budgetCodeTaskCode").as("budgetCodeTaskCode")
,因为我想考虑一个分组操作。但是,实际上我想做的是group("budgetCode", "taskCode").addToSet("budgetCode", "taskCode").as("budgetCode", "taskCode")
。但是,在addToSet
和as
方法中,我们不能放置两个参数。那么,我们该怎么办?而且,如何将这两种聚合方法放在AggregationResults groupResults
中?我试过了,但是没有起作用
为了区分
clarityResourceAffectation
和clarityResourceAffectationReport
,我在报告类的每个字段处添加了一个“ s”字母。我更新了帖子。在这里,我尝试了一种聚合操作的代码:
@Override
public List<ClarityResourceAffectationReport> aggregateAllTaskCode() {
AggregationOperation project = new AggregationOperation() {
@Override
public DBObject toDBObject(AggregationOperationContext aggregationOperationContext) {
return new BasicDBObject("$project", new BasicDBObject("task_code", "$task_code").append("action_code", Arrays.asList("$action_code")));
}
};
Aggregation aggregation = newAggregation(project,
group("budgetCode", "taskCode").addToSet("actionCode").as("actionCodes"),
group("budgetCode").first("taskCode").as("taskCode").addToSet(new BasicDBObject("taskCode","$_id.taskCode").append("actionCodes", "$actionCodes")).as("taskCodes"),
sort(Sort.Direction.ASC, previousOperation(),"taskCodes"));
AggregationResults groupResults = mongoTemplate.aggregate(aggregation, ClarityResourceAffectation.class,
ClarityResourceAffectationReport.class);
List<ClarityResourceAffectationReport> clarityResourceAffectationReports = groupResults.getMappedResults();
log.debug("clarityResourceAffectationReports.size()" + clarityResourceAffectationReports.size());
log.debug("aggregation.toString()" + aggregation.toString());
return clarityResourceAffectationReports;
}
我没有运行,并且出现错误:
f.b.k.l.w.r.errors.ExceptionTranslator : Target bean of type [[Ljava.lang.String; is not of type of the persistent entity ([Ljava.lang.String;)!
。无论如何,在代码中您也将.append("actionCodes", "actionCodes")).as("taskCodeActionCodes")
放在第二组后面。您能解释什么是taskCodeActionCodes
吗?扁平结构的结果
我稍微更改了
ResourceAffectationReport
字段的类型:字符串budgetCodes,字符串[] taskCodes和字符串[] [] actionCodes。[
{
"budgetCodes": "P24D001",
"taskCodes": [
"64578"
],
"actionCodes": [
[
"454"
],
[
"253"
],
[
"745"
],
[
"354"
]
]
},
{
"budgetCodes": "P24D002",
"taskCodes": [
"62678"
],
"actionCodes": [
[
"857"
],
[
"907"
],
[
"858"
]
]
}
]
地图结构的结果
在这里,报告文件的类型为String budgetCode,String [] taskCodes,String [] [] actionCodes,List> taskCodesActionCodes。
[
{
"budgetCodes": "P24D001",
"taskCodes": null,
"actionCodes": null,
"taskCodesactionCodes": [
{
"[Ljava.lang.String;@7e695137": [
[
"64578"
]
],
"[Ljava.lang.String;@48ec311a": [
[
"454"
],
[
"253"
],
[
"745"
],
[
"354"
]
]
},
{
"[Ljava.lang.String;@258b30b6": [
[
"62678"
]
],
"[Ljava.lang.String;@481154c7": [
[
"857"
],
[
"907"
],
[
"858"
]
}
]
},
{
"budgetCodes": "P24D002",
"taskCodes": null,
"actionCodes": null,
"taskCodesActionCodes": [
{
"[Ljava.lang.String;@1cdf4a9e": [
[
"64568"
]
],
"[Ljava.lang.String;@1613fdbb": [
[
"764"
],
[
"984"
],
[
"489"
]
]
},
{
"[Ljava.lang.String;@53167f62": [
[
"63887"
]
],
"[Ljava.lang.String;@5a30c8de": [
[
"757"
],
[
"394"
],
[
"294"
],
[
"765"
]
]
}
]
}
]
地图结构方法很有趣,但是我有一些问题要在前端显示,但是由于键是对象类型,这是另一个问题。我会再次测试,然后告诉您。无论如何,这很有趣。实际上,我有另一个想法。我想要的是在每个JSON文档中我都有一个String字段budgetCodes,一个String []字段taskCodes,其中将包含所有
将taskCodes链接到budgetCodes,我认为最终真正适合我想要的是创建一个像这样的TaskCode类:
public class TaskCode {
private String taskCode;
private String[] actionCode;
//Getters and Setters
}
通过这种方式,它将允许我为每个JSON文档使用一个带有budgetCode的简单字符串,一个链接的TaskCodes列表,用于
每个taskCode对象,即String属性taskCode,其中将包含taskCode的值。最后,每个taskCode对象将包含一个String []
与actionCodes列表。
关于POJO结构
它运行良好,但为了在AngularJS前端中显示数据,我遇到了一些问题。我想进行聚合操作,以创建一个菜单,在该菜单中,每次单击元素都会打开一个带有子列表的子菜单,依此类推,依此类推……我不知道聚合是否真的适应了我想做的事。因此,我想到了另一种方法。除了执行聚合操作外,另一种方法可能是通过数据库中的简单查找操作检索我想要的数据,并使用服务层来执行树算法。
提前致谢
最佳答案
您可以在单个聚合管道中执行多个级别分组。
更新了现有项目阶段以包括actionCode
,并更新了现有组以包括actionCode
。
这将显示扁平化的结构,每行包含budgetCodes
,taskCodes
和actionCodes
。
将您的actionCodes
更新为private String[][] actionCodes;
平面结构。
就像是
AggregationOperation project = new AggregationOperation() {
@Override
public DBObject toDBObject(AggregationOperationContext aggregationOperationContext) {
return new BasicDBObject("$project", new BasicDBObject("budget_code", 1).append("task_code", Arrays.asList("$task_code")).append("action_code", Arrays.asList("$action_code")));
}
};
Aggregation aggregation = newAggregation(project,
group("budgetCode", "taskCode").addToSet("actionCode").as("actionCodes"),
project("actionCodes").and("_id.budgetCode").as("budgetCodes").and("_id.taskCode").as("taskCodes").andExclude("_id"),
sort(Sort.Direction.ASC, "budgetCodes","taskCodes"));
像结构一样映射。
将输出DTO调整为
private String[] budgetCodes;
private List<Map<String[], String[][]>> taskCodeActionCodes;
这会将结果输出到Map中,从而为您提供多个分组。
就像是
AggregationOperation project = new AggregationOperation() {
@Override
public DBObject toDBObject(AggregationOperationContext aggregationOperationContext) {
return new BasicDBObject("$project", new BasicDBObject("budget_code", 1).append("task_code", Arrays.asList("$task_code")).append("action_code", Arrays.asList("$action_code")));
}
};
Aggregation aggregation = newAggregation(project,
group("budgetCode", "taskCode").addToSet("actionCode").as("actionCodes"),
group("_id.budgetCode").addToSet(new BasicDBObject("taskCode","$_id.taskCode").append("actionCodes", "$actionCodes")).as("taskCodeActionCodes"),
project("taskCodeActionCodes").and("budgetCodes").previousOperation().andExclude("_id"),
sort(Sort.Direction.ASC, "budgetCodes"));
POJO结构
public class ClarityResourceAffectationReport {
private String budgetCode;
private List<TaskCode> linkedTaskCodes;
}
public class TaskCode {
private String taskCode;
private String[] actionCode;
}
Aggregation aggregation = newAggregation(
group("budgetCode", "taskCode").addToSet("actionCode").as("actionCode"),
group("_id.budgetCode").addToSet(new BasicDBObject("taskCode","$_id.taskCode").append("actionCode", "$actionCode")).as("linkedTaskCodes"),
project("linkedTaskCodes").and("budgetCode").previousOperation().andExclude("_id"),
sort(Sort.Direction.ASC, "budgetCode"));
关于java - 将操作分为两个级别,每个级别都有一个元素-数组关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44503200/