【问题标题】:Wildcard search in Elasticsearch with a string field having only one wordElasticsearch 中的通配符搜索,字符串字段只有一个单词
【发布时间】:2020-03-03 11:46:20
【问题描述】:

我有一个用例,其中我的索引中的字符串类型字段具有单个单词(车号)作为其值,并且需要通过以下方式进行搜索:*abc*

实现它的最佳方法是什么?这样做会对性能产生什么影响?

目前我正在使用以下查询:_search?q=vehicleNumber:*119*,在我看来,这似乎是高度未优化的。

【问题讨论】:

标签: regex elasticsearch wildcard


【解决方案1】:

使用前导通配符可能会变得非常昂贵...如果您主要使用该通配符搜索数字“子字符串”并且其格式是标准化的(想想XX-12345-AB 形式的车牌号),您可以只提取将这些数字放入一个附加字段,然后对其进行范围查询。这肯定会比字符串上的通配符更快。


另一种选择是使用regex queries,例如,如果您知道要搜索的位置,这将很有帮助。事实证明,IMEI 确实有一定的结构——AA-BBBBBB-CCCCCC-EE——来自wiki

因此,如果您要查找序列号匹配项,请跳至索引 8:

GET /_search
{
  "query": {
    "regexp": {
      "vehicleNumber": {
        "value": ".{8,}119.*"
      }
    }
  }
}

总结一下,regexpwildcard 使用 same automaton in the background,因此在执行 leading * 查询时在两者之间进行选择不会提高速度性能。但是当你知道这个位置时,我怀疑regexp 可能会对此进行更多优化。

【讨论】:

  • 这可以在车辆号码的情况下提供帮助,但是如果我必须存储手机的 IMEI 号码并且必须对其进行子字符串搜索...我们该如何解决呢?
  • 如果您不打算更改映射中的任何内容,我认为您的方法已尽可能优化。
  • 我可以使用任何类型的分词器或分析器......类似于 ngram 的东西吗?
  • 我认为 ngram 在这里没有帮助。例如,当您想要支持模糊查询并处理拼写错误时,您会使用一个。但是由于您对子字符串匹配感兴趣,所以我会说通配符查询。你也可以考虑使用正则表达式查询——我会用这个信息更新我的答案。
猜你喜欢
  • 2018-08-08
  • 1970-01-01
  • 2016-08-15
  • 1970-01-01
  • 2019-11-16
  • 2019-11-03
  • 1970-01-01
  • 2013-10-22
  • 1970-01-01
相关资源
最近更新 更多