首页 > 解决方案 > 带有前缀查询的弹性搜索不区分大小写的查询

问题描述

我是弹性搜索的新手。我有以下查询

GET deals2/_search 
{
  "size": 200,
  "_source": ["acquireInfo"],
   "query": {
    "bool": {

      "must": [
        {

         "query_string": {
           "fields": ["acquireInfo.company_name.keyword"],
           "query": "az*"
         }
        }
      ]
    }
  }

}

在这里,我希望 Elastic 应该给出不区分大小写之类的结果 就像字符串以下面一样开头

"Az" 
"AZ" 
"az"
"aZ"
"Az"

但我并没有像这样得到所有的结果。所以任何人都可以请帮助我。

示例:- 我有 4 个文件

1)Aziia Avto Ust-Kamenogorsk OOO 
2)AZ Infotech Inc 
3)AZURE Midstream Partners LP 
4)State Oil Fund of the Republic of Azerbaijan

现在在 上搜索az,应该只返回前 3 个文档,因为它们从这里开始az 忽略大小写,而不是第 4 个文档,第 4 个文档也有az但不是在开头。

标签: elasticsearchcase-insensitive

解决方案


当您company_name在应用程序中使用关键字字段来索引时,就会发生这种情况。

关键字分析器是一个“noop”分析器,它将整个输入字符串作为单个标记返回,例如,公司名称,由 , 组成fooFoofOo仅存储大小写,搜索foo, 将仅匹配foo,因为弹性搜索最终适用于标记匹配(区分大小写)。

您需要使用标准分析器或其他一些自定义分析器来解决您的其他用例,并在字段上使用小写标记过滤器并使用被分析的匹配查询,并使用用于索引的相同分析器字段,这样您的搜索查询将生成相同的标记,这些标记存储在索引中,并且您的搜索将变得不区分大小写。

编辑:在聊天中与用户讨论并更新答案以满足他的要求,如下所示:-

第 1 步:- 定义索引的设置和映射。

端点:- http://{{hostname}}:{{port}}/{{index}}

{
  "settings": {
    "analysis": {
      "normalizer": {
        "my_normalizer": {
          "type": "custom",
          "char_filter": [],
          "filter": "lowercase"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "company_name": {
        "type": "keyword",
        "normalizer": "my_normalizer"
      }
    }
  }
}

第 2 步:索引所有文档

端点:http://{{hostname}}:{{port}}/{{index}}/_doc/ --> 1,2,3,4 等

{
    "company_name" : "State Oil Fund of the Republic of Azerbaijan"
}

Step3 :- 搜索查询

端点:- http://{{hostname}}:{{port}}/{{index}}/_search

{ "query": {
    "prefix" : { "company_name" : "az" }
  }
}

这将带来以下预期结果:-

{
    "took": 870,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 3,
            "relation": "eq"
        },
        "max_score": 1,
        "hits": [
            {
                "_index": "prerfixsearch",
                "_type": "_doc",
                "_id": "2ec9df0fc-dc04-47bb-914f-91a9f20d09efd15f2506-293f-4fb2-bdc3-925684a930b5",
                "_score": 1,
                "_source": {
                    "company_name": "AZ Infotech Inc"
                }
            },
            {
                "_index": "prerfixsearch",
                "_type": "_doc",
                "_id": "160d01183-a308-4408-8ac1-a85da950f285edefaca2-0b68-41c6-ba34-21bbef57f84f",
                "_score": 1,
                "_source": {
                    "company_name": "Aziia Avto Ust-Kamenogorsk OOO"
                }
            },
            {
                "_index": "prerfixsearch",
                "_type": "_doc",
                "_id": "1da878175-7db5-4332-baa7-ac47bd39b646f81c1770-7ae1-4536-baed-0a4f6b20fa38",
                "_score": 1,
                "_source": {
                    "company_name": "AZURE Midstream Partners LP"
                }
            }
        ]
    }
}

解释:,正如之前的 OP 没有提到在搜索结果中排除第 4 个文档,这就是我建议创建一个文本字段的原因,以便生成个人标记,但现在要求只有前缀搜索,我们不需要单个标记,我们只需要 1 个标记,但它应该小写以支持不区分大小写的搜索,这就是我在company_name字段上应用自定义规范器的原因。


推荐阅读