2016-10-31 3 views
0

У меня есть эластичный индекс поиска со следующими документами, и я хочу, чтобы иметь функциональные возможности автозаполнения над указанными полями:функциональность автозаполнения с помощью эластичного поиска

отображение: https://gist.github.com/anonymous/0609b1d110d91dceb9a90faa76d1d5d4

USECASE:

Мой запрос является формы типа префикса, например «sta», «star», «star w» .. «начать войну» и т. д. с дополнительным фильтром в качестве тегов = «научная фантастика». Кроме того, запросы могут соответствовать другим полям, таким как описание, исполнители (в поле заливки, а не вложенные). Я также хочу знать, в какой области он подходит.

я исследовал 2 способа для выполнения этого, но не из методов, кажется, для решения выше USECASE:

1) Suggester автозаполнения:

https://www.elastic.co/guide/en/elasticsearch/reference/1.7/search-suggesters-completion.html

С этим, кажется, я должен добавить еще поле «предлагать», реплицируя данные, которые нежелательны.

2) с использованием префикса фильтра/запроса:

https://www.elastic.co/guide/en/elasticsearch/reference/1.7/query-dsl-prefix-filter.html

это дает весь документ обратно не точные условия соответствия.

Есть ли чистый способ достижения этого, пожалуйста, сообщите.

ответ

1

Не создавайте сопоставление отдельно, вставляйте данные непосредственно в индекс. Для этого будет создано сопоставление по умолчанию. Используйте запрос ниже для автозаполнения.

GET /netflix/movie/_search 
{ 
"query": { 
    "query_string": { 
     "query": "sta*" 
    } 
    } 
} 
+0

Спасибо за ответ, но это вернет весь документ, а как только вернуть термины для этого документа в качестве тегов будет длинный список. – user3784881

+0

Можете ли вы поделиться своим сопоставлением –

+0

https://gist.github.com/anonymous/0609b1d110d91dceb9a90faa76d1d5d4 – user3784881

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.prefix использует keyword tokenizer с edge ngram filter так, что строка звездных войн можно разбить на с, ул, 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 
      } 
     ] 
     } 
    } 

UPDATE:

Вы можете использовать highlighting для этой цели, я думаю. В разделе «Выделить» вы получите целое слово и какое поле оно соответствует. Вы также можете использовать inner hits и выделять внутри него, чтобы получить вложенные документы.

{ 
    "query": { 
    "query_string": { 
     "query": "sta*" 
    } 
    }, 
    "_source": false, 
    "highlight": { 
    "fields": { 
     "*": {} 
    } 
    } 
} 
+0

Большое спасибо за ваше решение. Вот полное сопоставление: https://gist.github.com/anonymous/0609b1d110d91dceb9a90faa76d1d5d4. Есть ли способ вернуть поля, в которые он сопоставлен (он также имеет вложенные поля) как часть результата, используя ваше решение или любым другим способом , Еще раз спасибо! – user3784881

+1

Какое требование? хотел бы предложить результаты (автозаполнение) или узнать, какие поля совпадают с запросом пользователя? Я думал, что вы хотите автоматически заполнить название фильма. – ChintanShah25

+0

хотел бы предложить результаты (автозаполнение), а также узнать, из какого поля это предложение пришло, предложение может исходить из названия фильма, а также от имени актера, описания и т. Д. И т. Д., Так что в подсказке автоматически предлагается предложение с тем, что этот объект, например: query = "ar", приводит к 1) "arnold schwarzenegger" как субъект-актер (он соответствует имени актера) 2) аравийские ночи как фильм (так как он соответствует названию фильма). Я очень ценю вашу помощь за то же самое. – user3784881

Смежные вопросы