[英]Spring-Data not summing up the quarterly results
我是 Mongodb 和 spring-data 的新手,我參考了這個 stackoverflow 鏈接按季度分組,這個鏈接在 spring 數據中使用 $cond 運算符,並在下面構建了這個代碼片段,用於在 mongodb 中檢索季度銷售報告:
String pipeline = "{$project:{_id:1,'unitsSold':1,'dateSold':1,'results': 1 ,
'productName': 1, 'year':{$year:['$dateSold']}, "+
"'quarter':{$cond:[{$lte:[{$month:'$dateSold'},3]},"+
"'first'," +
"{$cond:[{$lte:[{$month:'$dateSold'},6]},"+
"'second',"+
"{$cond:[{$lte[{$month:'$dateSold'},9]},"+"'third',"+
"'fourth']}]}]}}},"+
"{$group:{'_id':{ 'year':'$year', 'quarter':'$quarter'},
'unitsSold': { $sum: '$unitsSold' },'results':{$push:'$$ROOT'}}}";
DBObject operation = (DBObject)JSON.parse (pipeline);
TypedAggregation<SampleReport> aggregation =newAggregation(SampleReport.class,
new DBObjectAggregationOperation(operation)
);
AggregationResults<SampleReport> result =mongoTemplate.aggregate(aggregation, SampleReport.class);
List<SampleReport> list = result.getMappedResults();
for(SampleReport r : list)
{
System.out.println (r.getProductName() + " : " + r.getUnitsSold() + " : " + r.getQuarter() +":: "+r.getYear());
}
問題不是總結銷售的單位。 請讓我知道我在彈簧數據上哪里出了問題。 但是這個查詢使用 robomongo 獲得了所需的結果。
問候
克里斯
如果你說它適用於另一個客戶端,那么可能在交易中丟失了一些東西。 您當然可以在這里清理一些東西以使其更加簡化。
我通常可以建議一種更有效的“數學”方法來確定當前季度而不是當前的嵌套條件語句,好像沒有其他方法可以讓事情變得更清晰。 除了“效率”之外,您不應該只在$group
之前使用$project
,在那里將所有內容簡單地組合到一個階段是合乎邏輯的:
[
{ "$group": {
"_id": {
"year": { "$year": "$dateSold" },
"quarter": {
"$add": [
{ "$subtract": [
{ "$divide": [{ "$subtract": [{ "$month": "$dateSold" },1]},3]},
{ "$mod": [
{ "$divide": [{ "$subtract": [{ "$month": "$dateSold" },1]},3]},
1
]}
]},
1
]
}
},
"unitsSold": { "$sum": "$unitsSold" }
}}
]
如果確實必須,請務必添加您的"$push": "$$ROOT"
,但減少涉及的邏輯並將所有內容放入一個合乎邏輯的單個管道階段,這在很大程度上是這里的重點。
下一階段是我強烈建議您對它進行本機編碼。 雖然可能很容易認為您有一個可以使用的 JSON 表示法,但您會發現,隨着時間的推移,這既不靈活,也不能提供非常好的可讀性來放置在長字符串中並依賴於解析它們。 此外,您通常希望在某個階段插入局部變量
Aggregation aggregation = newAggregation(
new CustomGroupOperation(
new BasicDBObject("$group",
new BasicDBObject("_id",
new BasicDBObject("year",new BasicDBObject("$year","$dateSold"))
.append("quarter",new BasicDBObject(
"$add",Arrays.asList(
new BasicDBObject("$subtract",Arrays.asList(
new BasicDBObject("$divide",Arrays.asList(
new BasicDBObject("$subtract",Arrays.asList(
new BasicDBObject("$month","$dateSold"),
1
)),
3
)),
new BasicDBObject("$mod",Arrays.asList(
new BasicDBObject("$divide", Arrays.asList(
new BasicDBObject("$subtract",Arrays.asList(
new BasicDBObject("$month", "$dateSold"),
1
)),
3
)),
1
))
)),
1
)
))
)
.append("unitsSold", new BasicDBObject("$sum", "$unitsSold"))
)
)
);
您似乎還抽象了一些其他代碼,但我個人更喜歡以不會與在newAggregation
結構中使用其他 spring-mongo 聚合助手沖突的方式實現CustomGroupOperation
:
public class CustomGroupOperation implements AggregationOperation {
private DBObject operation;
public CustomGroupOperation (DBObject operation) {
this.operation = operation;
}
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return context.getMappedObject(operation);
}
}
但正如最初所述,如果您得到0
結果,那么它是字段命名或“類型”,其中該字段的名稱不同,或者實際上是一個字符串。 但是相同的語句應該以類似的方式在任何其他客戶端中失敗,唯一的補救措施是適當地修復命名或“類型”。
對於您正在做的事情,這當然是一種“更清潔”的方法。 “數學”對於索引季度來說是合理的,甚至可以通過簡單的映射適用於其他“財務季度”。 與此處的管道階段整合一樣,根據數據的整體大小提供了顯着的性能提升,因為$project
意味着不必要地傳遞數據只是為了預先調整您不想要的字段。
修正定義和執行,然后檢查您的字段和數據以查看所有內容是否正確命名和鍵入。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.