我正在使用AngularJS前端和java後端的JHipster項目。我在MongoDB數據庫中使用Spring Data。在兩個層次上分組操作,每個級別都有一個元素 - 數組關聯
我在一個名爲budgetCode
的字符串字段上做了一個分組操作。因此,對於每個budgetCode
,都有一個鏈接的taskCodes
這是另一個字符串字段的列表。我成功通過另一個#1後要做到這一點:「分組在現場操作,並把喜歡的領域列表陣列中的」
這裏,方法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文件:
ClarityResourceAffectation
@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"
]
]
}
]
地圖結構
在這裏的結果是,類型報告文件字符串budgetCode的,字符串[] taskCodes,字符串[] [] actionCodes,列表> 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"
]
]
}
]
}
]
的地圖結構的方法是有趣的,但我在爲了顯示在我的前端的一些問題,但是這是因爲這是對象類型的鍵的另一問題。我會再次測試,我會告訴你。無論如何,它是Interresting。其實,我有另一個想法。我想要的是,在每個JSON文檔中,我有一個字符串字段budgetCodes,一個字符串[]字段taskCodes,其中將包含鏈接到budgetCodes的所有 taskCodes,我認爲最終真正適用於我想要創建的TaskCode類這樣的:
public class TaskCode {
private String taskCode;
private String[] actionCode;
//Getters and Setters
}
通過這種方式,可以讓我爲每個JSON文件,一個簡單的字符串與budgetCode,與 每個taskCode對象鏈接TaskCodes的列表中,字符串屬性taskCode這將包含taskCode的值。最後,每個taskCode對象將包含一個帶有actionCodes列表的String [] 。
關於POJO結構
它的功能良好,但我在爲了顯示在AngularJS前端的數據的一些問題。我想要做一個聚合操作來創建一個菜單,其中每次點擊一個元素將打開一個子菜單和一個子列表,等等......我不知道一個聚合是否真的適應我想要做的事情。所以,我想到了另一種方法。也許另一種方法可能是通過數據庫中的簡單查找操作來檢索我想要的數據,並使用服務層來完成樹算法。
在此先感謝
這可能會是一個更加清晰,如果你表現出一定的樣本文件和輸出你期望從他們得到。目前這個問題結構的危險在於你的「嘗試」可能完全沒有達到你需要的結果標記。這就是爲什麼通常最好是*「通過示例問問」*因此有一個明確的「來源」和「結果」。另外,請不要在項目的每個組件上「標記」您的問題。根據實際問題的應用標籤,您只是詢問「spring-mongo」和「聚合框架」**。 –
我明白你的意思。實際上,我只想在2個級別上進行分組,因爲每個結果都必須放在一個子數組中。這就是爲什麼'ClarityResourceAffection'(對於輸入字段)有三個字符串字段:String budgetCode,String taskCode,String actionCode和ClarityResourceAffectionReport(對於輸出字段),有三個數組'String [ ] budgetCode,String [] [] taskCode,String [] [] [] actionCode'。通過這種方式,'String [] budgetCode'將包含所有的budgetCodes,'String [] [] taskCode'將包含每個budgetCode的任務代碼列表等等。 – henry22
您知道我們無法從這裏看到您的計算機屏幕。所以我要求你展示一些數據和期望的結果。你的代碼沒有很好地解釋這一點。編輯你的問題,請包括文件。 –