我正在进行Elasticsearch查询,我希望按姓氏的字母顺序排序结果。我的问题:姓氏都是西班牙语的双重名称,而ES并没有按照我希望的方式对它们进行排序。 我希望订单是:
Batres Rivera
Batrín Chojoj
Fion Morales
Lopez Giron
Martinez Castellanos
Milán Casanova
这是我的疑问:
{
"query": {
"match_all": {}
},
"sort": [
{
"Last Name": {
"order": "asc"
}
}
]
}
我得到的顺序是:
Batres Rivera
Batrín Chojoj
Milán Casanova
Martinez Castellanos
Fion Morales
Lopez Giron
所以它不是按第一个字符串排序,而是由两者中的任何一个排序(Batres,Batrín,Casanova,Castellanos,Fion,Giron)。
如果我再试一次
{
"order": "asc",
"mode": "max"
}
然后我得到:
Batrín Chojoj
Lopez Giron
Martinez Castellanos
Milán Casanova
Fion Morales
Batres Rivera
默认情况下,所有字段都已编入索引,我使用
进行了检查curl -XGET localhost/my_index/_mapping
我回来了
my_index: {
my_type: {
properties: {
FirstName: {
type: string
}LastName: {
type: string
}MiddleName: {
type: string
}
...
}
}
}
是否有人知道如何通过姓氏的起始字符串按顺序按字母顺序排序结果?
谢谢!
答案 0 :(得分:13)
问题在于,您的LastName
字段已经过分析,因此字符串Batres Rivera
会被编入索引为多值字段,其中包含两个字词:batres
和rivera
。但这不像一个有序的数组,它更像是一个“价值包”。因此,当您尝试对字段进行排序时,它会选择其中一个术语(min
或max
)并对其进行排序。
您需要做的是将LastName
存储为单个术语(Batres Rivera
)以进行排序,方法是将字段映射为
{ "type": "string", "index": "not_analyzed"}
显然,您无法将该字段用于搜索目的:您将无法搜索rivera
并在该字段上进行匹配。
支持搜索和排序的方法是使用多字段:即以两种方式索引相同的值,一个用于搜索,一个用于排序。
在0.90。*中,多字段的语法是:
curl -XPUT "http://localhost:9200/my_index" -d'
{
"mappings": {
"my_type": {
"properties": {
"LastName": {
"type": "multi_field",
"fields": {
"LastName": {
"type": "string"
},
"raw": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
}
}'
在1.0。*中,multi_field
类型已被删除,现在任何核心字段类型都支持子字段,如下所示:
curl -XPUT "http://localhost:9200/my_index" -d'
{
"mappings": {
"my_type": {
"properties": {
"LastName": {
"type": "string",
"fields": {
"raw": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
}
}'
因此,您可以使用LastName
字段进行搜索,并使用LastName.raw
字段进行排序:
curl -XGET "http://localhost:9200/my_index/my_type/_search" -d'
{
"query": {
"match": {
"LastName": "rivera"
}
},
"sort": "LastName.raw"
}'
您还应该考虑使用ICU analysis plugin使用西班牙语排序顺序(或排序规则)进行排序。这有点复杂但值得使用:
curl -XPUT "http://localhost:9200/my_index" -d'
{
"settings": {
"analysis": {
"analyzer": {
"folding": {
"type": "custom",
"tokenizer": "icu_tokenizer",
"filter": [
"icu_folding"
]
},
"es_sorting": {
"type": "custom",
"tokenizer": "keyword",
"filter": [
"lowercase",
"spanish"
]
}
},
"filter": {
"spanish": {
"type": "icu_collation",
"language": "es"
}
}
}
},
"mappings": {
"my_type": {
"properties": {
"LastName": {
"type": "string",
"analyzer": "folding",
"fields": {
"raw": {
"type": "string",
"analyzer": "es_sorting"
}
}
}
}
}
}
}'
我们创建了一个folding
分析器,我们将其用于LastName
字段,该字段会将Muñoz Rivera
之类的字符串分析为两个术语munoz
(不含{ {1}})和~
。因此,用户可以搜索rivera
或munoz
,并且两者都匹配。
然后我们创建muñoz
分析器,用西班牙语为es_sorting
(小写)索引正确的排序顺序。
搜索将以相同的方式完成:
muñoz rivera
答案 1 :(得分:0)
我们需要知道您如何索引名称。
请查看此讨论链接。
这对你的情况非常有帮助。这取决于您的映射设置。您使用什么分析器作为名称字段。
需要您的映射定义来确定正确的解决方案。