筆記:使用mongo聚合查詢(一開始根本沒接觸過mongo,一點一點慢慢的查資料完成了工作需求)
需求:在訂單表中,根據buyerNick分組,統計每個buyerNick的電話、地址、支付總金額以及總商品數,返回結果是CustomerDetail。
/*
* project:列出所有本次查詢的字段,包括查詢條件的字段和需要搜索的字段;
* match:搜索條件criteria
* unwind:某一個字段是集合,將該字段分解成數組
* group:分組的字段,以及聚合相關查詢
* sum:求和(同sql查詢)
* count:數量(同sql查詢)
* as:別名(同sql查詢)
* addToSet:將符合的字段值添加到一個集合或數組中
* sort:排序
* skip&limit:分頁查詢
*/
public List<CustomerDetail> customerDetailList(Integer pageNum,String userId,String buyerNick,String itemId,List<String> phones) throws Exception{
Criteria criteria = Criteria.where("userId").is(userId);
Integer pageSize = 10;
Integer startRows = (pageNum - 1) * pageSize;
if(buyerNick != null && !"".equals(buyerNick)){
criteria.and("buyerNick").is(buyerNick);
}
if(phones != null && phones.size() > 0){
criteria.and("mobile").in(phoneList);
}
if(itemId != null && !"".equals(itemId)){
criteria.and("orders.numIid").is(itemId);
}
Aggregation customerAgg = Aggregation.newAggregation(
Aggregation.project("buyerNick","payment","num","tid","userId","address","mobile","orders"),
Aggregation.match(criteria),
Aggregation.unwind("orders"),
Aggregation.group("buyerNick").first("buyerNick").as("buyerNick").first("mobile").as("mobile").
first("address").as("address").sum("payment").as("totalPayment").sum("num").as("itemNum").count().as("orderNum"),
Aggregation.sort(new Sort(new Sort.Order(Sort.Direction.DESC, "totalPayment"))),
Aggregation.skip(startRows),
Aggregation.limit(pageSize)
);
List<CustomerDetail> customerList = tradeRepository.findAggregateList(new Query(criteria), userId, customerAgg,CustomerDetail.class);
return customerList;
}
public <T> List<T> findAggregateList(Query query,String userNickName, Aggregation aggregation,Class<T> clazz) {
String collectionName = getCollectionName(userNickName);
AggregationResults<T> aggregate = this.mongoTemplate.aggregate(aggregation, collectionName, clazz);
List<T> customerDetails = aggregate.getMappedResults();
return customerDetails;
}
Trade表:
public class TradeInfo{
private String tid;//訂單id
private Double payment;//支付金額
private String buyerNick;//買家昵稱
private String address;//地址
private String mobile;//手機號
private Long num;//購買商品數量
private List<order> orders;子訂單
}
CustomerDetail:
public class CustomerDetail{
private String buyerNick;//買家昵稱
private Double totalPayment;//訂單金額
private Integer orderNum;//訂單數
private Integer itemNum;//商品數
private String address;//地址
}
OVER!
補充:
mongo中的時間和本地時間是相差8小時的,所以需要按照時間分組進行統計計算的時候可以用到plus:

plus的參數可以是毫秒,8小時就是28800000,之后再進行正常的統計計算。
