如何构建匹配具有特殊字符的文本的 Elasticsearch 短语查询?

How to build an Elasticsearch phrase query that matches text with special characters?

在过去的几天里,我一直在研究弹性搜索索引和搜索,并且我必须构建我想要的不同查询。我现在的问题是能够构建一个能够匹配具有特殊字符的文本的查询,即使我没有在 "search bar" 中键入它们也是如此。我会举个例子来解释我的意思。

假设您有一个索引文档,其中包含一个名为 page content 的字段。在此字段内,您可以有一部分文本,例如

"O carro do João é preto." (means João's car is black in portuguese)

我希望能够做的是键入如下内容:

O carro do joao e preto

并且仍然能够得到正确的匹配。

到目前为止我尝试过的:

  1. 我一直在使用 elasticsearch (here) 文档中提供的匹配短语查询,例如下面的示例:

    GET _search
    {
        "query": {
                "match_phrase": {
                    "page content": 
                    {
                        "query": "o carro do joao e preto"
                    }
                }
        }
     }
    

这个查询的结果是 0 次匹配。这是完全可以接受的,因为提供的查询内容与该文档中存储的内容不同。

  1. 我试过设置 ASCII 折叠令牌过滤器 (here),但我不确定如何使用它。所以我基本上做的是用这个查询创建一个新索引:

    PUT /newindex '
    {
        "page content": "O carro do João é preto",
        "settings" : {
            "analysis" : {
                "analyzer" : {
                    "default" : {
                        "tokenizer" : "standard",
                        "filter" : ["standard", "my_ascii_folding"]
                    }
                },
                "filter" : {
                    "my_ascii_folding" : {
                        "type" : "asciifolding",
                        "preserve_original" : true
                    }
                }
            }
        }
    }'
    

然后如果我尝试查询,使用上面提供的 match_phrase 查询,如下所示:

O carro do joao e preto

它应该会显示我想要的正确结果。但问题是它对我不起作用。我忘记了什么吗?在过去的两天里,我一直在解决这个问题,但没有成功,我觉得这是我所缺少的东西。

所以问题:我需要做什么才能得到想要的匹配?

设法找到了我自己的问题的答案。创建索引时,我不得不稍微更改分析器。此 previous answer 中的更多详细信息:

我现在的代码:

{
    "settings" : {
        "analysis" : {
            "analyzer" : {
                "default" : {
                    "tokenizer" : "standard",
                    "filter" : ["standard", "lowercase", "asciifolding"]
                },
                "text" : {
                    "tokenizer" : "standard",
                    "filter" : ["standard", "lowercase"],
                    "char_filter" : "html_strip"
                },
                "sortable" : {
                    "tokenizer" : "keyword",
                    "filter" : ["lowercase"],
                    "char_filter" : "html_strip"
                }
            }
        }
    }
}