elasticsearch默认是根据相关度算分(_score)来排序,但是也支持自定义方式对搜索结果排序。
可以排序字段类型有:keyword类型、数值类型、地理坐标类型、日期类型等。
text不可以排序!!!
语法:
- GET /indexName/_search
- {
- "query": {
- "match_all": {}
- },
- "sort": [
- {
- "FIELD": "desc" // 排序字段、排序方式ASC、DESC
- }
- ]
- }
示例:
- # 查询结果处理-排序
- # query 查询语句
- # sort 排序语句
- # 默认是按照相关性算分排序,如果采用其他字段排序,相关性算分则为null
- # price 排序字段名()按照哪个字段排序
- # price后边是排序规则,可以写多个排序规则,这是简写版
- GET /hotel/_search
- {
- "query": {
- "match": {
- "name": "如家"
- }
- },
- "sort": [
- {
- "price": "asc"
- },
- {
- "score":"desc"
- }
- ]
- }
示例:
- # 查询结果处理-排序(距离排序)
- GET /hotel/_search
- {
- "query": {
- "match": {
- "name": "如家"
- }
- },
- "sort": [
- {
- "_geo_distance": {
- "location":"22.602582, 114.123284",
- "order": "asc",
- "unit": "km"
- }
- }
- ]
- }
elasticsearch 默认情况下只返回top10的数据。而如果要查询更多数据就需要修改分页参数了。
elasticsearch中通过修改from、size参数来控制要返回的分页结果:
from:从第几个文档开始
size:总共查询几个文档
分页的基本语法如下:
- GET /hotel/_search
- {
- "query": {
- "match_all": {}
- },
- "from": 0, // 分页开始的位置,默认为0
- "size": 10, // 期望获取的文档总数
- "sort": [
- {"price": "asc"}
- ]
- }
示例:
- # 查询结果处理-分页
- GET /hotel/_search
- {
- "query": {
- "match_all": {}
- },
- "from": 2,
- "size": 2
- }
分页限制问题,需要from + size <= 10000,否则会报错
- # 查询结果处理-分页(分页限制:from+size<=10000)
- GET /hotel/_search
- {
- "query": {
- "match_all": {}
- },
- "from": 10000,
- "size": 2
- }
实际中es是集群部署,假设现在有10个节点,我要查询TOP100条数据,es会把每个节点的TOP100条数据查出来,汇总起来,重新排序,再查出TOP100条数据,这样效率太低,而且汇总数据过多,对内存和CPU会产生非常大的压力,因此elasticsearch会禁止from+ size 超过10000的请求。
针对深度分页,ES提供了两种解决方案,官方文档:
search after:分页时需要排序,原理是从上一次的排序值开始,查询下一页数据。官方推荐使用的方式。
scroll:原理将排序后的文档id形成快照,保存在内存。官方已经不推荐使用。
高亮显示的实现分为两步:
1)给文档中的所有关键字都添加一个标签,例如
标签
2)页面给
标签编写CSS样式
高亮的语法:
- GET /hotel/_search
- {
- "query": {
- "match": {
- "FIELD": "TEXT" // 查询条件,高亮一定要使用全文检索查询
- }
- },
- "highlight": {
- "fields": { // 指定要高亮的字段
- "FIELD": {
- "pre_tags": "", // 用来标记高亮字段的前置标签
- "post_tags": "" // 用来标记高亮字段的后置标签
- }
- }
- }
- }
示例:
- # 查询结果处理-高亮
- # highlight 固定写法
- # fields 固定写法
- # name 在哪个字段中的如家高亮显示
- # require_field_match 如果为false,表示查询时的字段和高亮使用的字段可以不一致
- # es默认的高亮的标签就是,可以不用指定
- GET /hotel/_search
- {
- "query": {
- "match": {
- "name": "如家"
- }
- },
- "highlight": {
- "fields": {
- "name": {
- "require_field_match": "false"
- }
- }
- }
- }
注意:
高亮是对关键字高亮,因此搜索条件必须带有关键字,而不能是范围这样的查询。
默认情况下,高亮的字段,必须与搜索指定的字段一致,否则无法高亮
如果要对非搜索字段高亮,则需要添加一个属性:required_field_match=false