Elasticsearch:跨多个字段查询多个单词(带前缀)

标签 elasticsearch autocomplete autosuggest

我正在尝试实现由 ES 索引提供支持的自动建议控件。索引有多个字段,我希望能够使用 AND 运算符跨多个字段进行查询并允许部分匹配(仅前缀)。

举个例子,假设我有 2 个要查询的字段:“颜色”和“动物”。 我希望能够完成诸如“duc”、“duck”、“purpl”、“purple”、“purple duck”之类的查询。 我设法使用带有 AND 运算符的 multi_match() 来完成所有这些工作。

我似乎无法做的是匹配诸如“purple duc”之类的查询,因为 multi_match 不允许使用通配符。

我研究过 match_phrase_prefix(),但据我了解,它并不跨越多个字段。

我正在转向 tokeniser 的实现:感觉解决方案可能就在那里,所以最终的问题是:

1) 有人可以确认没有开箱即用的功能来做我想做的事吗?感觉这是一个足够常见的模式,可以随时使用。

2) 有人可以提出任何解决方案吗?分词器是解决方案的一部分吗? 我很高兴被指出正确的方向并自己做更多的研究。 显然,如果有人可以分享可行的解决方案,那就太棒了。

提前致谢 - F

最佳答案

实际上我前段时间为 Qbox 写了一篇关于这个的博文,您可以在这里找到:http://blog.qbox.io/multi-field-partial-word-autocomplete-in-elasticsearch-using-ngrams . (不幸的是,帖子中的某些链接已损坏,此时无法轻松修复,但希望您能理解。)

我会建议您参阅该帖子以了解详细信息,但这里有一些代码可用于快速测试。请注意,我使用的是 edge ngrams而不是完整的 ngrams .

还要特别注意 _all field 的使用, 和 match query operator .

好的,这是映射:

PUT /test_index
{
   "settings": {
      "analysis": {
         "filter": {
            "edgeNGram_filter": {
               "type": "edgeNGram",
               "min_gram": 2,
               "max_gram": 20
            }
         },
         "analyzer": {
            "edgeNGram_analyzer": {
               "type": "custom",
               "tokenizer": "whitespace",
               "filter": [
                  "lowercase",
                  "asciifolding",
                  "edgeNGram_filter"
               ]
            }
         }
      }
   },
   "mappings": {
      "doc": {
         "_all": {
            "enabled": true,
            "index_analyzer": "edgeNGram_analyzer",
            "search_analyzer": "standard"
         },
         "properties": {
            "field1": {
               "type": "string",
               "include_in_all": true
            },
            "field2": {
               "type": "string",
               "include_in_all": true
            }
         }
      }
   }
}

现在添加几个文档:

POST /test_index/doc/_bulk
{"index":{"_id":1}}
{"field1":"purple duck","field2":"brown fox"}
{"index":{"_id":2}}
{"field1":"slow purple duck","field2":"quick brown fox"}
{"index":{"_id":3}}
{"field1":"red turtle","field2":"quick rabbit"}

这个查询似乎说明了你想要什么:

POST /test_index/_search
{
   "query": {
      "match": {
         "_all": {
             "query": "purp fo slo",
             "operator": "and"
         }
      }
   }
}

返回:

{
   "took": 5,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 0.19930676,
      "hits": [
         {
            "_index": "test_index",
            "_type": "doc",
            "_id": "2",
            "_score": 0.19930676,
            "_source": {
               "field1": "slow purple duck",
               "field2": "quick brown fox"
            }
         }
      ]
   }
}

这是我用来测试它的代码:

http://sense.qbox.io/gist/b87e426062f453d946d643c7fa3d5480cd8e26ec

关于Elasticsearch:跨多个字段查询多个单词(带前缀),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32421720/

相关文章:

Elasticsearch SQL 类子查询聚合

jquery - 在输入的字段下设置动态创建的自动完成建议位置

elasticsearch - 我应该使用嵌套对象还是普通字段?

c# - 自定义文本框自动完成

java - 自动将注释附加到 Netbeans 中自动插入的大括号

java - 如何在 JTextArea swing 中实现 autosugesion

SOLR 建议器多字段自动完成

javascript - emergent react-autosuggest 列表中不监听 event click

elasticsearch - 如何使用elasticsearch Java API进行动态搜索?

join - 是否可以在 ElasticSearch 中使用任何 ES Connector for presto 或 Hive (ElasticSearch-Hadoop) 进行 JOIN 操作?