排序
- 默认情况下,ElasticSearch 会根据算分进行排序;
- 可以使用 sort API 指定排序的规则
排序 | sort API | 举几个栗子
根据单字段排序
- 使用了 sort API 之后,_score 的值就会变成 null;
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"}}
]
}
对 text 类型的字段排序
- 报错,需要开启 fielddata;
POST /kibana_sample_data_ecommerce/_search
{
"size": 5,
"query": {
"match_all": {
}
},
"sort": [
{"customer_full_name": {"order": "desc"}}
]
}
- 开启字段的 fielddata 就不报错了,可以随时打开,但是不建议打开,对全文本(text 类型)排序本身也没有很大的意义,只有在做一些 Aggregation 的时候,才把 fielddata 打开;
PUT kibana_sample_data_ecommerce/_mapping
{
"properties": {
"customer_full_name" : {
"type" : "text",
"fielddata": true,
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
排序的过程
- 排序是针对字段原始内容进行的,倒排索引无法发挥作用;
- 需要用到正排索引,通过文档 id 和字段快速得到字段原始内容;
ElasticSearch 中两种实现排序的方式
- Fielddata
- Doc Valus(一种列式存储,对 Text 类型无效)
Doc Values vs Fielddata
Doc Values | Field Data | |
---|---|---|
何时创建 | 索引时,和倒排索引一起创建 | 搜索时动态创建 |
创建位置 | 磁盘文件 | JVM Heap |
优点 | 避免大量内存占用 | 索引速度快,不占用额外的磁盘空间 |
缺点 | 降低索引速度,占用额外磁盘空间 | 文档过多时,动态创建开销大,占用过多 JVM Heap |
ES 默认采用 | ES 2.x 之后 | ES 1.x 及以前 |
关闭 Doc Values
ElasticSearch 2.x 开始默认的排序方式是 Doc Values,可以关掉;如果重新打开,需要重建索引;
PUT test_keyword
PUT test_keyword/_mapping
{
"properties": {
"user_name":{
"type": "keyword",
"doc_values":false
}
}
}
关闭 Doc Values 的好处
- 增加索引的速度;
- 减少磁盘空间;
什么时候关闭 Doc Values
- 明确不需要做排序和聚合分析的时候;