ElasticSearch 底层原理与分组查询(中)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: ElasticSearch 底层原理与分组查询

表现,会变成红色,所以说你的指定的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" 
} 
} 
} 
} 
} 
} 
} 
}


相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
1月前
|
存储 JSON 监控
大数据-167 ELK Elasticsearch 详细介绍 特点 分片 查询
大数据-167 ELK Elasticsearch 详细介绍 特点 分片 查询
52 4
|
1月前
|
自然语言处理 搜索推荐 Java
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(一)
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图
49 0
|
1月前
|
存储 自然语言处理 搜索推荐
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(二)
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(二)
34 0
|
2月前
|
JSON 自然语言处理 算法
ElasticSearch基础2——DSL查询文档,黑马旅游项目查询功能
DSL查询文档、RestClient查询文档、全文检索查询、精准查询、复合查询、地理坐标查询、分页、排序、高亮、黑马旅游案例
ElasticSearch基础2——DSL查询文档,黑马旅游项目查询功能
|
3月前
|
自然语言处理 Java 关系型数据库
ElasticSearch 实现分词全文检索 - 聚合查询 cardinality
ElasticSearch 实现分词全文检索 - 聚合查询 cardinality
119 1
|
4月前
|
存储 自然语言处理 关系型数据库
Elasticsearch 查询时 term、match、match_phrase、match_phrase_prefix 的区别
【7月更文挑战第3天】Elasticsearch 查询时 term、match、match_phrase、match_phrase_prefix 的区别
|
4月前
|
存储 数据库 索引
面试题ES问题之动态映射的定义如何解决
面试题ES问题之动态映射的定义如何解决
37 1
|
4月前
|
存储 数据采集 数据处理
数据处理神器Elasticsearch_Pipeline:原理、配置与实战指南
数据处理神器Elasticsearch_Pipeline:原理、配置与实战指南
175 12
|
3月前
|
存储 自然语言处理 Java
ElasticSearch 实现分词全文检索 - 经纬度定位商家距离查询
ElasticSearch 实现分词全文检索 - 经纬度定位商家距离查询
30 0
|
3月前
|
自然语言处理 Java
ElasticSearch 实现分词全文检索 - 高亮查询
ElasticSearch 实现分词全文检索 - 高亮查询
64 0