【问题标题】:ElasticSearch Regexp FilterElasticSearch 正则表达式过滤器
【发布时间】:2014-01-14 11:18:35
【问题描述】:

我在正确表达 ElasticSearch 正则表达式过滤器的正则表达式时遇到问题。我正在尝试匹配 url 字段中“info-for/media”中的任何内容,例如http://mydomain.co.uk/info-for/media/press-release-1。为了尝试正确使用正则表达式,我现在使用match_all,但这最终将是match_phrase 和用户的查询字符串。

POST 到 localhost:9200/_search

{
"query" : {
               "match_all" : { },
               "filtered" : {
                           "filter" : {
                                   "regexp": {
                                        "url":".*info-for/media.*" 
                                    }
                          }
                }
         },
}

这会返回 0 次点击,但会正确解析。 .*info.* 确实得到包含 url 的结果,但不幸的是太宽泛了,例如匹配任何包含“信息”的网址。一旦我在“info-for”中添加连字符,我再次得到 0 个结果。无论我尝试哪种转义字符组合,我都会得到解析异常,或者没有匹配。任何人都可以帮助解释我做错了什么吗?

【问题讨论】:

    标签: regex elasticsearch


    【解决方案1】:

    首先,尽量不要使用没有前缀的正则表达式或通配符。搜索.*foo.* 的方式是索引字典中的每个词都与模式匹配,而模式又被构造成匹配词的 OR 查询。这是您的语料库中唯一术语的数量O(n),随后的搜索也非常昂贵。

    这篇文章有更多的细节:https://www.found.no/foundation/elasticsearch-from-the-bottom-up/

    其次,您的 url 可能以某种方式被标记化,使得“info-for”和“media”在您的索引中成为单独的术语。因此,字典中没有 info-for/media-term 供正则表达式匹配。

    您可能想要做的是分别索引路径和域,使用path_hierarchy-tokenizer 生成术语。

    这是一个演示如何生成令牌的示例:https://www.found.no/play/gist/ecf511d4102a806f350b#analysis

    /foo/bar/baz 生成标记 /foo/bar/baz, /foo/bar, /foo 并且域 foo.example.com 被标记为 foo.example.com, example.com, com

    /foo/bar 下方搜索任何内容都可以是匹配path:/foo/bar 的简单术语过滤器。这是一个性能更高的过滤器,也可以缓存。

    【讨论】:

    • 一个更简单的选择是将此字段映射为具有非分析版本的多字段,并在未分析的字段上运行正则表达式过滤器。一般来说,正则表达式过滤器在未分析的字段上更有意义。
    • 执行起来仍然是一个非常昂贵的查询。
    • 感谢@AlexBrasetvik 我在将映射/分析器配置的 JSON 版本发布到我的 index _settings 端点时遇到了一些困难。它找不到我声明的分析器。如果您有 JSON 示例,将会非常有帮助,谢谢。
    • @AlexBrasetvik 为什么在非分析字段上执行正则表达式仍然很昂贵?
    猜你喜欢
    • 2014-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-02
    • 2017-06-19
    • 2012-12-10
    相关资源
    最近更新 更多