2016-05-10 2 views
0

я могу реально выполнить простой поиск совпадения с этим:ElasticSearch матч несколько полей с различными значениями

query: {match: {searchable: {query:search}}} 

Это хорошо работает, мой поиск поле анализируется в моем отображении.

Теперь я хочу выполнить поиск по нескольким полям: 1 строка, а все остальные - числовые.

Мое отображение:

mappings dynamic: 'false' do 
     indexes :searchable, analyzer: "custom_index_analyzer", search_analyzer: "custom_search_analyzer" 
     indexes :year, type: "integer" 
     indexes :country_id, type: "integer" 
     indexes :region_id, type: "integer" 
     indexes :appellation_id, type: "integer" 
     indexes :category_id, type: "integer" 
     end 

def as_indexed_json(options={}) 
     as_json(
     only: [:searchable, :year, :country_id, :region_id, :appellation_id, :category_id] 
    ) 
    end 

Я попытался это:

query: { 
        filtered: { 
         query: { 
         match: { 
          searchable: search 
         } 
         }, 
         filter: { 
         term: { 
          country_id: "1" 
         }, 
         term: { 
          region_id: "2" 
         }, 
         term: { 
          appellation_id: "34" 
         } 
         } 
        } 
        }, 
        sort: { 
        _score: { 
         order: :desc 
        }, 
        year: { 
         order: :desc, 
         ignore_unmapped: true 
        } 
        }, 
        size:100 

Он хорошо работает, но это даст мне 100 результатов во всех случаях из appellation_id посланного (34), даже если поле поиска находится очень далеко от текстового поиска.

Я также попробовал BOOL запрос:

self.search(query: { 
       bool: { 
        must: [ 
        { 
         match: { 
          country_id: "1" 
          }, 
          match: { 
          region_id: "2" 
          }, 
          match: { 
          appellation_id: "34" 
          }, 
          match: { 
          searchable: search 
          } 
        } 
        ] 
       } 
       }, 
       sort: { 
       _score: { 
        order: :desc 
       }, 
       year: { 
        order: :desc, 
        ignore_unmapped: true 
       } 
       }, 
       size:100 
      ) 

Но это даст мне все результаты, соответствующие для поиска поля и не заботиться о appellation_id хотел.

Моя цель - получить наилучшие результаты и производительность и попросить ES предоставить мне все данные из country_id = X, region_id = Y, appellation_id = Z и, наконец, выполнить сопоставление этого набора результатов с полем поиска. и не получают результатов, далеких от реальности, с помощью текста, доступного для поиска.

Спасибо.

ответ

0

Как вы можете знать elasticsearch match Запрос возвращает результат на основе relevance score. Вы можете попытаться использовать запрос term вместо соответствия для точного совпадения сроков. Также я предполагаю, что ваша структура запросов bool должна быть такой:

bool: { 
     must: [ 
      { match: { 
       country_id: "1" 
       }}, 
      {match: { 
      region_id: "2" 
      }}, 
      {match: { 
      appellation_id: "34" 
      }}, 
      {match: { 
      searchable: search 
      }} 
     ] 
    } 
+0

Alpert, It хорошо работает с вашей новой структурой (double {} вокруг соответствия). Я также попробовал ** ** ** вместо ** match ** и получить те же оценки. Так что спасибо. Моя единственная проблема заключается в поле поиска (для сопоставления используются ngrams): как остановить результаты, если найденные термины не являются ожидаемыми? Например, поиск «beaulieu» даст 2 приятных результата и 98 очень далек от этого слова. Скоринг подскочил с 11 до 2 ... но это зависит от условий поиска. –

+0

Я могу использовать параметр min_score, но это произвольный шаблон. –

+0

Проверьте, будет ли minimum_should_match работать для вас: https://www.elastic.co/guide/en/elasticsearch/guide/current/ngrams-compound-words.html – alpert

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