ElasticSearch笔记-聚合查询


概述

聚合查询,它是在搜索的结果上,提供的一些聚合数据信息的方法。比如:求和、最大值、平均数等。
聚合查询可以分为:bucket聚合查询、metrics聚合查询
指标聚合(metric)查询:相当于MYSQL的聚合函数,对数据分组进行统计,如max、min、avg、sum等
桶聚合(bucket)查询:相当于MYSQL的group by,作用是对数据分组。不要对text类型数据进行分组,会失败

为什么对text类型数据进行分组,会失败?
因为text类型会进行分词,分完词后会通过词条存储,分组是希望字段整体和其他的去比对,所以会失败

指标聚合案例

求全部学生的平均分数

GET index5/_search
{
  "size": 0, 
  "query": {
    "match_all": {}
  },
  "aggs": {
    "avg_fenshu": {
      "avg": {
        "field": "fenshu"
      }
    }
  }
}

aggs:appgregations的缩写
avg_fenshu:聚合名称

求全部学生的总分、平均分、最大分、最小分

GET index6/_search
{
  "size": 0, 
  "query": {
    "match_all": {}
  },
  "aggs": {
    "fenshu_sum": {
      "sum": {
        "field": "fenshu"
      }
    },
    "fenshu_avg": {
      "avg": {
        "field": "fenshu"
      }
    },
    "fenshu_max": {
      "max": {
        "field": "fenshu"
      }
    },
    "fenshu_min": {
      "min": {
        "field": "fenshu"
      }
    }
  }
}

桶聚合查询案例

统计每个年龄有多少人

根据年龄分组

GET index5/people/_search
{
  "size":0,
  "aggs": {
    "age_group": {
      "terms": {
        "field": "age"
      }
    }
  }
}

查询结果中可以得到每个分组的数量,这仅是一个bucket操作,doc_count是bucket操作默认执行的一个内置metric

统计每个班级的平均年龄

需要在bucket查询的基础上,再metrics查询
统计班级的平均年龄,根据班级分组,再对每个bucket执行一个metric聚合统计操作

GET index5/people/_search
{
  "size":0,
  "aggs": {
    "sex_group": {
      "terms": {
        "field": "classid"
      },
      "aggs": {
        "avg_age": {
          "avg": {
            "field": "age"
          }
        }
      }
    }
  }
}

下钻

下钻的意思是在分组的基础上在进行分组,比如在班级分组的基础上再对年龄分组,最后对每个最小粒度的分组执行聚合分析操作,年龄分组的基础上计算平均分数
也就是需要两个bucket查询,一个metrics查询

GET index5/people/_search
{
  "size":0,
  "aggs": {
    "sex_group": {
      "terms": {
        "field": "classid"
      },
      "aggs": {
        "age_group": {
          "terms": {
            "field": "age"
          },
          "aggs":{
            "avg_fenshu":{
              "avg": {
                "field": "fenshu"
              }
            }
          }
        }
      }
    }
  }
}

查找每个班级最高分、最低分、平均分

需要使用多个metric,对bucket分析

GET index5/people/_search
{
  "size":0,
  "aggs": {
    "class_group":{
      "terms": {
        "field": "classid"
      },
      "aggs": {
        "avg_age": {
          "avg": {
            "field": "age"
          }
        },
        "max_age":{
          "max": {
            "field": "age"
          }
        },
        "min_age":{
          "min":{
            "field": "age"
          }
        }
      }
    }
  }
}

按年龄区间统计平均分数

GET index5/people/_search
{
  "size":0,
  "aggs": {
    "age_group": {
      "histogram": {
        "field": "age",
        "interval": 1
      },
      "aggs": {
        "fenshu": {
          "avg": {
            "field": "fenshu"
          }
        }
      }
    }
  }
}

按时间区间统计平均分数

GET index5/people/_search
{
  "size":0,
  "aggs": {
    "age_group": {
      "date_histogram": {
        "field": "birthday",
        "interval": "year",
        "format": "yyyy-MM-dd",
        "min_doc_count": 0,
        "extended_bounds": {
          "min": "1985-01-01",
          "max": "2020-01-01"
        }
      },
      "aggs": {
        "avg_fenshu": {
          "avg": {
            "field": "fenshu"
          }
        }
      }
    }    
  }
}

global bucket

global bucket可排除查询条件,用于整体与按条件查询结果对比
查询1班的平均成绩与全部班级的平均成绩

GET index6/user/_search
{
  "size":0,
  "query": {
    "term": {
      "classid": {
        "value": 3
      }
    }
  }, 
  "aggs": {
    "age_avg": {
      "avg": {
        "field": "age"
      }
    },
    "all_user":{
      "global": {},
      "aggs": {
        "global_avg_fenshu": {
          "avg": {
            "field": "fenshu"
          }
        }
      }
    }
  }
}

过滤bucket

aggs.filter,针对聚合过滤
如果filter放query里,是全局的。如果想对统计结果过滤,需要将filter放在aggs中
搜索1班90年出生学生的平均成绩

GET index5/people/_search
{
  "size": 0,
  "query": {
    "match": {
      "classid": 1
    }
  }, 
  "aggs": {
    "recent_90":{
      "filter": {
        "range": {
          "birthday": {
            "gte": "1990/01/01",
            "lte": "1991/01/01"
          }
        }
      },
      "aggs": {
        "avg_fenshu": {
          "avg": {
            "field": "fenshu"
          }
        }
      }
    }
  }
}

排序

对分析的结果排序
按班级分组,并按平均分数排序

GET index5/people/_search
{
  "size": 0,
  "aggs": {
    "class_group": {
      "terms": {
        "field": "classid",
        "order": {
          "avg_fenshu": "desc"
        }
      },
      "aggs": {
        "avg_fenshu": {
          "avg": {
            "field": "fenshu"
          }
        }
      }
    }
  }
}

去重

对每个bucket中指定field进行去重,取去重后的count,类似count(distinct)

GET index5/people/_search
{
  "size": 0,
  "aggs": {
    "years": {
      "date_histogram": {
        "field": "birthday",
        "interval": "year",
        "format": "yyyy-MM-dd",
        "min_doc_count": 0,
        "extended_bounds": {
          "min": "1985-01-01",
          "max": "2020-01-01"
        }
      },
      "aggs": {
        "age_distinct": {
          "cardinality": {
            "field": "age"
          }
          }
      }
    }
  }
}