如何在 Elasticsearch 中搜索不匹配大小写的精确文本

use*_*879 2 elasticsearch spring-boot elasticsearch-query

我想在Elasticsearch中搜索用户名。为此,我想匹配确切的用户名,忽略其大小写,无论是大写还是小写,我只想找到该用户名。我为此使用以下查询:

QueryBuilder queryBuilder = QueryBuilders.termQuery("user_name.keyword", userName);
NativeSearchQuery build = new NativeSearchQueryBuilder().withQuery(queryBuilder).build();
List<Company> companies = elasticsearchTemplate.queryForList(build, User.class);
Run Code Online (Sandbox Code Playgroud)

但它也将单词与大小写精确匹配。例如:如果用户名是“Ram”并且我搜索“ram”,那么它不会返回该名称。如果我搜索“Ram”,那么它就会给我结果。但我希望它只匹配单词而不是单词的大小写。请有人帮我解决这个问题。我搜索了很多但找不到任何解决方案。

小智 5

问题是您正在使用user_name.keywordterms查询。Terms查询匹配确切的单词,而不是您可以使用MatchQueryBuilder查询:

代码 :

QueryBuilder queryBuilder = QueryBuilders.matchQuery("user_name", userName);
NativeSearchQuery build = new NativeSearchQueryBuilder().withQuery(queryBuilder).build();
List<Company> companies = elasticsearchTemplate.queryForList(build, User.class);
Run Code Online (Sandbox Code Playgroud)

使用.keyword字段时,elastic 不会分析文本,但如果您使用文本字段,ElasticSerach 会使用该字段上的默认分析器分析您的文本。默认分析器基本上将文本转换为小写并从中删除停用词。您可以从这里阅读:https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-standard-analyzer.html

由于您想要进行不区分大小写的搜索,因此不需要使用.keyword.

此外,terms查询匹配确切的术语,但同样,由于您想要进行不区分大小写的搜索,因此您应该match进行查询,默认情况下,它也会在内部将搜索文本转换为小写,然后在字段中搜索该文本。

而且,现在由于您的字段和搜索词都是小写的,您可以进行不区分大小写的搜索,但这不会进行完全匹配

为了进行精确的不区分大小写的匹配,您需要更新索引并使用带有关键字字段的规范化器,这保证分析链生成单个标记和不区分大小写的搜索。您可以从这里阅读更多相关信息。

索引创建:

curl -X PUT "localhost:9200/<index-name>" -H 'Content-Type: application/json' -d 
{
        "settings": {
            "analysis": {
                "normalizer": {
                    "case_insensitive_normalizer": {
                        "type": "custom",
                        "filter": [
                            "lowercase"
                        ]
                    }
                }
            }
        },
        "mappings": {
            "properties": {
                "user_name": {
                    "type": "keyword",
                    "normalizer": "case_insensitive_normalizer"
                }
            }
        }
}
Run Code Online (Sandbox Code Playgroud)

我已经对这些文档建立了索引:

文件1:

{
        "user_name": "Ram"
} 
Run Code Online (Sandbox Code Playgroud)

文件2:

{
        "user_name": "Ram Mohan"
}
Run Code Online (Sandbox Code Playgroud)

搜索查询:

{
     "query" : {
        "match" : {
            "user_name" : "ram"
        }
     }
}
Run Code Online (Sandbox Code Playgroud)

结果 :

"hits": [
            {

                "_source": {
                    "user_name": "Ram"
                }
            }
]
Run Code Online (Sandbox Code Playgroud)