如何在弹性搜索中对字段类型“文本”进行排序

kga*_*har 3 amazon-web-services node.js elasticsearch

我正在进行弹性搜索多字段排序查询,我的数据格式如下:

{
  "person_name" : "Abraham Benjamin deVilliers",
  "created_on": "Tue, 02 Apr 2018 16: 17: 54 GMT",
  "name": "Abraham",
  "office":{
     "name":"my_office"
  }
},
{
  "person_name" : "John Bradshaw",
  "created_on": "Thu Apr 05 2018 14:42:30 GMT",
  "name": "jhon",
  "office": {
     "name":"Abraham deVilliers"
  }
},
{
  "person_name" : "John Bradshaw",
  "created_on": "Tue, 03 Apr 2018 11: 39: 17 GMT",
  "name": "Abraham deVilliers",
  "office": {
     "name":"blabla"
  }
}
Run Code Online (Sandbox Code Playgroud)

其中字段person_name是type textcreated_on是type string。我必须根据字段person_name和对上述响应进行排序created_on

我们尝试的查询如下:

GET /my_index/_search

{
    sort: [{ 
             "person_name": { "order": "asc" },
             "created_on": { "order": "desc" }
    }]
}
Run Code Online (Sandbox Code Playgroud)

使用上述查询对响应进行排序时,出现以下错误:

消息:'[illegal_argument_exception]默认情况下,在文本字段上禁用字段数据。在[person_name]上设置fielddata = true,以通过反转反相索引将字段数据加载到内存中。请注意,这可能会占用大量内存。或者使用关键字字段代替。”

在搜索中,我们发现需要修改字段person_name从type text到type的映射keyword。但是我们无法修改现有映射,因为它已经包含了数百万条记录。

还有其他方法可以在text不更改弹性搜索的现有映射的情况下对字段执行排序查询吗?

任何帮助将不胜感激。

Alk*_*ris 7

有两种方法可以满足您的需求。

  1. 添加一个新的字段multi-fields。使用多字段时,每次您索引一个新字段时,elasticsearch都会自动为您引用的字段应用不同的分析器逻辑。该raw字段将不会被分析,这意味着它将总共是一个术语,因此可以用于排序。为此,您必须更新映射,然后使用reindex api来更新数据(您基本上是创建一个新索引,然后将您的应用程序切换为使用新索引而不是旧索引,以便执行此操作在没有停机的情况下,您可以使用别名)。不创建新索引而更新索引的另一种方法是使用update_by_query api
  2. 如果您只是希望这种工作方式不更改任何内容,则可以使用脚本。基本上,您将选择保存的值并根据该值进行排序。但这对于扩展使用而言不起作用。这又快又脏,所以要小心对待。

所有链接都指向elasticsearch的官方文档。