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可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
2月前
|
存储 搜索推荐 数据挖掘
ElasticSearch架构介绍及原理解析
ElasticSearch架构介绍及原理解析
120 0
|
3月前
|
存储 固态存储 Java
Elasticsearch中查询性能优化
Elasticsearch中查询性能优化
198 0
|
4月前
Elasticsearch之RestClient查询文档
Elasticsearch之RestClient查询文档
139 1
|
4月前
|
自然语言处理 API 索引
Elasticsearch Analyzer原理分析并实现中文分词
Elasticsearch Analyzer原理分析并实现中文分词
74 0
|
1天前
|
存储 SQL 运维
Elasticsearch 查询革新:探索 Wildcard 类型的高效模糊匹配策略
Elasticsearch 查询革新:探索 Wildcard 类型的高效模糊匹配策略
14 0
|
1天前
|
运维 测试技术 数据处理
Elasticsearch 优化查询中获取字段内容的方式,性能提升5倍!
Elasticsearch 优化查询中获取字段内容的方式,性能提升5倍!
11 0
|
1天前
|
存储 缓存 Java
Elasticsearch 8.X 聚合查询下的精度问题及其解决方案
Elasticsearch 8.X 聚合查询下的精度问题及其解决方案
8 0
|
1天前
|
搜索推荐 算法 数据挖掘
探索 Elasticsearch 8.X Terms Set 检索的应用与原理
探索 Elasticsearch 8.X Terms Set 检索的应用与原理
7 0
|
13天前
|
自然语言处理 Java 索引
SpringBoot 实现 elasticsearch 查询操作(RestHighLevelClient 的案例实战)
SpringBoot 实现 elasticsearch 查询操作(RestHighLevelClient 的案例实战)
17 1
|
25天前
|
监控 搜索推荐 安全
面经:Elasticsearch全文搜索引擎原理与实战
【4月更文挑战第10天】本文是关于Elasticsearch面试准备的博客,重点讨论了四个核心主题:Elasticsearch的分布式架构和数据模型、CRUD操作与查询DSL、集群管理与性能优化,以及安全与插件扩展。文中通过代码示例介绍了如何进行文档操作、查询以及集群管理,并强调理解Elasticsearch的底层原理和优化策略对面试和实际工作的重要性。
32 6

热门文章

最新文章