【问题标题】:Elasticsearch - query_string with wildcardsElasticsearch - 带有通配符的查询字符串
【发布时间】:2016-04-25 13:20:44
【问题描述】:

我在弹性搜索中有一些文本,其中包含各种格式的网址(http://www,www.)我想做的是搜索所有包含例如 google.com 的文本。

对于当前搜索,我使用类似这样的查询:

query = { "query": {
                "bool": {
                     "must": [{
                            "range": {
                            "cdate": {
                                "gt": dfrom,
                                "lte": dto }
                            }
                        },
             { "query_string":{
                "default_operator": "AND",
                "default_field": "text",
                "analyze_wildcard":"true",
                "query": searchString } }
            ]
        }
        }}

但是看起来像 google.com 的查询永远不会返回任何结果,例如搜索术语“test”可以正常工作(没有“)。我确实想使用 query_string 因为我喜欢使用布尔运算符,但我真的需要能够不仅搜索整个单词的子字符串。

谢谢!

【问题讨论】:

  • 你的url字段的映射是什么?
  • "text" 只是一个文本字段。

标签: elasticsearch query-string


【解决方案1】:

确实http://www.google.com 会被标准分析器标记为httpwww.google.com,因此google.com 将找不到。

因此,单独的标准分析器在这里没有帮助,我们需要一个可以正确转换 URL 标记的标记过滤器。如果您的 text 字段仅包含 URL,则另一种方法是使用 UAX Email URL tokenizer,但由于该字段可以包含任何其他文本(即用户 cmets),因此它将不起作用。

幸运的是,有一个名为 analysis-url 的新插件提供了 URL 令牌过滤器,这正是我们所需要的(在 small modification 请求之后,感谢 @jlinn ;-))

首先,你需要安装插件:

bin/plugin install https://github.com/jlinn/elasticsearch-analysis-url/releases/download/v2.2.0/elasticsearch-analysis-url-2.2.0.zip

然后,我们可以开始玩了。我们需要为您的 text 字段创建适当的分析器:

curl -XPUT localhost:9200/test -d '{
  "settings": {
    "analysis": {
      "filter": {
        "url_host": {
          "type": "url",
          "part": "host",
          "url_decode": true,
          "passthrough": true
        }
      },
      "analyzer": {
        "url_host": {
          "filter": [
            "url_host"
          ],
          "tokenizer": "whitespace"
        }
      }
    }
  },
  "mappings": {
    "url": {
      "properties": {
        "text": {
          "type": "string",
          "analyzer": "url_host"
        }
      }
    }
  }
}'

使用此分析器和映射,我们可以正确索引您希望能够搜索的主机。例如,让我们使用我们的新分析器分析字符串blabla bla http://www.google.com blabla

curl -XGET 'localhost:9200/urls/_analyze?analyzer=url_host&pretty' -d 'blabla bla http://www.google.com blabla'

我们将获得以下代币:

{
  "tokens" : [ {
    "token" : "blabla",
    "start_offset" : 0,
    "end_offset" : 0,
    "type" : "word",
    "position" : 0
  }, {
    "token" : "bla",
    "start_offset" : 0,
    "end_offset" : 0,
    "type" : "word",
    "position" : 1
  }, {
    "token" : "www.google.com",
    "start_offset" : 0,
    "end_offset" : 0,
    "type" : "word",
    "position" : 2
  }, {
    "token" : "google.com",
    "start_offset" : 0,
    "end_offset" : 0,
    "type" : "word",
    "position" : 3
  }, {
    "token" : "com",
    "start_offset" : 0,
    "end_offset" : 0,
    "type" : "word",
    "position" : 4
  }, {
    "token" : "blabla",
    "start_offset" : 0,
    "end_offset" : 0,
    "type" : "word",
    "position" : 5
  } ]
}

如您所见,http://www.google.com 部分将被标记为:

  • www.google.com
  • google.com 即您所期望的
  • com

所以现在如果您的searchStringgoogle.com,您将能够找到所有具有包含google.com(或www.google.com)的text 字段的文档。

【讨论】:

  • @pinas 你能试试这个吗?
【解决方案2】:

全文搜索总是关于倒排索引中的完全匹配,除非您执行强制遍历倒排索引的通配符搜索。在 queryString 的开头使用通配符会导致索引全遍历,不推荐。

不仅要考虑为 URL 编制索引,还要考虑应用 Keyword Tokenizer 的域(通过剥离协议、子域和域后的任何信息)。然后您可以根据该字段搜索域。

【讨论】:

  • 嗨 - 我可能解释得不好。我所做的是将来自公司内部 wiki(实际上是 cmets)的帖子编入索引,并尝试使这些内容可搜索。我要执行的一个查询是查找这些 cmets 中提到的所有 pastebin 链接。因此,我不仅索引 url,还索引可能包含 pastebin 链接的全文 cmets。将来我想做诸如“所有包含 pastebin 链接和单词 'test engine' 的 cmets ”之类的查询 - 查询字符串看起来不错,但这个布尔运算但通配符不起作用。
猜你喜欢
  • 2016-08-15
  • 1970-01-01
  • 2015-07-19
  • 1970-01-01
  • 2020-06-01
  • 2012-11-28
  • 1970-01-01
  • 2016-06-02
  • 1970-01-01
相关资源
最近更新 更多