2014-01-14 64 views
3

我在正确表达ElasticSearch正则表达式筛选器的正则表达式时出现问题。我试图在网址字段中的“info-for/media”中匹配任何内容,例如http://mydomain.co.uk/info-for/media/press-release-1。要尝试获得正确的正则表达式,我现在使用的是match_all,但最终将使用用户的查询字符串match_phraseElasticSearch正则表达式筛选器

POST为localhost:9200/_search

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

这将返回0命中,但正确地解析。 .*info.*确实会得到包含该网址的结果,但不幸的是该网址过于宽泛,例如匹配包含“信息”的任何网址。只要我在“info-for”中添加连字符,我就会再次得到0个结果。无论我尝试使用哪种转义字符组合,我都会得到解析异常,或者无法匹配。任何人都可以帮助解释我做错了什么?

回答

7

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

这篇文章有关于一些细节:https://www.found.no/foundation/elasticsearch-from-the-bottom-up/

其次,您的网址是可能的方式,使“信息的”和“媒体”独立的索引项标记化。因此,字典中没有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。这是一个大规模更高性能的过滤器,也可以缓存。

+1

一个更简单的选项是将此字段映射为未分析版本的多字段,并在未分析字段上运行regexp过滤器。一般来说,正则表达式过滤器在非分析字段上更有意义。 –

+0

这仍然是一个非常昂贵的查询来执行。 –

+0

谢谢@AlexBrasetvik我在将映射/分析器配置的JSON版本发布到我的索引_settings端点时遇到了一些困难。它无法找到我声明的分析器。如果你有它,示例JSON会非常有帮助,谢谢。 – idlemind