我有一个包含以下文档的弹性搜索索引,我想在指定的字段上拥有自动完成功能:
映射:https://gist.github.com/anonymous/0609b1d110d91dceb9a90faa76d1d5d4
USECASE:
我的查询是表格前缀类型,例如" sta"," star"," star w" .."开始战争"等附加过滤器作为标签="科幻小说"。此外,查询可以匹配其他字段,如描述,演员(在演员字段中,这不是嵌套的)。我也想知道它匹配的字段。
我调查了两种方法,但是没有方法似乎解决了上面的用例:
1)建议者自动完成:
https://www.elastic.co/guide/en/elasticsearch/reference/1.7/search-suggesters-completion.html
有了这个,似乎我必须添加另一个名为&#34的字段;建议"复制不可取的数据。
2)使用前缀过滤器/查询:
https://www.elastic.co/guide/en/elasticsearch/reference/1.7/query-dsl-prefix-filter.html
这使得整个文档不再是完全匹配的术语。
有没有一种干净的方法来实现这一点,请告知。
答案 0 :(得分:1)
不要单独创建映射,直接将数据插入索引。它将为此创建默认映射。使用以下查询进行自动完成。
GET /netflix/movie/_search
{
"query": {
"query_string": {
"query": "sta*"
}
}
}
答案 1 :(得分:1)
我认为completion suggester
是最干净的方法,但如果不合适,可以在名称字段中使用aggregations。
这是一个示例索引(我假设您使用的是 ES 1.7
PUT netflix
{
"settings": {
"analysis": {
"analyzer": {
"prefix_analyzer": {
"tokenizer": "keyword",
"filter": [
"lowercase",
"trim",
"edge_filter"
]
},
"keyword_analyzer": {
"tokenizer": "keyword",
"filter": [
"lowercase",
"trim"
]
}
},
"filter": {
"edge_filter": {
"type": "edge_ngram",
"min_gram": 1,
"max_gram": 20
}
}
}
},
"mappings": {
"movie":{
"properties": {
"name":{
"type": "string",
"fields": {
"prefix":{
"type":"string",
"index_analyzer" : "prefix_analyzer",
"search_analyzer" : "keyword_analyzer"
},
"raw":{
"type": "string",
"analyzer": "keyword_analyzer"
}
}
},
"tags":{
"type": "string", "index": "not_analyzed"
}
}
}
}
}
使用multi-fields, name 字段以不同方式进行分析。 name.prefix 正在keyword tokenizer使用edge ngram filter 所以字符串星球大战可以分解为 s , st , sta 等,但在搜索时, keyword_analyzer ,以便搜索查询不会被分解为多个小标记。 name.raw 将用于聚合。
以下查询将提供前10个建议。
GET netflix/movie/_search
{
"query": {
"filtered": {
"filter": {
"term": {
"tags": "sci-fi"
}
},
"query": {
"match": {
"name.prefix": "sta"
}
}
}
},
"size": 0,
"aggs": {
"unique_movie_name": {
"terms": {
"field": "name.raw",
"size": 10
}
}
}
}
结果将类似于
"aggregations": {
"unique_movie_name": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "star trek",
"doc_count": 1
},
{
"key": "star wars",
"doc_count": 1
}
]
}
}
更新:
我认为您可以使用highlighting来实现此目的。突出显示部分将为您提供整个单词以及匹配的字段。您还可以使用inner hits并在其中突出显示以获取嵌套文档。
{
"query": {
"query_string": {
"query": "sta*"
}
},
"_source": false,
"highlight": {
"fields": {
"*": {}
}
}
}