Elasticsearch 聚合功能

起因:在项目开发过程中,要使用到搜索 引擎来对一些关键字实现逆向查询,如果仅用模糊搜索,那么搜索的时间会根据数据量的增大而增大,对比之下就学了elasticsearch,也记录一下,常常回顾。


1. 什么是Elasticsearch聚合功能

类型数据的分组,ES中聚合是对查询出来的数据结果进行分组

ES中的聚合命令是aggregation

  • Bucket Aggregation:一些列满足特定条件的的文档集合

  • Metric Aggregation:一些数学运算,可以对文档字段进行统计分析

  • Pipeline Aggregation:对聚合结果进行二次聚合

  • Matrix Aggregation:支持对多个字段的操作并提供一个结果矩阵

select count(brand) #这个就相当于上面的Metric
from cars
group by brand #这个就相当于上面的bucket

大多数Metric都是输出一个值

  • min / max / sum / avg / cardinality

部分metric支持多个数值

  • stats / percentiles / percentiles_ranks

注意:聚合分桶只能对keyword字段进行,对text进行是不行的

如果想要在text字段上进行聚合分桶如何做

  • 第一种方式:加个keyword的子字段 nickname.keyword

  • 第二种方式:就对text分词进行分桶

# 在ES中默认对fielddata是false的
# 因为开启text的fielddata后对内存占用高
# 开启后该field进行分词后桶合并
"nickname": {
 "type": "text",
 "fielddata": true
}

2. 聚合桶实例功能使用和分析

2.1. 使用terms分桶加metric数学运算

# 场景1: 对查询结果进行聚合,得出不同城市的学员数
{
 "query": {
 "match_all": {}
 },
 "aggs": {
 "city_count": {
 "terms": {
 "field": "city"
 }
 }
 }
}
# 场景2: 对查询结果进行聚合,得出不同城市的学员数,并得出各个城市学员消费的最大最小平均
# 关键字: terms / aggs / min / max / avg 
# aggs下面的第一个key是你的分组名
{
 "query": {
 "match_all": {}
 },
 "size": 0,
 "aggs": {
 "city_count": {
 "terms": {
 "field": "city"
 },
 "aggs": {
 "avg_consume": {
 "avg": {
 "field": "consume"
 }
 },
 "max_consume": {
 "max": {
 "field": "consume"
 }
 },
 "min_consume": {
 "min": {
 "field": "consume"
 }
 }
 }
 }
 }
}
# 场景3: 对查询结果进行聚合,得出不同城市的学员数,城市的平均消费水平,该城市学院的性别分布
{
 "query": {
 "match_all": {}
 },
 "size": 0,
 "aggs": {
 "city_count": {
 "terms": {
 "field": "city"
 },
 "aggs": {
 "avg_consume": {
 "avg": {
 "field": "consume"
 }
 },
 "sex_count": {
 "terms": {
 "field": "sex"
 }
 }
 }
 }
 }
}
# 将场景3修改为stats的多输出metric
{
 "query": {
 "match_all": {}
 },
 "size": 0,
 "aggs": {
 "city_count": {
 "terms": {
 "field": "city"
 },
 "aggs": {
 "avg_stats": {
 "stats": {
 "field": "consume"
 }
 },
 "sex_count": {
 "terms": {
 "field": "sex"
 }
 }
 }
 }
 }
}
# 场景4:统计一下各个城市学员,年龄最大排前2的并返回信息
{
 "query": {
 "match_all": {}
 },
 "size": 0,
 "aggs": {
 "city_count": {
 "terms": {
 "field": "city"
 },
 "aggs": {
 "age_top": {
 "top_hits": {
 "size": 2,
 "sort": [
 {
 "age": "desc"
 }
 ]
 }
 }
 }
 }
 }
}

2.2. 基础数据

Elasticsearch安装时要提前把ik分词器,pinyin分词器安装好

mapping

# POST  /index_customer/_mapping
{
 "properties": {
 "id": {
 "type": "long"
 },
 "age": {
 "type": "integer"
 },
 "username": {
 "type": "keyword"
 },
 "nickname": {
 "type": "text",
 "analyzer": "ik_max_word",
 "fields": {
 "pinyin": {
 "type": "text",
 "analyzer": "pinyin"
 }
 }
 },
 "consume": {
 "type": "float"
 },
 "desc": {
 "type": "text",
 "analyzer": "ik_max_word"
 },
 "sex": {
 "type": "byte"
 },
 "birthday": {
 "type": "date"
 },
 "city": {
 "type": "keyword"
 },
 "faceimg": {
 "type": "text",
 "index": false
 }
 }
}

document

# POST /index_customer/_doc/1001
{
 "id": 1001,
 "age": 24,
 "username": "kingliu",
 "nickname": "飞上天空做太阳",
 "consume": 1289.88,
 "desc": "我在艾编程学习java和vue,学习到了很多知识",
 "sex": 1,
 "birthday": "1996-12-24",
 "city": "北京",
 "faceimg": "https://www.icodingedu.com/img/customers/1001/logo.png"
}
# POST /index_customer/_doc/1002
{
 "id": 1002,
 "age": 26,
 "username": "lucywang",
 "nickname": "夜空中最亮的星",
 "consume": 6699.88,
 "desc": "我在艾编程学习VIP课程,非常打动我",
 "sex": 0,
 "birthday": "1994-02-24",
 "city": "北京",
 "faceimg": "https://www.icodingedu.com/img/customers/1002/logo.png"
}
# POST /index_customer/_doc/1003
{
 "id": 1003,
 "age": 30,
 "username": "kkstar",
 "nickname": "照亮你的星",
 "consume": 7799.66,
 "desc": "老师们授课风格不同,但结果却是异曲同工,讲的很不错,值得推荐",
 "sex": 1,
 "birthday": "1990-12-02",
 "city": "北京",
 "faceimg": "https://www.icodingedu.com/img/customers/1003/logo.png"
}
# POST /index_customer/_doc/1004
{
 "id": 1004,
 "age": 31,
 "username": "alexwang",
 "nickname": "骑着老虎看日出",
 "consume": 9799.66,
 "desc": "课程内容充实,有料,很有吸引力,赞一个",
 "sex": 1,
 "birthday": "1989-05-09",
 "city": "上海",
 "faceimg": "https://www.icodingedu.com/img/customers/1004/logo.png"
}
# POST /index_customer/_doc/1005
{
 "id": 1005,
 "age": 32,
 "username": "jsonzhang",
 "nickname": "我是你的神话",
 "consume": 12789.66,
 "desc": "需要抽时间把所有内容都学个遍,太给力料",
 "sex": 1,
 "birthday": "1988-07-19",
 "city": "上海",
 "faceimg": "https://www.icodingedu.com/img/customers/1005/logo.png"
}
# POST /index_customer/_doc/1006
{
 "id": 1006,
 "age": 27,
 "username": "abbyli",
 "nickname": "好甜的棉花糖",
 "consume": 10789.86,
 "desc": "还不错,内容超过我的预期值,钱花的值",
 "sex": 0,
 "birthday": "1993-10-11",
 "city": "上海",
 "faceimg": "https://www.icodingedu.com/img/customers/1006/logo.png"
}
# POST /index_customer/_doc/1007
{
 "id": 1007,
 "age": 33,
 "username": "jacktian",
 "nickname": "船长jack",
 "consume": 9789.86,
 "desc": "一直想抽时间学习,这下有时间整了,给力",
 "sex": 1,
 "birthday": "1987-09-16",
 "city": "深圳",
 "faceimg": "https://www.icodingedu.com/img/customers/1007/logo.png"
}
# POST /index_customer/_doc/1008
{
 "id": 1008,
 "age": 23,
 "username": "feifei",
 "nickname": "我爱篮球",
 "consume": 6689.86,
 "desc": "虽然又一些不太懂,但只要有时间,相信一定能学好的",
 "sex": 1,
 "birthday": "1997-04-18",
 "city": "深圳",
 "faceimg": "https://www.icodingedu.com/img/customers/1008/logo.png"
}
# POST /index_customer/_doc/1009
{
 "id": 1009,
 "age": 25,
 "username": "daisyzhang",
 "nickname": "一起看日出",
 "consume": 6680,
 "desc": "学习起来还是很有意思的,值得我多次学习",
 "sex": 0,
 "birthday": "1995-03-27",
 "city": "深圳",
 "faceimg": "https://www.icodingedu.com/img/customers/1009/logo.png"
}
# POST /index_customer/_doc/1010
{
 "id": 1010,
 "age": 29,
 "username": "ethenhe",
 "nickname": "旋风小子",
 "consume": 6699.99,
 "desc": "课程严谨,知识丰富,讲解到位,编程给力",
 "sex": 1,
 "birthday": "1991-06-22",
 "city": "广州",
 "faceimg": "https://www.icodingedu.com/img/customers/1010/logo.png"
}
# POST /index_customer/_doc/1011
{
 "id": 1011,
 "age": 27,
 "username": "lydiazheng",
 "nickname": "跳芭蕾的小妮",
 "consume": 8899.99,
 "desc": "自己一直都没有动力去系统学习,这次有了老师和大家的督促,非常不错,终于坚持下来了",
 "sex": 0,
 "birthday": "1993-08-27",
 "city": "广州",
 "faceimg": "https://www.icodingedu.com/img/customers/1011/logo.png"
}
# POST /index_customer/_doc/1012
{
 "id": 1012,
 "age": 37,
 "username": "draglong",
 "nickname": "飞龙在天",
 "consume": 18899.99,
 "desc": "技术宅,就喜欢研究技术,和大家碰撞感觉很好",
 "sex": 1,
 "birthday": "1983-11-22",
 "city": "广州",
 "faceimg": "https://www.icodingedu.com/img/customers/1012/logo.png"
}

