【问题标题】:Wrong regexp query for elasticsearchelasticsearch的错误正则表达式查询
【发布时间】:2018-06-28 07:37:16
【问题描述】:

我对弹性搜索的正则表达式查询有一些问题。在我的索引中有一个带有逗号分隔数值 (ID) 的文本字段,f.e.

2,140,3,2495

我有以下查询词:

"regexp" : {
  "myIds" : {
    "value" : "^2495,|,2495,|,2495$|^2495$",
    "boost" : 1
  }
}

但是我的结果列表是空的。

让我说,我知道正则表达式查询有点慢,但索引仍然存在并且充满了数百万个文档,所以很遗憾,它不是重组它的选项。所以我需要一个正则表达式解决方案。

【问题讨论】:

  • 在 ES 正则表达式中,模式默认锚定,^$ 是文字字符。试试"2495,.*|.*,2495,.*|.*,2495|2495"。或者,我认为您可以使用更简单的"(.*,)?2495(,.*)?"

标签: regex elasticsearch


【解决方案1】:

在 ElasticSearch 正则表达式中,模式默认锚定,^$ 被视为文字字符。

您的意思是使用"2495,.*|.*,2495,.*|.*,2495|2495" - 2495, 在字符串的开头,,2495, 在中间,,2495 在结尾或等于2495 的整个字符串。

或者,你可以使用更简单的

"(.*,)?2495(,.*)?"

意思是

  • (.*,)? - 以, 结尾的可选文本(不包括换行符)
  • 2495 - 你的价值
  • (,.*)? - 以, 结尾的可选文本(不包括换行符)

这是online demo showing how this expression works(虽然不是证明)。

【讨论】:

  • 您的第二个解决方案非常聪明,因为它很简单,如果我要使用多个 ID 构建查询,则正则表达式不会太复杂。但该解决方案有一个缺点:如果我查询 ID“9”,它也会匹配,因为我上面的示例字符串具有“2495”。但这是错误的行为,因为 9 不是 2495。有没有办法像您的示例一样保持查询简单但防止不正确的匹配?
  • @altralaser 你想说"(.*,)?9(,.*)?"返回2495吗? It should not。如果这里是 Java 正则表达式,那么试试(?<![,])9(?![^,])"^(.*,)?9(,.*)?$"
【解决方案2】:

好的,我让它工作了,但现在又遇到了另一个问题。我构建的字符串如下:

(.*,)?2495(,.*)?|(.*,)?10(,.*)?|(.*,)?898(,.*)?

它适用于几个 ID,但如果我有 50 个 ID,那么 ES 会抛出一个异常,表示正则表达式太复杂而无法处理。
有没有办法简化正则表达式或重组它本身的查询?

【讨论】:

  • 如果我的回答有帮助,请考虑支持/接受它,而不是重新发布作为您的答案。既然你有一个新问题,你应该发布一个新问题。
猜你喜欢
  • 2014-10-08
  • 2023-03-13
  • 1970-01-01
  • 2013-08-20
  • 1970-01-01
  • 1970-01-01
  • 2021-08-12
  • 1970-01-01
相关资源
最近更新 更多