一、数据聚合
1、聚合的分类
聚合(aggregations)可以实现对文档数据的统计、分析、运算。
聚合常见有三类:
- 桶聚合 Bucket:对文档数据分组,并统计每组数量
- TermAggregation:按照文档字段值分组(有点像mysql的group by)
- Date Histogram:按照日期阶梯分组,例如一周为一组,或者一月一组
- 度量聚合 Metric:对文档数据做计算,例如最大值,最小值,平均值等
- avg:求平均值
- max:求最大值
- min:求最小值
- stats:同时求max、min、avg、sum等
- 管道聚合 Pipeline:基于其他聚合结果再做聚合
参与聚合的字段类型必须是不可分词的:
- keyword
- 数值
- 日期
- 布尔
2、DSL实现Bucket聚合
现在要统计所有数据中的酒店品牌有几种,可以根据酒店品牌的名称做聚合
aggs代表聚合,与query同级,用aggs的时候query的作用是做返回,在query范围下聚合
聚合必须要的三要素是:聚合名称,聚合类型,聚合字段
可以配置的属性:
- size:限制聚合结果的数量
- order:指定聚合结果排序方式
- field:指定聚合字段
3、DSL实现Metrics聚合
用了mertrics的stats,最大、最小、平均都求,然后再上面order指定根据平均值排序
4、RestAPI实现聚合
5、案例
实现对品牌、城市、星级的聚合
需求:搜索页面的品牌、城市等信息不应该是在页面写死,而是通过聚合索引库中的酒店数据得来
要用map来接收,map的key就是城市或者星级这些,value就是对应的聚合list
这样就可以完成基本的功能了,但会有个问题:
像这样,如果用户带着条件来查询的话,比如带着虹桥来查询,我们给用户筛选条件聚合还是根据全局索引聚合的,会先很多别的城市,这些城市没有虹桥如果点击就出问题了。所以我们要想办法改成对用户的输入条件聚合
其实就是在聚合条件上加查询条件,限制聚合的范围。
二、自动补全
1、拼音分词器
要实现根据字母做补全,就必须对文档按照拼音分词。
直接去下载拼音分词器的插件,然后analyzer选pinyin就行
2、自定义分词器
拼音分词器的问题:分的次都是单个的没有什么用,ru、jia这种没用的,还有就是全部第一个小写,而且我们大多数情况还是用汉字进行分词,而不是拼音,我们要保留汉字分词
这个时候就必须要自定义分词器
要自定义分词器,必须先了解分词器的组成:
- character filters:在tokenizer之前对文本进行处理,例如删除字符、替换字符
- tokenizer:将文本按照一定的规则切割成词条(tern),例如keyword就是不分词
- tokenizer filter:将tokenizer输出的词条做进一步处理,例如大小写转化,同义词处理,拼音处理
所以,我们知道pinyin分词器不会进行分词,那么我们就可以先用ik分词器先分词,再用pinyin分词器做处理,就可以得到pinyin的分词了
但是拼音分词器会对每个字的首字母结合的还有会去中文,这两个我们要优化
我们在创建索引的时候,可以用自定义分词器,但是在搜索的时候,就不能使用这个分词器了
3、completion suggester查询
es提供了completion suggester查询来实现自动补全功能。这个查询会匹配以用户输入内容开头的词条并返回。为了提高补全查询的效率,对文档中字段的类型有一些约束:
参与补全查询的字段必须是completion类型(专门做自动补全查询的类型)
字段的内容一般是用来补全的多个词条形成的数组(右图,如果我们输入的s,那么可以补全这两个数据,但如果我们输入w,没有等多个词条的话就不会补全,所以分多个词条更人性化)
前面是品牌,后面是产品的名称,一个产品的都存在一个数组里
4、案例实战
实现hotel索引库的自动补全、拼音搜索功能
思路:
- 修改hotel索引库结构,设置自定义拼音分词器
- 修改索引库的name、all字段,使用自定义分词器
- 索引库添加一个新字段suggestion,类型为completion类型,使用自定义的分词器
- 给HotelDoc类添加suggestion字段,内容包含brand、business
- 重新导入数据到hotel库
首先,我们先修改索引库的数据结构,要多加一个completion_analyzer分词器,这个分词器是keyword,代表不分词,因为我们参与自动补全的都是一个个的词条,这些词条已经是最小了不需要再分词了,然后再用拼音分词器变成拼音就好了
all的创建索引库用的是自定义的拼音结合的分词器,搜索的分词器就用ik
因为这个suggestion是多个类型的词条组成的数组,所以用list,然后品牌和商圈都可以做自动补全的内容。把想要做自动动补全的都可以加进去。但是这个商圈,business可能有多个是用/分割开的,所以我们要进一步进行拆分
然后加入,现在就可以搜索一下试试了
然后我们就要用java的客户端来操作了
这样就能实现自动补全功能了