Searchkick not searching multiple terms when specify fields Searchkick not searching multiple terms when specify fields elasticsearch elasticsearch

Searchkick not searching multiple terms when specify fields


If all of your fields share the same analyzer, you can use elasticsearch feature called cross_fields. If it is not the case, you can use query_string. Unfortunately searchkick does not support cross_fields and query_string yet. So, you have to do it by yourself.

Index (different analyzers)

searchkick merge_mappings: true, mappings: {  product: {    properties: {      name: {        type: 'string',        analyzer: 'searchkick_word_start_index',        copy_to: 'grouped'      },      manufacturer_name: {        type: 'string',        analyzer: 'default_index',        copy_to: 'grouped'      },      grouped: {        raw: {type: 'string', index: 'not_analyzed'}      }    }  }}

Search with cross_fields

@products = Product.search(body: {  query: {     multi_match: {                  query: query,                  type: "cross_fields",                  operator: "and",                  fields: [                      "name",                      "manufacturer_name",                      "grouped",                  ]              }         }}

Search with query_string

@products = Product.search(body: {  query: {      query_string: {                  query: query,                  default_operator: "AND",                  fields: [                      "name",                      "manufacturer_name",                      "grouped",                  ]              }         }}

Update- Changed my answer to the use of different analyzers and multi fields following the this solution.

Unfortunately passing the query to elasticsearch by yourself you lose searchkick features like highlight and conversions, but, you can still do it, adding it to the elasticsearch query.

Adding hightlight to the query

@products = Product.search(body: {  query: {    ...  }, highlight: {    fields: {      name: {},      manufacturer_name: {}    }  }

Adding conversions to the query

@products = Product.search(body: {  query: {    bool: {      must: {        dis_max: {          queries: {            query_string: {              ...            }          }        }      },      should: {        nested: {          path: 'conversions',          score_mode: 'sum',          query: {            function_score: {              boost_mode: 'replace',              query: {                match: {                  "conversions.query": query                }              },              field_value_factor: {                field: 'conversions.count'              }            }          }        }      }    }  }


The easiest way to do this is to combine the fields into one with the search_data method.

class Product  def search_data    {      full_name: "#{manufacturer_name} #{name}"    }  endend

Be sure to reindex afterwards. Then use full name to search. All of Searchkick's features will continue to work.