Elasticsearch:跨多个字段查询多个单词(带前缀)
Elasticsearch: query for multiple words across multiple fields (with prefix)
我正在尝试实现由 ES 索引提供支持的自动建议控件。该索引有多个字段,我希望能够使用 AND 运算符跨多个字段进行查询并允许部分匹配(仅限前缀)。
举个例子,假设我有 2 个要查询的字段:"colour" 和 "animal"。
我希望能够完成 "duc"、"duck"、"purpl"、"purple"、"purple duck" 等查询。
我设法使用 multi_match() 和 AND 运算符来完成所有这些工作。
我似乎无法匹配 "purple duc" 之类的查询,因为 multi_match 不允许使用通配符。
我调查了 match_phrase_prefix(),但据我了解,它并未跨越多个领域。
我正在转向一个 tokeniser 的实现:感觉解决方案可能就在那里,所以最终的问题是:
1) 有人可以确认没有开箱即用的功能可以做我想做的事吗?感觉这是一个足够常见的模式,可以随时使用。
2) 有人可以提出任何解决方案吗?分词器是解决方案的一部分吗?
我很高兴被指出正确的方向并自己做更多的研究。
显然,如果有人可以分享可行的解决方案,那就太棒了。
提前致谢
- F
我实际上在 Qbox, which you can find here: http://blog.qbox.io/multi-field-partial-word-autocomplete-in-elasticsearch-using-ngrams 前一段时间写了一篇关于这个的博客 post。 (不幸的是,post 上的某些链接已损坏,此时无法轻易修复,但希望您能理解。)
我会推荐您参考 post 以了解详细信息,但这里有一些代码,您可以使用它来快速测试它。请注意,我使用的是 edge ngrams instead of full ngrams.
还要特别注意 _all field, and the 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
我正在尝试实现由 ES 索引提供支持的自动建议控件。该索引有多个字段,我希望能够使用 AND 运算符跨多个字段进行查询并允许部分匹配(仅限前缀)。
举个例子,假设我有 2 个要查询的字段:"colour" 和 "animal"。 我希望能够完成 "duc"、"duck"、"purpl"、"purple"、"purple duck" 等查询。 我设法使用 multi_match() 和 AND 运算符来完成所有这些工作。
我似乎无法匹配 "purple duc" 之类的查询,因为 multi_match 不允许使用通配符。
我调查了 match_phrase_prefix(),但据我了解,它并未跨越多个领域。
我正在转向一个 tokeniser 的实现:感觉解决方案可能就在那里,所以最终的问题是:
1) 有人可以确认没有开箱即用的功能可以做我想做的事吗?感觉这是一个足够常见的模式,可以随时使用。
2) 有人可以提出任何解决方案吗?分词器是解决方案的一部分吗? 我很高兴被指出正确的方向并自己做更多的研究。 显然,如果有人可以分享可行的解决方案,那就太棒了。
提前致谢 - F
我实际上在 Qbox, which you can find here: http://blog.qbox.io/multi-field-partial-word-autocomplete-in-elasticsearch-using-ngrams 前一段时间写了一篇关于这个的博客 post。 (不幸的是,post 上的某些链接已损坏,此时无法轻易修复,但希望您能理解。)
我会推荐您参考 post 以了解详细信息,但这里有一些代码,您可以使用它来快速测试它。请注意,我使用的是 edge ngrams instead of full ngrams.
还要特别注意 _all field, and the 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