【问题标题】:How to sort on a text field with elastic search如何使用弹性搜索对文本字段进行排序
【发布时间】:2021-03-01 18:34:54
【问题描述】:
{
  "parent" : "some_id",
  "type" : "support",
  "metadata" : {
    "account_type" : "Regular",
    "subject" : "Test Subject",
    "user_name" : "John Doe",
    "origin" : "Origin",
    "description" : "TEST",
    "media" : [ ],
    "ticket_number" : "XXXX",
    "status" : "completed",
  },
  "create_time" : "2021-02-24T15:08:57.750Z",
  "entity_name" : "comment"
}

这是我的演示数据。当我尝试按 metadata.sort 进行排序时,例如->

GET comments-*/_search
{
    "query": {
        "bool": {
            "must": [{
                "match": {
                    "type": "support"
                }
            }]
        }
    },
    "from": 0,
    "size": 50,
    "sort": [{
      "metadata.status": {
         "order": "desc"
       }
    }]
}

它说 -> 默认情况下,文本字段上的字段数据是禁用的。在 [metadata.status] 上设置 fielddata=true 以便通过反转倒排索引将 fielddata 加载到内存中。请注意,这可能会占用大量内存。或者使用关键字字段。

我不知道如何实现相同的目标,因为我对 ESS 很陌生。任何帮助将不胜感激

【问题讨论】:

    标签: elasticsearch kibana


    【解决方案1】:

    很可能,问题在于metadata.status 属于text 类型,它是不可排序的(see docs)。如果文本字段是 keyword 类型,您可以对其进行排序。

    请检查您的索引的映射。最有可能的是,您的索引具有默认映射 (see docs),并且 keyword 子字段会自动分配给具有字符串值的每个字段。

    TL;DR:尝试运行此查询

    GET comments-*/_search
    {
        "query": {
            "bool": {
                "must": [{
                    "match": {
                        "type": "support"
                    }
                }]
            }
        },
        "from": 0,
        "size": 50,
        "sort": [{
          "metadata.status.keyword": {
             "order": "desc"
           }
        }]
    }
    

    【讨论】:

    • 嗨@glenacota 感谢您的回复。您提到的上述查询适用于具有特定索引的值,例如GET comments-some-id/_search,但是当使用GET comments-*/_search 时,即对于所有索引,它会抛出类似下面的内容```“原因”:“没有为 [metadata.status.keyword 找到映射” ] 为了排序" ``` 不知道为什么,但我已经使用自定义脚本实现了要求,如下所示 ``` sort : { '_script': { 'script': "doc['metadata.status.keyword'] .value", 'order': 'desc', 'type': 'string' } } ```
    • 您收到错误的原因是并非所有与 cmets-* 匹配的索引都有metadata.status.keyword 的映射(或根本没有metadata.status 字段)。我不确定为什么使用脚本进行排序没有返回错误:sweat_smile:
    • 嘿@PradiptaDey,问题得到解答了吗?
    【解决方案2】:

    您只能在字符串字段上按“关键字”类型的字段进行排序。

    如果您在发送文档之前未设置映射,Elasticsearch 动态映射将创建 2 个字段。

    在本例中为“status”和“status.keyword”。

    所以尝试使用“metadata.status.keyword”。

    TL;DR

    对于不会进行全文搜索的字段(如状态标志),最好只存储字段的关键字版本。

    为此,您必须为任何文档编制索引之前设置映射。

    有个窍门:

    1. 摄取数据
    POST test_predipa/_doc
    {
      "parent" : "some_id",
      "type" : "support",
      "metadata" : {
        "account_type" : "Regular",
        "subject" : "Test Subject",
        "user_name" : "John Doe",
        "origin" : "Origin",
        "description" : "TEST",
        "media" : [ ],
        "ticket_number" : "XXXX",
        "status" : "completed"
      },
      "create_time" : "2021-02-24T15:08:57.750Z",
      "entity_name" : "comment"
    }
    
    1. 获取自动生成的映射
    GET test_predipa/_mapping
    
    1. 使用相同的映射创建一个新的空索引并根据需要进行修改(在这种情况下,从 metadata.status 中删除文本类型字段并只保留关键字 one。
    PUT test_predipa_new
    {
      "mappings": {
        "properties": {
          "create_time": {
            "type": "date"
          },
          "entity_name": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "metadata": {
            "properties": {
              "account_type": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "description": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "origin": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "status": {
                "type": "keyword"
              },
              "subject": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "ticket_number": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "user_name": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              }
            }
          },
          "parent": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "type": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    }
    
    1. 将数据从旧索引移到新的空索引
    POST _reindex
    {
      "source": {
        "index": "test_predipa"
      },
      "dest": {
        "index": "test_predipa_new"
      }
    }
    
    1. 运行排序查询
    GET test_predipa_new/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "type": "support"
              }
            }
          ]
        }
      },
      "from": 0,
      "size": 50,
      "sort": [
        {
          "metadata.status": {
            "order": "desc"
          }
        }
      ]
    }
    

    【讨论】:

      猜你喜欢
      • 2020-02-21
      • 2016-12-09
      • 1970-01-01
      • 2016-06-04
      • 1970-01-01
      • 2015-02-25
      • 1970-01-01
      • 2021-01-24
      • 2017-09-06
      相关资源
      最近更新 更多