2016-11-11 3 views
4

У меня есть следующие данные для индексации на ElasticSearch.Выделить на ElasticSearch autocomplete

enter image description here

Я хочу реализовать функцию автозаполнения, и подчеркнуть, почему конкретный документ соответствует запросу.

Это те настройки моего индекса:

{ 
    "settings": { 
     "number_of_shards": 1, 
     "analysis": { 
      "filter": { 
       "autocomplete_filter": { 
        "type":  "edge_ngram", 
        "min_gram": 1, 
        "max_gram": 15 
       } 
      }, 
      "analyzer": { 
       "autocomplete": { 
        "type":  "custom", 
        "tokenizer": "standard", 
        "filter": [ 
         "autocomplete_filter" 
        ] 
       } 
      } 
     } 
    } 
} 

Index Анализ

  • Splits текст на границах слов.
  • Удаляет pontuation.
  • нижний регистр
  • Край NGrams каждый маркер

Так индекс Перевернутый выглядит следующим образом:

enter image description here

Это, как я определил отображения для поля имя:

{ 
    "index_type": { 
     "properties": { 
      "name": { 
       "type":  "string", 
       "index_analyzer": "autocomplete", 
       "search_analyzer": "standard" 
      } 
     } 
    } 
} 

Когда я запрашиваю:

GET http://localhost:9200/index/type/_search 

{ 
    "query": { 
     "match": { 
      "name": "soft" 
     } 
    }, 
    "highlight": { 
     "fields" : { 
      "name" : {} 
     } 
    } 
} 

Поиск: мягкой

Применение стандартного Tokenizer, "мягкий" это термин, чтобы найти на инвертированном индексе. Этот поиск соответствует Документы: 1, 3, 4, 5, 6, 7, который является правильным, но Выделенная часть я бы ожидать, чтобы быть «мягким», а не целое слово:

{ 
    "hits": [ 
    { 
     "_source": { 
     "name": "SoftwareRocks everytime" 
     }, 
     "highlight": { 
     "name": [ 
      "<em>SoftwareRocks</em> everytime" 
     ] 
     } 
    }, 
    { 
     "_source": { 
     "name": "Software AG" 
     }, 
     "highlight": { 
     "name": [ 
      "<em>Software</em> AG" 
     ] 
     } 
    }, 
    { 
     "_source": { 
     "name": "Software AG2" 
     }, 
     "highlight": { 
     "name": [ 
      "<em>Software</em> AG2" 
     ] 
     } 
    }, 
    { 
     "_source": { 
     "name": "Op Software AG good software better" 
     }, 
     "highlight": { 
     "name": [ 
      "Op <em>Software</em> AG good <em>software</em> better" 
     ] 
     } 
    }, 
    { 
     "_source": { 
     "name": "Op Software AG" 
     }, 
     "highlight": { 
     "name": [ 
      "Op <em>Software</em> AG" 
     ] 
     } 
    }, 
    { 
     "_source": { 
     "name": "is soft ware ok" 
     }, 
     "highlight": { 
     "name": [ 
      "is <em>soft</em> ware ok" 
     ] 
     } 
    } 
    ] 
} 

Поиск: Software AG

Применение стандартного Tokenizer, то "Software AG" превращается в "программное обеспечение" и "ж", чтобы найти на инвертированного индекса. Этот поиск соответствует документам: 1, 3, 4, 5, 6, что является правильным, но выделенная часть, которую я ожидал бы быть «программным обеспечением» и «аг», а не всем словом «программное обеспечение» и «аг»:

{ 
    "hits": [ 
    { 
     "_source": { 
     "name": "Software AG" 
     }, 
     "highlight": { 
     "name": [ 
      "<em>Software</em> <em>AG</em>" 
     ] 
     } 
    }, 
    { 
     "_source": { 
     "name": "Software AG2" 
     }, 
     "highlight": { 
     "name": [ 
      "<em>Software</em> <em>AG2</em>" 
     ] 
     } 
    }, 
    { 
     "_source": { 
     "name": "Op Software AG" 
     }, 
     "highlight": { 
     "name": [ 
      "Op <em>Software</em> <em>AG</em>" 
     ] 
     } 
    }, 
    { 
     "_source": { 
     "name": "Op Software AG good software better" 
     }, 
     "highlight": { 
     "name": [ 
      "Op <em>Software</em> <em>AG</em> good <em>software</em> better" 
     ] 
     } 
    }, 
    { 
     "_source": { 
     "name": "SoftwareRocks everytime" 
     }, 
     "highlight": { 
     "name": [ 
      "<em>SoftwareRocks</em> everytime" 
     ] 
     } 
    } 
    ] 
} 

Я прочитал документацию блика на elasticsearch, но я не могу понять, как выполняются подсветка. Для двух приведенных выше примеров я ожидаю, что будет выделен только согласованный токен инвертированного индекса, а не целое слово. Может ли кто-нибудь помочь, как выделить только прошедшее значение?

Update

Итак, кажется, что на ElasticSearch сайте, автозаполнения на стороне сервера похожи на мою реализацию. Однако кажется, что они выделяют согласованный запрос на клиенте. Если они это сделают, я начал думать, что на ElasticSearch нет правильного решения, поэтому я реализовал функцию выделения на стороне сервера, а не на стороне клиента (как они, кажется, делают).

