表现,会变成红色,所以说你的指定的field中,如果包含了那个搜索词的话,就会在 那个field的文本中,对搜索词进行红色的高亮显示
GET /news_website/_doc/_search { "query": { "bool": { "should": [ { "match": { "title": "文章" } }, { "match": { "content": "文章" } } ] } }, "highlight": { "fields": { "title": {}, "content": {} } } }
highlight中的field,必须跟query中的field一一对齐的
2、常用的highlight介绍 plain highlight,lucene highlight,默认 posting highlight,index_options=offsets
(1)性能比plain highlight要高,因为不需要重新对高亮文本进行分词
(2)对磁盘的消耗更少
DELETE news_website PUT /news_website { "mappings": { "properties": { "title": { "type": "text", "analyzer": "ik_max_word" }, "content": { "type": "text", "analyzer": "ik_max_word", "index_options": "offsets" } } } } PUT /news_website/_doc/1 { "title": "我的第一篇文章", "content": "大家好,这是我写的第一篇文章,特别喜欢这个文章门户网站!!!" } GET /news_website/_doc/_search { "query": { "match": { "content": "文章" } }, "highlight": { "fields": { "content": {} } } }
fast vector highlight
index‐time term vector设置在mapping中,就会用fast verctor highlight
(1)对大field而言(大于1mb),性能更高
DELETE /news_website PUT /news_website { "mappings": { "properties": { "title": { "type": "text", "analyzer": "ik_max_word" }, "content": { "type": "text", "analyzer": "ik_max_word", "term_vector" : "with_positions_offsets" } } } }
强制使用某种highlighter,比如对于开启了term vector的field而言,可以强制使用plain hlight
GET /news_website/_doc/_search { "query": { "match": { "content": "文章" } }, "highlight": { "fields": { "content": { "type": "plain" } } } }
总结一下,其实可以根据你的实际情况去考虑,一般情况下,用plain highlight也就足够了, 不需要做其他额外的设置 如果对高亮的性能要求很高,可以尝试启用posting highlight 如果field的值特别大,超过了1M,那么可以用fast vector highlight
3、设置高亮html标签,默认是<em>
标签
GET /news_website/_doc/_search { "query": { "match": { "content": "文章" } }, "highlight": { "pre_tags": ["<span color='red'>"], "post_tags": ["</span>"], "fields": { "content": { "type": "plain" } } } }
4、高亮片段fragment的设置
GET /news_website/_doc/_search { "query" : { "match": { "content": "文章" } } , "highlight" : { "fields" : { "content" : {"fragment_size" : 150, "number_of_fragments" : 3 } } } }
fragment_size: 你一个Field的值,比如有长度是1万,但是你不可能在页面上显示这么长啊。。。设置要显示出来的fragment文本判断的长度,默认是100
number_of_fragments:你可能你的高亮的fragment文本片段有多个片段,你可以指定就显示几个片段
四、 聚合搜索技术深入
bucket 和 metric 概念简介
bucket就是一个聚合搜索时的数据分组。如:销售部门有员工张三和李四,开发部门有员工王五和赵六。那么根据部门分组聚合得到结果就是两个bucket。销售部门 bucket中有张三和李四, 开发部门 bucket中有王五和赵六。
metric就是对一个bucket数据执行的统计分析。如上述案例中,开发部门有2个员工,销售部门有2个员工,这就是metric。metric有多种统计,如:求和,最大值,最小值,平均值等。
1 用一个大家容易理解的SQL语法来解释,如:select count() from table group by colum n。那么group by column分组后的每组数据就是bucket。对每个分组执行的count()就是metric。
2.准备案例数据
DELETE /cars PUT /cars { "mappings": { "properties": { "price": { "type": "long" }, "color": { "type": "keyword" }, "brand": { "type": "keyword" }, "model": { "type": "keyword" }, "sold_date": { "type": "date", "format": ["yyyy-MM-dd"] }, "remark" : { "type" : "text", "analyzer" : "ik_max_word" } } } }
批量写入数据,注意日期格式
GET /cars/_doc/_search { "query": { "match_all": {} } } POST /cars/_bulk {"index":{}} { "price" : 258000, "color" : "金色", "brand":"大众", "model" : "大众迈腾", "sold_date" : "2015-01-11","remark" : "大众中档车" } {"index":{}} { "price" : 123000, "color" : "金色", "brand":"大众", "model" : "大众速腾", "sold_date" : "2015-02-11","remark" : "大众神车" } {"index":{}} { "price" : 239800, "color" : "白色", "brand":"标志", "model" : "标志508", "sold_date" : "2015-03-11","remark" : "标志品牌全球上市车型" } {"index":{}} { "price" : 148800, "color" : "白色", "brand":"标志", "model" : "标志408", "sold_date" : "2015-04-11","remark" : "比较大的紧凑型车" } {"index":{}} { "price" : 1998000, "color" : "黑色", "barand":"大众", "model" : "大众辉腾", "sold_date" : "2015-05-11","remark" : "大众最让人肝疼的车" } {"index":{}} { "price" : 218000, "color" : "红色", "brand":"奥迪", "model" : "奥迪A4", "sold_date" :"2015-06-11","remark" : "小资车型" } {"index":{}} { "price" : 489000, "color" : "黑色", "brand":"奥迪", "model" : "奥迪A6", "sold_date" : "2015-07-11","remark" : "政府专用?" } {"index":{}} { "price" : 1899000, "color" : "黑色", "brand":"奥迪", "model" : "奥迪A 8", "so ld_date" : "2021-10-11" ,"remark" : "很贵的大A6。。。" }
1、根据color分组统计销售数量
只执行聚合分组,不做复杂的聚合统计。在ES中最基础的聚合为terms,相当于SQL中的count。
在ES中默认为分组数据做排序,使用的是doc_count数据执行降序排列。可以使用
_key元数据,根据分组后的字段数据执行不同的排序方案,也可以根据_count元数
据,根据分组后的统计值执行不同的排序方案。
GET /cars/_search { "size" : 8, # 显示数据条数 "aggs": { "group_by_color": { "terms": { "field": "color", "order": { "_count": "desc" } } } } }
2、统计不同color车辆的平均价格
本案例先根据color执行聚合分组,在此分组的基础上,对组内数据执行聚合统计,这个组内数据的聚合统计就是metric。同样可以执行排序,因为组内有聚合统计,且对统计数据给予了命名avg_by_price,所以可以根据这个聚合统计数据字段名执行排序逻辑。
场景:下钻分析
GET /cars/_search { "aggs": { "group_by_color": { "terms": { "field": "color", "order": { "avg_by_price": "asc" } }, "aggs": { "avg_by_price": { "avg": { "field": "price" } } } } } }
size可以设置为0,表示不返回ES中的文档,只返回ES聚合之后的数据,提高查询速度,当然如果你需要这些文档的话,也可以按照实际情况进行设置
GET /cars/_search { "size" : 0, "aggs": { "group_by_color": { "terms": { "field": "color" }, "aggs": { "group_by_brand" : { "terms": { "field": "brand", "order": { "avg_by_price": "desc" } }, "aggs": {18 "avg_by_price": { "avg": { "field": "price" } } } } } } } }
3、统计不同 color 不同 brand 中车辆的平均价格
先根据color聚合分组,在组内根据brand再次聚合分组,这种操作可以称为下钻
分析。
Aggs如果定义比较多,则会感觉语法格式混乱,aggs语法格式,有一个相对固定
的结构,简单定义:aggs可以嵌套定义,可以水平定义。
嵌套定义称为下钻分析。水平定义就是平铺多个分组方式。
# 语法 GET /index_name/type_name/_search { "aggs" : { "定义分组名称(最外层)": { "分组策略如:terms、avg、sum" : { "field" : "根据哪一个字段分组", "其他参数" : "" }, "aggs" : { "分组名称1" : {}, "分组名称2" : {} } } } } # 实践案例 GET /cars/_search { "aggs": { "group_by_color": { "terms": { "field": "color", "order": { "avg_by_price_color": "asc" } }, "aggs": { "avg_by_price_color" : { "avg": { "field": "price" } }, "group_by_brand" : { "terms": { "field": "brand", "order": { "avg_by_price_brand": "desc" } }, "aggs": { "avg_by_price_brand": { "avg": { "field": "price" } } } } } } } }