簡體   English   中英

Spring-Data 未總結季度業績

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM