写在前面
es搜索返回结果的排序默认是按照得分的高低来排的,本文来看下如何按照字段来排序,实现类似于MySQL的order by xxx
的效果。
1:什么是fileddata和doc_value
参考ElasticSearch之零碎知识点 和一文带你彻底弄懂ES中的doc_values和fielddata 。
2:实例
测试数据参考这篇文章 。
- 先来看日期字段排序的查询:
POST kibana_sample_data_ecommerce/_search
{"size": 5,"query": {"match_all": {}},"sort": [{"order_date": {"order": "desc"}}]
}
可以正常查询,但是注意此时因为不需要根据算分来排序,所以是就没有计算得分了。
- 看下多字段排序
POST kibana_sample_data_ecommerce/_search
{"size": 5,"query": {"match_all": {}},"sort": [{"order_date": {"order": "desc"},"_doc": {"order": "asc"},"_score": {"order": "desc"}}]
}
_doc 是按照文档的索引顺序排序。
_score是按照得分来排序,因此此时就要计算得分了。
- 基于text字段的排序
POST kibana_sample_data_ecommerce/_search
{"size": 5,"query": {"match_all": {}},"sort": [{"customer_full_name": {"order": "desc"}}]
}
报错了,这是因为text字段类型默认是关闭fielddata的,因此想要对text类型使用排序,需要显式的在mapping中打开。
上述,日期不报错,是因为日期是默认打开doc_values的,因为在实际业务中我们按照日期排序的场景很多,类似的整形也是打开doc_values的。但text类型因为数据结构本身的限制,所以是不支持doc_values的,所以只能通过打开fielddata来完成排序需求。
- 打开text的fielddata
PUT kibana_sample_data_ecommerce/_mapping
{"properties": {"customer_full_name": {"type": "text","fielddata": true,"fields": {"keyword": {"type": "keyword","ignore_above": 256}}}}
}
在执行上述的查询就正常了:
- 最佳实践
在业务中,如果是确定不需要的字段可以显式的关闭doc_values和fielddata。减少索引的速度,以及jvm heap和磁盘空间的占用。
写在后面
参考文章列表
ElasticSearch之零碎知识点 。