Elasticsearch:按字母顺序排序西班牙语双重名称

时间:2014-01-22 12:09:20

标签: sorting elasticsearch alphabetical

我正在进行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
            }
            ...
        }
    }
}

是否有人知道如何通过姓氏的起始字符串按顺序按字母顺序排序结果?

谢谢!

2 个答案:

答案 0 :(得分:13)

问题在于,您的LastName字段已经过分析,因此字符串Batres Rivera会被编入索引为多值字段,其中包含两个字词:batresrivera。但这不像一个有序的数组,它更像是一个“价值包”。因此,当您尝试对字段进行排序时,它会选择其中一个术语(minmax)并对其进行排序。

您需要做的是将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}})和~。因此,用户可以搜索riveramunoz,并且两者都匹配。

然后我们创建muñoz分析器,用西班牙语为es_sorting(小写)索引正确的排序顺序。

搜索将以相同的方式完成:

muñoz rivera

答案 1 :(得分:0)

我们需要知道您如何索引名称。

请查看此讨论链接。

http://elasticsearch-users.115913.n3.nabble.com/Is-there-a-way-to-search-terms-lower-cased-td932996.html

这对你的情况非常有帮助。这取决于您的映射设置。您使用什么分析器作为名称字段。

需要您的映射定义来确定正确的解决方案。