Elasticsearch搜索操作
示例数据
# 创建mapping
PUT /hotel
{"mappings": {"properties": {"title": {"type": "text"},"city": {"type": "keyword"},"price": {"type": "double"},"create_time": {"type": "date","format": "yyyy-MM-dd HH:mm:ss"},"amenities": {"type": "text"},"full_room": {"type": "boolean"},"location": {"type": "geo_point"},"praise": {"type": "integer"}}}
}# 导入数据
POST /_bulk
{"index": {"_index": "hotel","_id":"001"}}
{"title": "文雅酒店", "city": "青岛", "price": 556.00, "create_time": "2020-04-18 12:00:00", "amenities": "浴池,普通停车场/充电停车场", "full_room": false, "location": {"lat": 36.083078, "lon": 120.37566},"praise": 10}
{"index": {"_index": "hotel","_id":"002"}}
{"title": "金都嘉怡假日酒店", "city": "北京", "price": 337.00, "create_time": "2021-03-15 20:00:00", "amenities": "wifi,充电停车场/可升降停车场", "full_room": false, "location": {"lat": 39.915153, "lon": 116.4030},"praise": 60}
{"index": {"_index": "hotel","_id":"003"}}
{"title": "金都欣欣酒店", "city": "天津", "price": 200.00, "create_time": "2021-05-09 16:00:00", "amenities": "提供假日part,免费早餐,可充电停车场", "full_room": true, "location": {"lat": 39.186555, "lon": 117.162007},"praise": 30}
{"index": {"_index": "hotel","_id":"004"}}
{"title": "金都酒店", "city": "北京", "price": 500.00, "create_time": "2021-02-18 08:00:00", "amenities": "浴池(假日需预定),室内游泳池,普通停车场", "full_room": true, "location": {"lat": 39.915343, "lon": 116.4239},"praise": 20}
{"index": {"_index": "hotel","_id":"005"}}
{"title": "文雅精选酒店", "city": "北京", "price": 800.00, "create_time": "2021-01-01 08:00:00", "amenities": "浴池(假日需预定),wifi,普通停车场", "full_room": true, "location": {"lat": 39.918229, "lon": 116.422011},"praise": 20}
{"index": {"_index": "hotel","_id":"006"}}
{"title": "完美商务酒店", "city": "东莞", "price": 190.00, "create_time": "2022-04-15 17:24:00", "amenities": "无早餐,wifi,普通停车场", "full_room": false, "location": {"lat": 23.014747, "lon": 113.770511},"praise": 80}
搜索辅助功能
指定返回的字段
_source
子句可以设定返回结果的字段。
# 示例
GET /${index_name}/_search
{"_source": ["${field}","${field}"] # 仅返回指定字段
}
结果计数
_count
API可以对返回的数据进行数量统计。
# 返回整个索引的文档数
GET /${index_name}/_count# 返回过滤后的文档数
GET /${index_name}/_count
{"query": {"term": {"${field}": {"value": "${value}"}}}
}
结果分页
在默认情况下,ES返回前10个搜索匹配的文档。可以通过设置from和size来定义搜索位置和每页显示的文档数量,from表示查询结果的起始下标,默认值为0,size表示从起始下标开始返回的文档个数,默认值为10。
分页的缺点:当用户查询第n页的时候,实际上es是把前n页的数据全部找出来,再去除前n-1页最后得到需要的数据返回,查最后一页就相当于全扫描。
# 返回20个结果
GET /${index_name}/_search
{"from": 0,"size": 20
}
在默认情况下,用户最多可以取得10000个文档,超过这个值会报错。可以修改max_result_window
的值来调整最大限制。
PUT /${index_name}/_settings{"index": {"max_result_window": 20000 # 设置最大限制为20000}}
滚动查询
scroll
适合那种需要一次性或分批拉出大量数据做离线处理、迁移等。
# 语法
GET /${index_name}/_search?scroll=${time} # time指的是数据保留时间,最大不超过1d,也就是24h
{"size": ${num}
}# 示例
GET /hotel12/_search?scroll=1m # 查询10条数据,保留1分钟
{"size": 10
} # 上述命令会返回一个scroll_id,用scroll_id继续查询即可获取后续数据,无需指定索引,因为scroll_id是唯一的
# 重复请求以下api,最后会将全部数据取出
GET /_search/scroll
{"scroll":"1m","scroll_id":"DnF1ZXJ5VGhlbkZldGNoBAAAAAAABPP1FmRFSU9NM1VNU2JxNG9UUlNnSmpXMVEAAAAAAL7OTxYxT0dJOVJVMVFxU2I0N2xCR2IyVzJnAAAAAAC-j70WVVlOZkxQRzJRLXlMRlVMbEQtalBfUQAAAAAAyWm-Fk9HdGx1b3VsUXRLZHV4c1E1OExja0E="
}
性能分析
ES提供了profile功能,该功能详细地列出了搜索时每一个步骤的耗时,可以帮助用户对DSL的性能进行剖析。
# 开启profile功能
GET /${index_name}/_search
{"profile": true,"query": {"match": {"${field}": "${value}"}}
}
评分分析
如果用户不指定按照某个字段进行升序或者降序排列,那么ES会使用打分算法计算的分数对文档进行排序。
ES提供了explain功能来帮助使用者查看搜索时的匹配详情。
# explain使用示例
GET /${index_name}/_explain/${_id}
{"query": {"match": {"${field}": "${value}"}}
}
搜索匹配功能
查询所有文档
使用match_all
查询文档时,ES不对文档进行打分计算,默认情况下给每个文档赋予1.0的得分。用户可以通过boost参数设定该分值。
# match_all默认也只会返回10条数据
GET /${index_name}/_search
{"query": {"match_all": {"boost": ${num} # 设置文档的分值}}
}
关键字别查询
term查询
term
查询是结构化精准查询的主要查询方式,用于查询待查字段和查询值是否完全匹配。
# 语法
GET /${index_name}/_search
{"query": {"term": {"${field}": {"value": "${value}"}}}
}
terms查询
terms
查询是term查询的扩展形式,用于查询一个或多个值与待查字段是否完全匹配。
GET /${index_name}/_search
{"query": {"terms": {"${field}": [ # 指定查询字段"${value1}", # 指定查询值,多个值之间用逗号分隔"${value2}","${value3}",...]}}
}
range查询
range
查询用于范围查询,一般是对数值型和日期型数据的查询。
范围比较符:
- gt:大于
- lt:小于
- gte:大于或等于
- lte:小于或等于
# 语法
GET /${index_name}/_search
{"query": {"range": {"${field}": {"${范围比较符}": "${value}"}}}
}# 示例:酒店价格在300-500之间
GET /hotel/_search
{"query": {"range": {"price": {"gte": "300","lte": "500"}}}
}
注意,使用range查询时,查询值必须符合该字段在mappings中设置的规范。意思是不能拿字符串去搜数字类型的范围,会报错。
exists查询
使用exists
搜索可以找到某个字段不为空的文档。
字段不为空的条件有:
- 值存在且不是null
- 值不是空数组
- 值是数组,但不是[null]
字段为空的条件有:
- 值是
null
- 值是
[]
(空数组) - 值是
[null]
,元素为null的数组
GET /${index_name}/_search
{"query": {"exists": {"field": "${field}"}}
}
布尔查询
must查询
当查询中包含must
查询时,表示当前查询为逻辑查询中的“与”查询,被命中的文档必须匹配该查询中的多个子查询结果。
# 语法
GET /${index_name}/_search
{"query": {"bool": {"must": [ # 可以包含多个[关键字级别查询](https://www.wolai.com/oY96bxtB5oQV9ZvaZfb9Eg#9v5dJHAJNQhHjef65M5wWa)和[布尔查询](https://www.wolai.com/oY96bxtB5oQV9ZvaZfb9Eg#pM18FZBFcZkW4wrb7ZVJJH){# term查询},{# range查询或exists查询}]}}
}# 示例:查询北京价格在350-500之间的酒店
GET /hotel/_search
{"query": {"bool": {"must": [{"term": {"city": {"value": "北京"}}},{"range": {"price": {"gte": 350,"lte": 500}}}]}}
}
should查询
当查询中包含should
查询时,表示当前查询为逻辑查询中的“或”查询。被命中的文档可以匹配该查询中的一个或多个子查询结果。
# 语法
GET /${index_name}/_search
{"query": {"bool": {"should": [ # 可以包含多个[term级别查询](https://www.wolai.com/oY96bxtB5oQV9ZvaZfb9Eg#9v5dJHAJNQhHjef65M5wWa)和布尔查询{# term查询},{# range查询或exists查询}]}}
}# 示例:查询北京或者天津的酒店
GET /hotel/_search
{"query": {"bool": {"should": [{"term": {"city": {"value": "北京"}}},{"term": {"city": {"value": "天津"}}}]}}
}
must_not查询
当查询中包含must_not
查询时,表示当前查询为逻辑查询中的“非”查询,被命中的文档必须不匹配该查询中的多个子查询结果。
# 语法
GET /${index_name}/_search
{"query": {"bool": {"must_not": [ # 可以包含多个term级别查询和布尔查询{# term查询},{# range查询或exists查询}]}}
}# 示例:查询不是北京或者天津的酒店
GET /hotel/_search
{"query": {"bool": {"must_not": [{"term": {"city": {"value": "北京"}}},{"term": {"city": {"value": "天津"}}}]}}
}
filter查询
filter查询即过滤查询,排除不匹配的文档。
区别:
- 其他布尔查询关注的是查询条件和文档的匹配程度,并按照匹配程度进行打分;
- 而filter查询关注的是查询条件和文档是否匹配,不打分,但是会对部分匹配结果进行缓存。
# 语法
GET /${index_name}/_search
{"query": {"bool": {"filter": [ # 可以包含多个term级别查询和布尔查询{# term查询},{# range查询或exists查询}]}}
}# 示例:查询北京不满房的酒店
GET /hotel/_search
{"query": {"bool": {"filter": [{"term": {"city": {"value": "北京"}}},{"term": {"full_room": false}}]}}
}
Constant Score查询
Constant Score
查询可以过滤出某个文本字段是否包含某个词,但是会忽略TF(Term Frequency,检索词频率),也就是会忽略搜索关键字在文档中的次数。
# 语法
GET /${index_name}/_search
{"query": {"constant_score": {"filter": {# 可以加各种搜索方式,如term、match、bool等}}}
}# 示例:查询amenities字段包含关键词“停车场”的酒店
GET /hotel/_search
{"_source": ["amenities"],"query": {"constant_score": {"filter": {"match": {"amenities": "停车场"}}}}
} # 输出结果中,无论“停车场”出现几次,分数都是1,boost可以修改分数
Function Score查询
Function Score
查询通过函数来控制文档的相关度,从而影响排序结果。
# 语法
GET /${index_name}/_search
{"query": {"function_score": {"query": {},"functions": [{}]}}
}# 示例
GET /hotel/_search
{"_source": ["title","city"], "query": {"function_score": {"query": { # 查询语句为term查询"term": {"city": {"value": "北京"}}},"functions": [ # 使用随机分数函数{"random_score": {} }],"score_mode": "sum" # 最终分数设置为各个函数结果的总和}}
}
全文搜索
全文搜索首先对查询词进行分析,然后根据查询词的分词结果构建查询。
match查询
match
查询只要分词中的一个或者多个在文档中存在即可。
# 语法
GET /${index_name}/_search
{"query": {"match": {"${field}": "${value}"}}
}# 示例:默认分词器会拆分成“金”“都”“酒”“店”,因此,只要文档中包含这4个字中的任何一个字,都会被搜索到
GET /hotel/_search
{"_source": ["title"],"query": {"match": {"title": "金都酒店"}}
}
multi_match查询
multi_match
查询可以在多个字段中查询关键词。
# 语法
GET /${index_name}/_search
{"query": {"multi_match": {"query": "${value}","fields": ["${field}",...]}}
}# 示例
GET /hotel/_search
{"_source": ["title","amenities"], "query": {"multi_match": {"query": "假日","fields": ["title","amenities"]}}
}
match_phrase查询
match_phrase
用于搜索确切的短语或邻近的词语。
# 语法
GET /${index_name}/_search
{"query": {"match_phrase": {"${field}": "${value}"}}
}# 示例
GET /hotel/_search
{"query": {"match_phrase": {"title": "文雅酒店"}}
} # 只会在示例数据中匹配”文雅酒店“,不会匹配”文雅精选酒店“
基于地理位置查询
对于geo_point
字段类型的查询方式有3种,分别为geo_distance
查询、geo_bounding_box
查询和geo_polygon
。
geo_distance查询
geo_distance
查询方式需要用户指定一个坐标点,在指定距离该点的范围后,ES即可查询到相应的文档。
GET /hotel/_search
{"_source": ["title","city","location"], "query": {"geo_distance": {"distance": "5km", # 指定范围为5km"location": { # 设置指定坐标点的纬度、精度"lat": "39.915143","lon": "116.4039"}}}
}
搜索建议
搜索建议:即在用户输入搜索关键词的过程中系统进行自动补全。
当字段的类型定义为completion
时,才可以使用Completion Suggester
提供的搜索建议功能。
GET /hotel_sug/_search
{"suggest": {"hotel_zh_sug": { # 定义搜索建议的名称"prefix": "如家", # 设置搜索建议的前缀"completion": { # 设置搜索建议对应的字段"field": "query_word"}}}
}
排序功能
在默认情况下,ES对搜索结果是按照相关性降序排序的。
ES提供了sort
子句可以对数据进行排序。使用sort子句一般是按照字段信息进行排序,不受相关性影响,而且打分步骤需要耗费一定的硬件资源和时间,因此默认情况下,不对文档进行打分。
按普通字段值排序
sort默认是升序,即asc,可通过order字段设置为降序,即desc。
# 语法
GET /${index_name}/_search
{"sort": [{"${field}": {"order": "desc" # 设置为降序排列}}]
}# 示例
GET /hotel/_search
{"_source": ["title","price"],"query": {"match": {"title": "金都"}},"sort": [ # sort是个数组,可以按照多个字段进行排序{"price": {"order": "desc"}}]
}
按地理距离排序
GET /hotel/_search
{"_source": ["title","city","location"],"query": {"geo_distance": {"distance": "5km", # 查询的地理范围"location": { # 设置的中心点坐标"lat": "39.915143","lon": "116.4039"}}},"sort": [{"_geo_distance": {"location": { # 设置排序的中心点坐标"lat": "39.915143","lon": "116.4039"},"order": "asc", # 距离由近到远"unit": "km", # 排序所使用的距离单位"distance_type": "plane" # 排序所使用的距离算法,默认算法是arc(精准但是耗时长),plane则相反}}]
}
Elasticsearch搜索操作相关推荐
- elasticsearch实战三部曲之三:搜索操作
elasticsearch实战三部曲之三:搜索操作 2019年01月13日 21:35:18 博陵精骑 阅读数:1367 标签: elasticsearch 更多 个人分类: elasticsearc ...
- ElasticSearch搜索详细讲解与操作
全文检索基础 全文检索流程 流程: #mermaid-svg-7Eg2qFEl06PIEAxZ {font-family:"trebuchet ms",verdana,arial, ...
- kotlin + springboot启用elasticsearch搜索
参考自: http://how2j.cn/k/search-engine/search-engine-springboot/1791.html?p=78908 工具版本: elasticsearch ...
- ElasticSearch搜索底层基础原理总结
目录: 1._search结果分析 2.multi-index和multi-type 3.分页查询与deep paging 4.query DSL和query string 5.mapping 6.倒 ...
- 分布式搜索elasticsearch搜索功能【深入】
elasticsearch搜索功能[深入] 分布式搜索elasticsearch搜索功能[深入] 1.数据聚合 1.1 聚合的种类 1.2 DSL实现聚合 1.2.1 Bucket聚合 1.2.2 M ...
- ElasticSearch(搜索服务器)-第一天
1为什么使用es ElasticSearch 搜索服务器.简称es. 初识es 搜索时数据库的问题 2.1是什么 搜索服务器 软件 2.1.1互联网搜索 https://www.baidu.com/ ...
- Elasticsearch 搜索测试与集成Springboot3
Elasticsearch是专门做搜索的,它非常擅长以下方面的问题 Elasticsearch对模糊搜索非常擅长(搜索速度很快) 从Elasticsearch搜索到的数据可以根据评分过滤掉大部分的,只 ...
- 详细描述一下Elasticsearch搜索的过程
详细描述一下Elasticsearch搜索的过程 我们都知道es是一个分布式的存储和检索系统,在存储的时候默认是根据每条记录的_id字段做路由分发的,这意味着es服务端是准确知道每个document分 ...
- 基于octree的空间划分及搜索操作
(1) octree是一种用于管理稀疏3D数据的树形数据结构,每个内部节点都正好有八个子节点,介绍如何用octree在点云数据中进行空间划分及近邻搜索,实现"体素内近邻搜索(Neighbo ...
最新文章
- Skin设计小组新作品发布—CornflowerBlue
- 页面左边导航固定,右边自适应宽度
- PHP学习记录(字符串函数)
- python udp数据报
- QML从右到左的用户界面
- 在我看来,代码审查就是在排大便...
- 四川大学计算机专业调剂,2019四川大学计算机学院考研调剂信息(第二批)
- Android音视频开发之ExoPlayer(二):播放列表常用的功能
- 状态码406解决方式
- 单词前缀dia/dis/duo/en/epi/eu等衍生单词(辅助记忆)
- kafka auto.offset.reset / latest / earliest 详解
- FTP显示文件的修改时间与实际时间不一致
- Redis 在windows中启动
- 用Google搜索本地硬盘
- 彻底清除已删除的文件
- 【Android开发】 获取手机上的各种apk的包名和类名,实现跳转到其他应用
- 【文献笔记】【部分精读】【CIR】Angle of Arrival Estimation based on Channel Impulse Response Measurements
- 中国广电网络股份有限公司46位股东出资情况大揭秘!
- iOS 利用宏判断系统版本
- 系统架构设计笔记(59)—— 嵌入式系统的组成
热门文章
- javaweb项目图书借阅管理系统设计与实现(有文档+调试视频教程+项目源码).rar
- 云计算机能不能玩游戏,云电脑有哪些?可不可以拿来玩steam游戏?
- 知乎问 想找一个linux培训机构,目前看千峰、黑马、达内 北大青鸟等机构,请问哪个好一点?
- 使用Navicat 连接oracle “ORA-03135: Connection Lost Contact”
- python计算学生平均年龄_不能理解平均年龄的计算
- Android 适配暗黑模式
- 智美2.0 文字格式化
- html中如何实现a标签的点击事件
- Java+OpenCV实现图片中的人脸识别
- 【python】秀人集-写真集-爬虫-2.0