排序
-
Elasticsearch 默认采⽤相关性算分对结果进⾏ 降序排序
-
可以通过设定 sorting 参数,⾃⾏设定排序
-
如果不指定_score,算分为 Null
#单字段排序
POST /kibana_sample_data_ecommerce/_search
{
"size": 5,
"query": {
"match_all": {
}
},
"sort": [
{"order_date": {"order": "desc"}}
]
}
res:
"hits" : [
{
"_index" : "kibana_sample_data_ecommerce",
"_type" : "_doc",
"_id" : "VNBu0nABbRdUz8AoQBo4",
"_score" : null,
"_source" : {
"category" : [
"Men's Shoes",
"Men's Clothing"
],
多字段进⾏排序
-
组合多个条件
-
优先考虑写在前⾯的排序
-
⽀持对相关性算分进⾏排序
#多字段排序
POST /kibana_sample_data_ecommerce/_search
{
"size": 5,
"query": {
"match_all": {
}
},
"sort": [
{"order_date": {"order": "desc"}},
{"_doc":{"order": "asc"}},
{"_score":{ "order": "desc"}}
]
}
Demo
-
Elasticsearch 默认对查询结果的相关性算分进⾏降序排序
-
⽤户可以设定对单个 sorting 参数,⾃⾏设定排序。如果不对算分进⾏排序。_score 为 null
-
⽀持多个字段排序
对 Text 类型排序
#对 text 字段进行排序。默认会报错,需打开fielddata
POST /kibana_sample_data_ecommerce/_search
{
"size": 5,
"query": {
"match_all": {
}
},
"sort": [
{"customer_full_name": {"order": "desc"}}
]
}
res:
{
"error": {
"root_cause": [
{
"type": "illegal_argument_exception",
"reason": "Fielddata is disabled on text fields by default. Set fielddata=true on [customer_full_name] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead."
}
],
"type": "search_phase_execution_exception",
"reason": "all shards failed",
"phase": "query",
"grouped": true,
排序的过程
-
排序是针对字段原始内容进⾏的。 倒排索引⽆法发挥作⽤
-
需要⽤到正排索引。通过⽂档 Id 和字段快速得到字段原始内容
-
Elasticsearch 有两种实现⽅法
-
Fielddata
-
Doc Values (列式存储,对 Text 类型⽆效)
-
Doc Values vs Field Data
| Doc Values | Field data | |
|---|---|---|
| 何时创建 | 索引时,和倒排索引⼀起创建 | 搜索时候动态创建 |
| 创建位置 | 磁盘⽂件 | JVM Heap |
| 优点 | 避免⼤量内存占⽤ | 索引速度快,不占⽤额外的磁盘空间 |
| 缺点 | 降低索引速度,占⽤额外磁盘空间 | ⽂档过多时,动态创建开销⼤,占⽤过多JVM Heap |
| 缺省值 | ES 2.x 之后 | ES 1.x 及之前 |
Demo
-
单字段多字段排序
-
对 Text 和 Keyword 类型进⾏排序
打开 Fielddata
-
默认关闭,可以通过 Mapping 设置打开。修改 设置后,即时⽣效,⽆需重建索引
-
其他字段类型不⽀持,只⽀持对 Text 进⾏设定
-
打开后,可以对 Text 字段进⾏排序。但是是对 分词后的 term 排序,所以,结果往往⽆法满⾜ 预期,不建议使⽤
-
部分情况下打开,满⾜⼀些聚合分析的特定需求
#打开 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
-
默认启⽤,可以通过 Mapping 设置关闭
-
增加索引的速度 / 减少磁盘空间
-
如果重新打开,需要重建索引
-
什么时候需要关闭
-
明确不需要做排序及聚合分析
#关闭 keyword的 doc values
PUT test_keyword
PUT test_keyword/_mapping
{
"properties": {
"user_name":{
"type": "keyword",
"doc_values":false
}
}
}
获取 Doc Values & Fielddata 中存储的内容
-
Text 类型的不⽀持 Doc Values
-
Text 类型打开 Fielddata后,可以查看分词 后的数据
DELETE temp_users
PUT temp_users
PUT temp_users/_mapping
{
"properties": {
"name":{"type": "text","fielddata": true},
"desc":{"type": "text","fielddata": true}
}
}
Post temp_users/_doc
{"name":"Jack","desc":"Jack is a good boy!","age":10}
#打开fielddata 后,查看 docvalue_fields数据
POST temp_users/_search
{
"docvalue_fields": [
"name","desc"
]
}
#查看整型字段的docvalues
POST temp_users/_search
{
"docvalue_fields": [
"age"
]
}
Fielddata Demo
-
对 Text 字段设置 fielddata,⽀持随时修改
-
Doc Values 可以在 Mapping 中关闭。但是需要重新索引
-
Text 不⽀持 Doc Values
-
使⽤ docvalue_fields 查看存储的信息
本节知识点回顾
-
Elasticsearch ⽀持⾃定义排序
-
Doc Values 和 Fielddata 的对⽐
-
如何设置 Doc Values 和 Fielddata
课程demo
#单字段排序
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"}}
]
}
GET kibana_sample_data_ecommerce/_mapping
#对 text 字段进行排序。默认会报错,需打开fielddata
POST /kibana_sample_data_ecommerce/_search
{
"size": 5,
"query": {
"match_all": {
}
},
"sort": [
{"customer_full_name": {"order": "desc"}}
]
}
#打开 text的 fielddata
PUT kibana_sample_data_ecommerce/_mapping
{
"properties": {
"customer_full_name" : {
"type" : "text",
"fielddata": true,
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
#关闭 keyword的 doc values
PUT test_keyword
PUT test_keyword/_mapping
{
"properties": {
"user_name":{
"type": "keyword",
"doc_values":false
}
}
}
DELETE test_keyword
PUT test_text
PUT test_text/_mapping
{
"properties": {
"intro":{
"type": "text",
"doc_values":true
}
}
}
DELETE test_text
DELETE temp_users
PUT temp_users
PUT temp_users/_mapping
{
"properties": {
"name":{"type": "text","fielddata": true},
"desc":{"type": "text","fielddata": true}
}
}
Post temp_users/_doc
{"name":"Jack","desc":"Jack is a good boy!","age":10}
#打开fielddata 后,查看 docvalue_fields数据
POST temp_users/_search
{
"docvalue_fields": [
"name","desc"
]
}
#查看整型字段的docvalues
POST temp_users/_search
{
"docvalue_fields": [
"age"
]
}









网友评论