4

I have a Piece model with a boolean attribute of published.

I want the search results to only contain Pieces that are plublished: true.

My index action for the PiecesController is:

def index
    @list = params[:list]
    @sort = params[:sort]
    if params[:q]
      @pieces = Piece.search(params[:q]).records
    else
      @pieces = Piece.all_in_category(@list, @sort)
    end
end

From searching around it seems that I should overwrite the search method in the Piece controller but I am not sure the correct way of doing this to maintain the current search methods functionality.

What is the best way to filter the elasticsearch results using the elasticsearch-rails gem?

Cu1ture
  • 1,273
  • 1
  • 14
  • 29
  • does adding a scope to `Piece` work? eg. `scope :published, -> {where(published: true)}` and then calling `Piece.published.search(params[:q]).records`? I have limited experience with elastic but it is very well [documented](https://www.elastic.co/guide/en/elasticsearch/client/ruby-api/current/index.html) so I would start there. – engineersmnky Jun 30 '15 at 17:46
  • No unfortunately not, I did try that but had no luck. I haven't been able to work out how the gem api lets you assign the filter property that the elasticsearch documentation talks about. I may end up switching to the chewy gem instead at this rate :) – Cu1ture Jun 30 '15 at 17:49
  • Yeah it sound like you will need to modify the hash that is passed in which means it might be easier to just build the hash and inject the appropriate query methods. This I can help with if you show me what your search object `params[:q]` looks like. Or checkout [`elastic-scopes`](http://elastics.github.io/elastics/doc/3-elastics-scopes/1-Overview.html) as it seems to modify AR scope to fit nicely with `elasticsearch` – engineersmnky Jun 30 '15 at 19:02

2 Answers2

2

Try this format:

Elasticsearch v2.4

@customers = Customer.__elasticsearch__.search(
        query: { 
          bool: {
            filter: {
              term: {"account_id" => current_account.id.to_s}
            },
            must: {
              query_string: {
                query: "*#{params[:q]}*"
              }
            }
          },
        },
        size: options[:per_page],
        from: options[:from]
      ).records
Aaron Breckenridge
  • 1,723
  • 18
  • 25
-1

have you tried

@pieces = Piece.search(params[:q]).records.where(published: true)

it works on one of my ES models

CoupDeMistral
  • 188
  • 1
  • 9
  • 6
    Yes this works however it is filtering the records in the sql db query rather than the elasticsearch index query. I would prefer to do it in the elasticsearch query to prevent loading unnecessary query data and taking advantage of the elasticsearch index filter abilities. I've decided to switch to the chewy gem now because this has a really neat api for filtering queries thats much more accessible. – Cu1ture Jun 30 '15 at 21:27
  • Brilliant solution. Thanks a lot! – Stef Hej Jul 06 '16 at 20:57
  • 1
    We need to filter on elasticsearch. Not a solution in most cases. – freeze Jul 25 '19 at 10:20