unicode - Elasticsearch对Unicode字符使用了错误的大小写折叠

标签 unicode elasticsearch icu

在我的一个项目中,我试图使用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 WorldUnicode 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"
    }
  }
}'

但是我得到了相同的结果。如果我使用BAHADIRbahadir搜索,可以找到我的数据,但是通过搜索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/

相关文章:

python - 使用 UCS-4 的 Python Swig 绑定(bind)

c++ - 检查 unicode 引号是打开还是关闭

node.js - Intl.NumberFormat 在 Node 和浏览器中的不同行为

php - 带有单数/复数词的 NumberFormatter

python - rabbitmqadmin无法处理unicode?

java - 转义双引号无法正常工作

Java:如何获取字符(或其类型类别)的 Unicode 名称?

Elasticsearch、Nest 和 Lucene.net

elasticsearch - ElasticsearchTemplate-为什么对某些操作隐式使用indexName而对其他操作则隐式使用

sql - 在elasticsearch中获取最近一小时的记录