mongoTemplate.aggregate()聚合查詢


一、概述

1. 聚合的表達式

MongoDB中聚合(aggregate)主要用於處理數據(諸如統計平均值,求和等),並返回計算后的數據結果。有點類似sql語句中的 count(*)。

下表展示了一些聚合的表達式:

表達式 描述 實例
$sum 計算總和。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}])
$avg 計算平均值 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}])
$min 獲取集合中所有文檔對應值得最小值。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}])
$max 獲取集合中所有文檔對應值得最大值。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}])
$push 在結果文檔中插入值到一個數組中。 db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}])
$addToSet 在結果文檔中插入值到一個數組中,但不創建副本。 db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}])
$first 根據資源文檔的排序獲取第一個文檔數據。 db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}])
$last 根據資源文檔的排序獲取最后一個文檔數據 db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])

2. 管道的概念

管道在Unix和Linux中一般用於將當前命令的輸出結果作為下一個命令的參數。

MongoDB的聚合管道將MongoDB文檔在一個管道處理完畢后將結果傳遞給下一個管道處理。管道操作是可以重復的。

表達式:處理輸入文檔並輸出。表達式是無狀態的,只能用於計算當前聚合管道的文檔,不能處理其它的文檔。

這里我們介紹一下聚合框架中常用的幾個操作:

  • $project:修改輸入文檔的結構。可以用來重命名、增加或刪除域,也可以用於創建計算結果以及嵌套文檔。
  • $match:用於過濾數據,只輸出符合條件的文檔。$match使用MongoDB的標准查詢操作。
  • $limit:用來限制MongoDB聚合管道返回的文檔數。
  • $skip:在聚合管道中跳過指定數量的文檔,並返回余下的文檔。
  • $unwind:將文檔中的某一個數組類型字段拆分成多條,每條包含數組中的一個值。
  • $group:將集合中的文檔分組,可用於統計結果。
  • $sort:將輸入文檔排序后輸出。
  • $geoNear:輸出接近某一地理位置的有序文檔。

3. 聚合查詢示例:

db.articles.aggregate( [
                        { $match : { score : { $gt : 70, $lte : 90 } } },
                        { $group: { _id: null, count: { $sum: 1 } } }
                       ] );

但是在代碼中要如何實現類似以上功能呢?

二、代碼實現(sum求和)

功能描述:

  1. 當name和course同時傳參時,按id分組,統計總分數
  2. 按name分組,統計相同name的總分數
  3. 按course分組,統計總分數
public double getTotleScoreWithMongoTemplate(StudentScore studentScore) {

  //封裝查詢條件
  List<AggregationOperation> operations = new ArrayList<>();

  if (StringUtils.isEmpty(studentScore.getName()) && StringUtils.isEmpty(studentScore.getCourse())){

    //totleScore為StudentScore類中新建的屬性,用於接收統計后的總分數;當然也可以使用score(或其他屬性)接收
    operations.add(Aggregation.group("id").sum("score").as("totleScore"));
  }
  if (!StringUtils.isEmpty(studentScore.getName())) {
    operations.add(Aggregation.match(Criteria.where("name").is(studentScore.getName())));
    operations.add(Aggregation.group("name").sum("score").as("totleScore"));
  }
  if (!StringUtils.isEmpty(studentScore.getCourse())) {
    operations.add(Aggregation.match(Criteria.where("course").is(studentScore.getCourse())));
    operations.add(Aggregation.group("course").sum("score").as("totleScore"));
  }
  Aggregation aggregation = Aggregation.newAggregation(operations);

  //查詢、並獲取結果
  AggregationResults<StudentScore> results = mongoTemplate.aggregate(aggregation, "studentScore", StudentScore.class);
  double totleScore = results.getUniqueMappedResult().getTotleScore();

  return totleScore;
}

  對於其他的功能,可以修改以上代碼自行測試,此處不再舉例


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM