2

我與MongoDB和Spring Data的Aggregation Framework打了很長時間,我真的想知道我想做的事情是否真的可行。SpringData - Mongo - Aggregation

我有以下蒙戈文件:

{ 
    "_id": ObjectId("564520fad4c64dd36fb1f0a4"), 
    "_class": "com.sample.Purchase", 
    "created": new Date(1447371002645), 
    "productId": NumberLong(12), 
    "clientId": "c1", 
    "price": NumberLong(20) 
} 

我想創建以下數據:

List<ClientStatsEntry> entries; 

public class ClientStatsEntry { 
    private String clientId; 
    private Date firstSeen; 
    private Date lastSeen; 
    private Long totalPriceSpend; 
    private long totalCount; 
} 

所以基本步驟是:

  1. 過濾收集,按ProductID (火柴)
  2. 拆分所有剩餘的元素的clientId(GROUPBY)
  3. 檢索第一個和最後一個條目
  4. 總結一下所有的價格,並存儲在「totalPrice」
  5. 計數所有購買的創建日期,並將其存儲在「TOTALCOUNT」

我試圖啓動與方法,但我不能找到一種方法,如何在一個聚集pipepline做的一切:

Aggregation agg = newAggregation(
      match(Criteria.where("productId").is(productId)), 
      group("clientId").sum("price").as("totalPriceSpend"), 
      Aggregation.project("totalPriceSpend", "productId").and("productId").previousOperation()); 

回答

2

我相信你正在尋找這種聚合管道(註釋分別表示ŧ他列出的步驟):

db.purchase.aggregate([ 
    /* 1. Filter collection by productId (match) */ 
    { 
     "$match": { 
      "productId": productId 
     } 
    }, 
    /* 2. Split all remaining elements by clientIds (groupBy) */ 
    { 
     "$group": { 
      "_id": "$clientId", 
      "firstSeen": { "$min": "$createdDate"}, // 3. a) Retrieve the created date of the first entry 
      "lastSeen": { "$max": "$createdDate"}, // 3. b) Retrieve the created date of the last entry 
      /* 4. Sum up all prices and store in "totalPrice" */ 
      "totalPriceSpend": { 
       "$sum": "$price" 
      }, 
      /* 5. Count all purchases and store it in "totalCount" */ 
      "totalCount": { 
       "$sum": 1 
      } 
     } 
    } 
]) 

春季數據MongoDB的聚集等價如下:

Aggregation agg = Aggregation.newAggregation( 
    match(Criteria.where("productId").is(productId)), 
    group("clientId") 
     .min("createdDate").as("firstSeen") 
     .max("createdDate").as("lastSeen") 
     .sum("price").as("totalPriceSpend") 
     .count().as("totalCount"), 
    project("firstSeen", "lastSeen", "totalPriceSpend", "totalCount") 
     .and("clientId").previousOperation() 
); 
AggregationResults<ClientStatsEntry> result = 
    mongoTemplate.aggregate(agg, ClientStatsEntry.class); 
List<ClientStatsEntry> clientStatsList = result.getMappedResults(); 
+1

絕對真棒!非常感謝您的幫助,這實際上工作很好! :) – Fritz

+1

只是爲了完成以前的答案,有一個缺少匹配和組方法之間的「排序()」操作,按「createdDate」排序...然後它實際上很不錯 – Fritz

+0

@Fritz Gotcha,已經完全錯過那個關鍵點。在這種情況下,'$ min'和'$ max'操作符是易於替代的。感謝您的更正,稍微更新我的答案。 – chridam

相關問題