【问题标题】:Elatsticsearch partial, case-incensitive matchingElasticsearch 部分,不区分大小写的匹配
【发布时间】:2020-06-22 13:57:53
【问题描述】:

我正在尝试在 Elasticseach 7 中实现部分的、区分大小写的匹配。

我正在使用设置创建索引:

{
  "merchant_3" : {
    "settings" : {
      "index" : {
        "number_of_shards" : "2",
        "provided_name" : "merchant_3",
        "max_result_window" : "100000",
        "creation_date" : "1592833582520",
        "analysis" : {
          "analyzer" : {
            "englishAnalyzer" : {
              "filter" : [
                "lowercase"
              ],
              "tokenizer" : "standard"
            }
          }
        },
        "number_of_replicas" : "1",
        "uuid" : "5mjRMQ65TSGFFU0LfAH4eA",
        "version" : {
          "created" : "7060299"
        }
      }
    }
  }
}

和映射:

{
  "merchant_3" : {
    "mappings" : {
      "properties" : {
        "Name" : {
          "type" : "keyword"
        },
        ...
      }
    }
  }
}

以下查询正确返回文档:

POST /merchant/_search
{
  "query": {
    "wildcard": {
        "Name": "*Example*"
    }
  }
}

但是当我将搜索词小写时,它不会返回文档:

POST /merchant/_search
{
  "query": {
    "wildcard": {
        "Name": "*example*"
    }
  }
}

如何配置 Elasticsearch 以使用小写搜索词匹配 Name 字段值?

【问题讨论】:

  • 很想知道为什么您使用昂贵的前导通配符和未分析的关键字字段,并且您没有应用您创建的自定义分析器,无论如何添加一个解决所有这些问题的答案
  • 您能添加一个您希望匹配的示例文档吗?

标签: elasticsearch


【解决方案1】:

正如评论中提到的,当前方法存在一些缺陷,并且由于您没有提及您的用例,我建议您阅读my SO answer,其中解释了您应该考虑的各种功能和非功能要求。

在您的情况下,我使用 ngram analyzer 添加索引时间方法,如果您需要前缀类型的部分搜索,可以将其更改为 edge ngram

索引映射

{
  "settings": {
    "analysis": {
      "filter": {
        "autocomplete_filter": {
          "type": "ngram",
          "min_gram": 1,
          "max_gram": 10
        }
      },
      "analyzer": {
        "autocomplete": { 
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "autocomplete_filter"
          ]
        }
      }
    },
    "index.max_ngram_diff": 5 // note this
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "autocomplete", // note this
        "search_analyzer": "standard" // note this
      }
    }
  }
}

索引示例文档

{
  "title" : "Example movie"
}

使用Example搜索

{
    "query": {
        "match" : {
            "title" : "Example"
        }
    }
}

结果

"hits": [
      {
        "_index": "testpartial",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.471659,
        "_source": {
          "title": "Example movie"
        }
      }
    ]

用小写字母example 搜索也会产生相同的结果,只需更改上一个查询中的搜索词即可。

【讨论】:

  • 如果他搜索的是ExampleDocument呢?
  • @Gibbs 我的查询也会带来这个 :),OP 没有添加样本,但我验证了你的测试用例,它通过了 :)
  • 如果搜索词是moviemov,这将不起作用?
  • @crmepham 如果您有一个包含movie 的文档,那么它适用于moviemov,我也刚刚测试过,我可以要求您尝试我的解决方案并让我知道如果某些东西不起作用,还让您有机会浏览我在回答中提供的链接吗?
  • @crmepham 已经有一段时间了,如果您能跟进并让我知道您是否还有其他问题,那就太好了你。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-19
  • 2017-12-12
  • 2017-11-14
  • 2012-03-15
相关资源
最近更新 更多