2013-08-23 6 views
7

У меня есть индекс местоположения, в котором много названий мест и их соответствующих стран.Точные совпадения с ElasticSearch (во время запроса)

Затем я хочу знать, имеются ли у нас местоположения с названием «Берлин» в стране с кодом страны «DE».

Вот мой код Java попытка:

SearchResponse response = client.prepareSearch("locations") 
       .setQuery(QueryBuilders.matchQuery("title", "Berlin")) 
       .setFilter(FilterBuilders.termFilter("country", "DE")) 
       .execute() 
       .actionGet(); 

Но это дает мне слишком много ответов, например, поиска для "Zoo Berlin" и т. д. Мне нужны точные соответствия.

(Но обратите внимание, что у меня есть другие сценарии, в которых желательны эта подстроке/поиск текста соответствие.)

Есть ли способ, чтобы решить, на запрашивая время, а не во время индексации, какое поведение (точный против проанализировано текст) хочет?

+0

Точное совпадение, вы имеете в виду «берлин», должно соответствовать «Берлину»? – ramseykhalaf

+0

Да, например. (И я не слишком много отношусь к делу.) Но если «Берлин» совпадает с «Berlin Hauptbahnhof», это проблематично. –

ответ

10

Укажите поле, в котором вы выполняете фильтр условий, как not_analyzed. Например, вы можете индексировать поле «страна», как multi_field, с одним из подполея not_analyzed:

 "country": { 
      "type": "multi_field", 
      "fields": { 
       "country": {"type": "string", "index": "analyzed"}, 
       "exact": {"type": "string","index": "not_analyzed"} 
      } 
     } 

Кроме того, вы могли бы сделать то же самое с «названием» полем для выполнения срока запрос:

 "title": { 
      "type": "multi_field", 
      "fields": { 
       "title": {"type": "string", "index": "analyzed"}, 
       "exact": {"type": "string","index": "not_analyzed"} 
      } 
     } 

Затем во время запроса, если вы хотите получить титул с точным термином «Берлин» фильтруется точным термином «DE», использует термин запрос и термин фильтр с not_analyzed полями:

SearchResponse response = client.prepareSearch("locations") 
       .setQuery(QueryBuilders.termQuery("title.exact", "Berlin")) 
       .setFilter(FilterBuilders.termFilter("country.exact", "DE")) 
       .execute() 
       .actionGet(); 

Обратите внимание, что term filters и term queries требуют, чтобы поля not_analyzed работали (т. Е. Возвращали точные соответствия).

+2

Есть ли способ выполнить not_analyzed запрос во время запроса, не изменяя отображение? –

+0

Не уверен.Вы можете использовать API обновления, чтобы добавить анализатор в свой индекс и указать этот анализатор во время запроса. См. Этот вопрос [SO вопрос] (http://stackoverflow.com/questions/11657505/defining-analyzer-while-querying-in-elasticsearch). Однако я не знаю, можно ли указать индекс: not_analyzed без изменения отображения. –

+0

Согласно http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/_finding_exact_values.html сопоставление должно быть изменено («Сначала требуется удаление индекса, поскольку мы не можем изменять отображаемые отображения».) –

0

С версией 5 + на ElasticSearch нет понятия анализируемого и не анализируемого для индекса, его управляемый по типу!

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

Но если тип данных определяется как ключевое слово, то автоматически его НЕ анализирует и возвращает полное точное соответствие.

Так что вы должны помнить о том, как указывать ключевое слово типа, если вы хотите сделать точное совпадение.

, и вы можете использовать один и тот же термин запрос и фильтр терминов, как объясняется @Scott Rice.

Пример кода ниже для создания индекса с этим определением, обратите внимание, что я создал два типа для каждого поля в качестве токенизируемого, так что тип - это текст, а другой - точный, поэтому type - это ключевое слово, иногда его полезно хранить как для определенных полей :

PUT testindex 
{ 
    "mappings": { 
     "original": { 
     "properties": { 
      "@timestamp": { 
      "type": "date" 
      }, 
      "@version": { 
      "type": "text", 
      "fields": { 
       "keyword": { 
       "type": "keyword", 
       "ignore_above": 256 
       } 
      } 
      }, 
      "APPLICATION": { 
      "type": "text", 
      "fields": { 
       "token": {"type": "text"}, 
       "exact": {"type": "keyword"} 
      } 
      }, 
      "type": { 
      "type": "text", 
      "fields": { 
       "token": {"type": "text"}, 
       "exact": {"type": "keyword"} 
      } 
      } 
     } 
     } 
    } 
    } 
Смежные вопросы