Моя реализация на стороне сервера (с помощью PHP) является:

public function search($term) 
{ 
    $params = [ 
     'index' => $this->getIndexName(), 
     'type' => $this->getIndexType(), 
     'body' => [ 
      'query' => [ 
       'match' => [ 
        'name' => $term 
       ] 
      ] 
     ] 
    ]; 

    $results = $this->client->search($params); 

    $hits = $results['hits']['hits']; 

    $data = []; 

    $wrapBefore = '<strong>'; 
    $wrapAfter = '</strong>'; 

    foreach ($hits as $hit) { 
     $data[] = [ 
      $hit['_source']['id'], 
      $hit['_source']['name'], 
      preg_replace("/($term)/i", "$wrapBefore$1$wrapAfter", strip_tags($hit['_source']['name'])) 
     ]; 
    } 

    return $data; 
} 

выходов я направленных с этим вопросом:

enter image description here

Я добавил щедрот, чтобы увидеть, если есть решение на уровне ElasticSearch для достижения того, что я описал выше.

+0

Вы пробовали двойную цитату? например '' \ "soft \" "' Я подозреваю, что это может быть тот вид поиска, который вы там делаете, что может сделать разницу. – gerosalesc

+0

Вы пытались [принудительно выделить источник] (https://www.elastic.co /guide/en/elasticsearch/reference/current/search-request-highlighting.html#_force_highlighting_on_source), указав «force_source»: true'? – Val

+0

Также вы можете также увидеть [префиксный запрос] (https://www.elastic.co/guide/en/elasticsearch/guide/current/prefix-query.html) для «мягкого» примера – gerosalesc

ответ

1

На данный момент с последней версией эластичности это невозможно, так как документация высокого уровня не содержит никаких настроек или запросов для этого. Я проверил пример эластичного автозаполнения в консоли браузера на вкладке xhr requests и нашел ответ для ответа на запрос «att» автозаполнения для ключевого слова следующим образом.

url - https://search.elastic.co/suggest?q=att 
    { 
     "current_page": 1, 
     "last_page": 4, 
     "total_hits": 49, 
     "hits": [ 
      { 
       "tags": [], 
       "url": "/elasticon/tour/2016/jp/not-attending", 
       "section": "Elasticon", 
       "title": "Not <em>Attending</em> - JP" 
      }, 
      { 
       "section": "Elasticon", 
       "title": "<em>Attending</em> from Training - JP", 
       "tags": [], 
       "url": "/elasticon/tour/2016/jp/attending-training" 
      }, 
      { 
       "tags": [], 
       "url": "/elasticon/tour/2016/jp/attending-keynote", 
       "title": "<em>Attending</em> from Keynote - JP", 
       "section": "Elasticon" 
      }, 
      { 
       "tags": [], 
       "url": "/elasticon/tour/2016/not-attending", 
       "section": "Elasticon", 
       "title": "Thank You - Not <em>Attending</em>" 
      }, 
      { 
       "tags": [], 
       "url": "/elasticon/tour/2016/attending", 
       "section": "Elasticon", 
       "title": "Thank You - <em>Attending</em>" 
      }, 
      { 
       "section": "Blog", 
       "title": "What It's Like to <em>Attend</em> Elastic Training", 
       "tags": [], 
       "url": "/blog/what-its-like-to-attend-elastic-training" 
      }, 
      { 
       "tags": "Elasticsearch", 
       "url": "/guide/en/elasticsearch/plugins/5.0/mapper-attachments-highlighting.html", 
       "section": "Docs/", 
       "title": "Highlighting <em>attachments</em>" 
      }, 
      { 
       "title": "<em>attachments</em> » email", 
       "section": "Docs/", 
       "tags": "Logstash", 
       "url": "/guide/en/logstash/5.0/plugins-outputs-email.html#plugins-outputs-email-attachments" 
      }, 
      { 
       "section": "Docs/", 
       "title": "Configuring Email <em>Attachments</em> » Actions", 
       "tags": "Watcher", 
       "url": "/guide/en/watcher/2.4/actions.html#configuring-email-attachments" 
      }, 
      { 
       "url": "/guide/en/watcher/2.4/actions.html#hipchat-action-attributes", 
       "tags": "Watcher", 
       "title": "HipChat Action <em>Attributes</em> » Actions", 
       "section": "Docs/" 
      }, 
      { 
       "title": "Slack Action <em>Attributes</em> » Actions", 
       "section": "Docs/", 
       "tags": "Watcher", 
       "url": "/guide/en/watcher/2.4/actions.html#slack-action-attributes" 
      } 
     ], 
     "aggs": { 
      "sections": [ 
       { 
        "Elasticon": 5 
       }, 
       { 
        "Blog": 1 
       }, 
       { 
        "Docs/": 43 
       } 
      ], 
      "top_tags": [ 
       { 
        "XPack": 14 
       }, 
       { 
        "Elasticsearch": 12 
       }, 
       { 
        "Watcher": 9 
       }, 
       { 
        "Logstash": 4 
       }, 
       { 
        "Clients": 3 
       }, 
       { 
        "Shield": 1 
       } 
      ] 
     } 
    } 

Но на интерфейсе они показывают «att», только подсвеченные в результатах аутсорсинга. Следовательно, они обрабатывают элементы подсветки на уровне браузера.

+0

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

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