3. ES桶聚合后相关指标分析&text字段聚合方式

如果想要对text类型的字段进行分桶

1、给field增加keyword的子字段

POST /index_customer/_mapping
{
    "properties": {
        "nickname": {
            "analyzer": "ik_max_word",
            "type": "text",
            "fields": {
                "pinyin": {
                    "analyzer": "pinyin",
                    "type": "text"
                },
                "keyword": {
                    "ignore_above": 256,
                    "type": "keyword"
                }
            }
        }
    }
}
# 在数据添加后增加子字段需要将index进行更新
POST /index_customer/_update_by_query

2、给field增加fielddata

# fielddata是对text文本进行分词后的桶聚合
# 默认是false,打开会比较占内存,所以没有必要的情况
POST /index_customer/_mapping
{
    "properties": {
        "nickname": {
            "analyzer": "ik_max_word",
            "type": "text",
            "fielddata": true,
            "fields": {
                "pinyin": {
                    "analyzer": "pinyin",
                    "type": "text",
                    "fielddata": true
                },
                "keyword": {
                    "ignore_above": 256,
                    "type": "keyword"
                }
            }
        }
    }
}

分桶返回的参数分析

  • doc_count_error_upper_bound:可能存在潜在的结果是聚合后结果排行第二的值

  • sum_other_doc_count:表示本次聚合中还有多少没有统计展示出

    • 桶默认聚合展示10条
    • 可以使用size来调整条目数
    • 只能指定条目数,不能分页
  • buckets:会根据结果的统计降序排列

size进行桶查询的展示

POST /index_customer/_search
{
    "query": {
        "match_all": {}
    },
    "size": 0,
    "aggs": {
        "nickname_term": {
            "terms": {
                "field": "nickname",
                "size": 20
            }
        }
    }
}

当doc频繁有数据加入到文档中,并且这个field会频繁进行分桶,需要添加一个缓存配置

# 频繁聚合查询,索引不断有新的doc加入
# "eager_global_ordinals": true
POST /index_customer/_mapping
{
    "properties": {
        "nickname": {
            "analyzer": "ik_max_word",
            "type": "text",
            "fielddata": true,
            "eager_global_ordinals": true,
            "fields": {
                "pinyin": {
                    "analyzer": "pinyin",
                    "type": "text",
                    "fielddata": true,
                    "eager_global_ordinals": true
                },
                "keyword": {
                    "ignore_above": 256,
                    "type": "keyword"
                }
            }
        }
    }
}

分组基数查询

# cardinality统计桶分词的基数
POST /index_customer/_search
{
    "query": {
        "match_all": {}
    },
    "size": 0,
    "aggs": {
        "nickname_term": {
            "cardinality": {
                "field": "nickname"
            }
        }
    }
}

4. 桶range计算

就是一个区间值的查询

POST POST /index_customer/_search
{
    "query": {
        "match_all": {}
    },
    "size": 0,
    "sort": [
        {
            "consume": "desc"
        }
    ],
    "aggs": {
        "city_count": {
            "terms": {
                "field": "city"
            }
        },
        "consume_range": {
            "range": {
                "field": "consume",
                "ranges": [
                    {
                        "to": 3000
                    },
                    {
                        "from": 3000,
                        "to": 6000
                    },
                    {
                        "from": 6000,
                        "to": 9000
                    },
                    {
                        "from": 9000
                    }
                ]
            }
        }
    }
}

直方图的聚合

POST /index_customer/_search
{
    "query": {
        "match_all": {}
    },
    "size": 0,
    "sort": [
        {
            "consume": "desc"
        }
    ],
    "aggs": {
        "city_count": {
            "terms": {
                "field": "city"
            }
        },
        "consume_histogram": {
            "histogram": {
                "field": "consume",
                "interval": 2000,
                "extended_bounds": {
                    "min": 0,
                    "max": 20000
                }
            }
        }
    }
}

5. Pipeline聚合计算

pipeline就是对聚合分析再做一次聚合分析

# 场景:从所有城市的平均消费中,拿出最低的那个城市
GET /index_customer/_search
{
    "query": {
        "match_all": {}
    },
    "size": 0,
    "sort": [
        {
            "consume": "desc"
        }
    ],
    "aggs": {
        "city_count": {
            "terms": {
                "field": "city"
            },
            "aggs": {
                "avg_consume": {
                    "avg": {
                        "field": "consume"
                    }
                }
            }
        },
        "min_consume_by_city": {
            "min_bucket": {
                "buckets_path": "city_count>avg_consume"
            }
        }
    }
}
# min_bucket / buckets_path 是关键字
# max_bucket / min_bucket / avg_bucket / sum_bucket / stats_bucket

不要以为每天把功能完成了就行了,这种思想是要不得的,互勉~!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335