ES-基本使用
DSL语法
Elasticsearch提供了基于]SON的DSL (Domain Specific Language)来定义查询。常见的查询类型包括
- 查询所有:查询出所有数据,一般测试用。例如:match all
- 全文检索 (full text)查询: 利用分词器对用户输入内容分词,然后去倒排索引库中匹配。例如:
- match query——搜索一个字段
- multi match_query——可以搜索多个字段
- 精确查询:根据精确词条值查找数据,一般是查找keyword、数值、日期、boolean等类型字段。例如:
- ids
- range
- term
- 地理 (geo)查询:根据经纬度查询。例如:
- geo distance
- geo bounding box
- 复合 (compound)查询:复合查询可以将上述各种查询条件组合起来,合并查询条件。例如
- bool
- function score
查询的基本语法
查询的基本语法如下:
全文查询:
match_query语法如下:
GET _search
{
"query": {
"match": {
"all": "外滩如家"
}
}
}
multi_match语法如下:
GET _search
{
"query": {
"multi_match": {
"query": "外滩如家",
"fields": ["brand","name","bussiness"]
}
}
}
tips:推荐使用match_query方式,因为查询多个字段会浪费效率,建议利用copy_to把多个字段copy到一个字段里去查询
精确查询
精确查询一般是查找keyword、数值、日期、boolean等类型字段。所以不会对搜索条件分词。常见的有:
- term:根据词条精确值查询
- range:根据值的范围查询
trem查询语法如下:
GET _search
{
"query": {
"term": {
"city": {
"value": "上海"
}
}
}
}
range查询语法如下:
GET _search
{
"query": {
"range": {
"price": {
"gte": 10,
"lte": 20
}
}
}
}
tips:gte是大于等于,lte是小于等于,大于是gt,小于是lt
地理查询
根据经纬度查询,例如:
- geo_bounding_box:查询geo_point值落在某个矩形范围内的所有文档
- geodistance:查询到指定中心点小于某个距离值的所有文档
geo_bounding_box语法如下:
GET /hotel/_search
{
"query": {
"geo_bounding_box": {
"location": {
"top_left": {}
"lat": 31.1,
"lon": 121.5
},
"bottom_right": {
"lat": 30.9,
"lon": 121.7
}
}
}
}
geodistance语法如下:
GET /hotel/_search
{
"query": {
"geo_distance": {
"distance": "15km".
"location": "31.21,121.5"
}
}
}
复合查询
复合(compound)查询: 复合查询可以将其它简单查询组合起来,实现更复杂的搜索逻辑,例如:
- fuction score: 算分函数查询,可以控制文档相关性算分,控制文档排名。例如百度竞价
- Boolean Query: 布尔查询
Function score query的语法如下:
Boolean Query
布尔查询是一个或多个查询子句的组合。子查询的组合方式有:
- must:必须匹配每个子查询,类似“与'
- should:选择性匹配子查询,类似“或
- must_not:必须不匹配,不参与算分,类似“非”
- filter:必须匹配,不参与算分
小练习:利用bool查询实现功能
需求:搜索名字包含“如家”,价格不高于400,在坐标31.21,121.5周围10km范围内的酒店。
GET /hotel/_search
{
"query": {
"bool": {
"must": [
{"term":{"name": "如家"}}
],
"must_not": [
{"range":{"price":{"gt":400}}}
],
"filter": [
{"geo_distance": {
"distance": 10,
"distance_unit": "km",
"location": {"lat": 31.21,"lon": 121.5}
}}
]
}
}
}
搜索结果处理
elasticsearch支持对搜索结果排序,默认是根据相关度算分( score) 来排序。可以排序字段类型有: keyword类型
数值类型、地理坐标类型、日期类型等。
普通类型排序语法格式:
经纬度类型排序语法格式:
小练习:对酒店数据按照用户评价降序排序,评价相同按照价格升序排
GET /hotel/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"score": {
"order": "desc"
},
"price": {
"order": "asc"
}
}
]
}
小练习:实现对酒店数据按照到你的位置坐标的距离升序排序
获取经纬度的方式:https://lbsamap.com/demo/isapi-v2/example/map/click-to-get-lnglat/
#找到121.612282,31.034661周围的酒店,距离升序排序
GET /hotel/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"_geo_distance": {
"location": {
"lat": 31.034661,
"lon": 121.612282
},
"order": "asc",
"unit": "km"
}
}
]
}
分页
es中有三种方式实现分页查询,如下:
- from + size:
优点:支持随机翻页
缺点:深度分页问题,默认查询上限 (from+size)是10000场景:百度、京东、谷歌、淘宝这样的随机翻页搜索
- after search:
优点:没有查询上限(单次查询的size不超过10000)
缺点:只能向后逐页查询,不支持随机翻页场景:没有随机翻页需求的搜索,例如手机向下滚动翻页
- scroll:
优点:没有查询上限(单次查询的size不超过10000)
缺点:会有额外内存消耗,并且搜索结果是非实时的场景:海 量数据的获取和迁移。不推荐。
from+size模式
elasticsearch 默认情况下只返回top10的数据。而如果要查询更多数据就需要修改分页参数了。
elasticsearch中通过修改from、size参数来控制要返回的分页结果
语法格式如下:
GET /hotel/_search
{
"query": {
"match_all": {}
},
"from": 990,//分页开始的数据
"size": 10,//期望获取的文档总数
"sort": [
{"price": "asc"}
]
}
因为es底层采用的是倒排索引,所以其实是不利于做分页查询的,所以它这里采用的是逻辑分页
单点时,比如要查询990到1000的数据,那么就需要查询出前1000条,然后截取后面10条数据
但是如果在集群中,那么这种方式就不适用了,集群模式请看下面:
注意:search after有一个缺点,就是分页的时候只能向后查,不能查前面的页
高亮
高亮:就是在搜索结果中把搜索关键字突出。
显示原理是这样的:
- 将搜索结果中的关键字用标签标记出来
- 在页面中给标签添加Css样式
语法如下:
tips:默认情况下,ES搜索字段必须要和高亮字段一致才能显示高亮,如果想要不一致,可以再"pre_tags"配置标签前添加"request_fileId_match:"fasle"
RestClient查询文档
快速入门
match_all的API如下:
对响应的结果进行解析
match和multiMatch的API
boolean,must、filter的API:
排序和分页的API
CSDN-Ada助手: MySQL入门 技能树或许可以帮到你:https://edu.csdn.net/skill/mysql?utm_source=AI_act_mysql
ha_lydms: 文章干货满满!作者在阐述每个知识点时,都力求详尽且清晰,使得读者可以轻松理解并掌握。
CSDN-Ada助手: 推荐 MySQL入门 技能树:https://edu.csdn.net/skill/mysql?utm_source=AI_act_mysql
普通网友: 写的很好!我也写了一篇获取【大厂面试真题解析、核心开发学习笔记、最新全套讲解视频、实战项目源码讲义、学习路线简历模板】的文章
CSDN-Ada助手: 恭喜作者第20篇博客《MVCC的实现》发表!您的持续创作精神让人钦佩。建议下一步可以深入探讨MVCC在数据库中的应用场景和优势,或者结合实际案例进行分析,让读者更好地理解和应用MVCC技术。期待您更多的精彩内容,加油!