ruby-on-railsrubyelasticsearchruby-on-rails-5elasticsearch-rails

ElasticSearch - Pass Array of Terms to Filter


I have a query where I would like to pass a dynamic amount of terms to the filter. Is there anyway to pass this as an array? I've tried several different things but always end up with a malformed request error from elasticsearch. I'm using Ruby on Rails with the elasticsearch-rails gem. Here is my query:

@products = Product.search(
     query:{
       function_score:{
         query:{
           bool:{
             must:{
               multi_match:{
                 fields: ['brand^5', '_all'],
                 query: "#{query}",
                 fuzziness: "AUTO"
               }
             },

               filter:{
                 bool:{
                   must:[
                     {term: {"brand":"NordicTrack"}},
                     {term: {"product_type":"Treadmill"}}
                   ]
                 }
               }

           }
         },
         field_value_factor:{
            field: "popularity",
            modifier: "log1p"
         }
       }
     }).page(page).per(25)

I would like to pass an array like this:

array = ['{term: {"brand":"NordicTrack"}}', {term: {"product_type":"Treadmill"}}]

Into the "must" statement like this:

 @products = Product.search(
     query:{
       function_score:{
         query:{
           bool:{
             must:{
               multi_match:{
                 fields: ['brand^5', '_all'],
                 query: "#{query}",
                 fuzziness: "AUTO"
               }
             },

               filter:{
                 bool:{
                   must: array
                 }
               }

           }
         },
         field_value_factor:{
            field: "popularity",
            modifier: "log1p"
         }
       }
     }).page(page).per(25)

However, this causes a malformed request error by ES.


Solution

  • Ensure that your array elements are not strings. Your example shows:

    array = ['{term: {"brand":"NordicTrack"}}', {term: {"product_type":"Treadmill"}}]
    

    It should be:

    array = [{term: {"brand":"NordicTrack"}}, {term: {"product_type":"Treadmill"}}]
    

    If you are building the array in ruby, it should look something like this:

    array = []
    array.push term: {"brand":"NordicTrack"}
    array.push term: {"product_type":"Treadmill"}