【问题标题】:ElasticSearch Search query is not case sensitiveElasticSearch 搜索查询不区分大小写
【发布时间】:2019-03-15 17:22:54
【问题描述】:

我正在尝试搜索查询,它可以很好地进行精确搜索,但是如果用户输入小写或大写,则它不起作用,因为 ElasticSearch 不区分大小写。

例子

{
    "query" : {
        "bool" : { 
            "should" : {
                "match_all" : {} 
            },
            "filter" : {
                "term" : { 
                    "city" : "pune"
                }
            }
        }
    }
}

当 city 正好是“pune”时它可以正常工作,如果我们将文本更改为“PUNE”它就不起作用。

【问题讨论】:

  • 那么city字段的字段类型是什么?
  • “城市”:{“类型”:“文本”}
  • 您可能需要检查您的映射以查看是否分析了 city 字段。
  • 使用match query 而不是term query

标签: elasticsearch nest


【解决方案1】:

ElasticSearch 不区分大小写。

“Elasticsearch”不区分大小写。默认情况下,JSON 字符串属性将映射为 text datatype(使用 keyword datatype submulti field,我将稍后解释)。

text 数据类型具有与之相关的分析概念;在索引时,字符串输入通过an analysis chain 馈送,结果 terms 存储在倒排索引数据结构中,用于快速全文搜索。对于未指定分析器的text 数据类型,将使用默认分析器,即Standard Analyzer。标准分析器的组件之一是 Lowercase token filter,它将标记小写(术语)。

在通过搜索 API 查询 Elasticsearch 时,可以使用许多不同类型的查询,以适应几乎任何用例。诸如matchmulti_match 查询等一类查询是全文查询。这些类型的查询在搜索时对查询输入执行分析,并将生成的术语与存储在倒排索引中的术语进行比较。默认使用的分析器也是标准分析器。

另一类查询,例如termtermsprefix 查询,是术语级别的查询。这些类型的查询不分析查询输入,因此将按原样将查询输入与存储在倒排索引中的术语进行比较。

在您的示例中,您对"city" 字段的term 查询在大写时找不到任何匹配项,因为它正在搜索text 字段,该字段的输入在索引时进行了分析。使用默认映射,keyword sub 字段可以提供帮助。 keyword 数据类型不进行分析(嗯,它具有normalizers 的分析类型),因此可用于精确 匹配,以及排序和聚合。要使用它,您只需要定位 "city.keyword" 字段。另一种方法是将"city" 字段使用的分析器更改为不使用小写标记过滤器的分析器;采用这种方法需要您重新索引索引中的所有文档。

【讨论】:

  • 谢谢,配置起来很容易。
【解决方案2】:

除非您定义自定义映射,否则 Elasticsearch 将分析文本字段小写。

精确值(如数字、日期和关键字)具有精确值 在字段中指定的添加到倒排索引以使 他们可搜索。

但是,会分析文本字段。这意味着它们的值是 首先通过分析器生成一个术语列表,它们是 然后添加到倒排索引。文本分析的方法有很多: 默认标准分析器会删除大多数标点符号,分解文本 成单个单词,并将它们小写

见:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html

因此,如果您想在查询之前自行使用术语查询 — analyze the term。或者在这种情况下将术语小写。

【讨论】:

    【解决方案3】:

    为了解决这个问题,我创建了自定义规范化并更新映射以添加,

    在我们必须删除索引并重新添加之前

    先删除索引

    删除http://localhost:9200/users

    现在重新创建索引

    输入http://localhost:9200/users

    {
      "settings": {
        "analysis": {
          "normalizer": {
            "lowercase_normalizer": {
              "type": "custom",
              "char_filter": [],
              "filter": ["lowercase", "asciifolding"]
            }
          }
        }
      },
      "mappings": {
        "user": {
          "properties": {
            "city": {
              "type": "keyword",
              "normalizer": "lowercase_normalizer"
            }
          }
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-21
      • 1970-01-01
      相关资源
      最近更新 更多