首页 > 解决方案 > 在具有特殊字符的自定义关键字字段上使用术语查询时出现意外结果

问题描述

我有一个包含以下字段的索引:

myField: {
    type: "text",
    fields: {
        keyword: {
            type: "keyword",
            ignore_above: 256
        },
        keyword_lowercase: {
            type: "text",
            analyzer: "lowercase_keyword_analyzer",
            fielddata: true
        }
    },
    analyzer: "autocomplete_analyzer",
    search_analyzer: "autocomplete_search_analyzer"
},

分析仪:

lowercase_keyword_analyzer: {
    filter: [
        "lowercase",
        "asciifolding"
    ],
    type: "custom",
    tokenizer: "keyword"
},
autocomplete_search_analyzer: {
    filter: [
        "lowercase",
        "asciifolding"
    ],
    type: "custom",
    tokenizer: "standard"
},
autocomplete_analyzer: {
    filter: [
        "lowercase",
        "asciifolding",
        "autocomplete_edge_ngram"
    ],
    type: "custom",
    tokenizer: "standard"
}

我有一份价值为:L'OCCITANE 的文件

MATCH 查询:

"query": {
    "bool": {
        "should": [
        {
            "match": {
                "myField.keyword_lowercase": {
                    "query": "l’occitane"
                }
            }
        }]
    }
}

找到它,但是一个 TERM 查询:

"query": {
    "bool": {
        "should": [
        {
            "term": {
                "myField.keyword_lowercase": {
                    "value": "l’occitane"
                }
            }
        }]
    }
}

才不是。奇怪的是,如果我将撇号从文档中的 ' 更改为 ':

"query": {
    "bool": {
        "should": [
        {
            "term": {
                "myField.keyword_lowercase": {
                    "value": "l'occitane"
                }
            }
        }]
    }
}

术语搜索现在有效。据我了解,asciifolding 过滤器应该可以防止这种情况,我发现这个问题与带有特殊字符的其他单词有关。

这里发生了什么?

标签: elasticsearchelasticsearch-query

解决方案


这有点难看,但正如你所说,这是两种撇号。我会说一个是single quote,法国的一个是apostrophe

分别索引它们

POST mag/_doc
{"myField": "l'occitane"}

POST mag/_doc
{"myField":"l’occitane"}

然后通过分析的关键字进行聚合:

GET mag/_search
{
  "aggs": {
    "by_terms": {
      "terms": {
        "field": "myField.keyword_lowercase"
      }
    }
  }
}

屈服

"buckets" : [
        {
          "key" : "l'occitane",
          "doc_count" : 2
        }
      ]

这意味着 asciifolding 过滤器将 转换apostrophesingle-quote并且由于术语查询对倒排索引中的确切值进行操作,因此您将无法使用apostrophe. 你需要和

...
        {
          "term": {
            "myField.keyword_lowercase": {
              "value": "l'occitane"
            }
          }
        }
...

如果您确实想应用小写术语查询,则需要删除 asciifolding 或在其中添加另一个映射字段,myField而不需要上述 asciifolding。这样,查询myField.keyword_lowercase_no_ascii 与撇号一起使用。


推荐阅读