在我的一个项目中,我试图使用Elasticsearch(1.7)查询数据。但是,对于unicode字符,它是否返回大写取决于其是否为大写。我尝试使用icu_analyzer摆脱问题。
这是一个演示我的问题的小例子。我的索引是这样的
$ curl -X PUT http://localhost:9200/tr-test -d '
{
"mappings": {
"names": {
"properties": {
"name": {
"type": "string"
}
}
}
},
"settings": {
"index": {
"number_of_shards": "5",
"number_of_replicas": "1",
"analysis": {
"filter": {
"nfkc_normalizer": {
"type": "icu_normalizer",
"name": "nfkc"
}
},
"analyzer": {
"my_lowercaser": {
"tokenizer": "icu_tokenizer",
"filter": [
"nfkc_normalizer"
]
}
}
}
}
}
}'
这是一个测试数据来演示我的问题。
$ curl -X POST http://10.22.20.140:9200/tr-test/_bulk -d '
{"index": {"_type":"names", "_index":"tr-test"}}
{"name":"BAHADIR"}'
这是一个类似的查询。如果我使用
BAHADIR
作为query_string
进行查询,则可以轻松找到我的测试数据。$ curl -X POST http://10.22.20.140:9200/tr-test/_search -d '
{
"query": {
"filtered": {
"query": {
"query_string": {
"query": "BAHADIR"
}
}
}
}
}'
在土耳其语中,
BAHADIR
的小写版本是bahadır
。使用bahadır
查询时,我期望得到相同的结果。但是Elasticsearch找不到我的数据。我无法使用ICU进行分析来解决此问题。如果我使用bahadir
进行查询,则效果很好。我已经读过Living in a Unicode World和Unicode Case Folding。但是无法解决我的问题。我仍然无法使elasticsearch使用正确的大小写折叠。
更新资料
我也尝试像这样创建索引。
$ curl -X PUT http://localhost:9200/tr-test -d '
{
"mappings": {
"names": {
"properties": {
"name": {
"type": "string",
"analyzer" : "turkish"
}
}
}
},
"settings": {
"index": {
"number_of_shards": "5",
"number_of_replicas": "1"
}
}
}'
但是我得到了相同的结果。如果我使用
BAHADIR
或bahadir
搜索,可以找到我的数据,但是通过搜索bahadır
正确的小写版本BAHADIR
不能找到我的数据。
最佳答案
您应该尝试在设置中使用Turkish Language Analyzer。
{
"mappings": {
"names": {
"properties": {
"name": {
"type": "string",
"analyzer": "turkish"
}
}
}
}
}
如您在实现细节中所见,它还定义了一个
turkish_lowercase
,因此我想它将为您解决问题。如果您不希望使用土耳其语分析器的所有其他功能,请仅使用turkish_lowercase
定义一个自定义功能如果需要在
name
字段上进行全文搜索,则还应该将查询方法更改为match query,这是在单个字段上的基本全文搜索方法。{
"query": {
"match": {
"name": "bahadır"
}
}
}
另一方面,query string query比较复杂,它在允许高级语法的多个字段上搜索;它还具有传递您要使用的
analyzer
的选项,因此,如果您确实需要这种查询,则应尝试在查询中传递"analyzer": "turkish"
。我不是查询字符串查询的专家。
关于unicode - Elasticsearch对Unicode字符使用了错误的大小写折叠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32452791/