-->

tire terms filter not working

2019-06-07 06:11发布

问题:

I'm trying to achieve a "scope-like" function with tire/elasticsearch. Why is this not working, even when i have entries with status "Test1" or "Test2"? The results are always empty.

  collection = @model.search(:page => page, :per_page => per_page) do |s|
    s.query {all}
    s.filter :terms, :status => ["Test1", "Test2"]
    s.sort {by :"#{column}", "#{direction}"}
  end 

The method works fine without the filter. Is something wrong with the filter method?! I've checked the tire doku....it should work.

Thanks! :)

回答1:

Your issue is most probably being caused by using the default mappings for the status field, which would tokenize it -- downcase, split into words, etc.

Compare these two:

http://localhost:9200/myindex/_analyze?text=Text1&analyzer=standard

http://localhost:9200/myindex/_analyze?text=Text1&analyzer=keyword

The solution in your case is to use the keyword analyzer (or set the field to not_analyzed) in your mapping. When the field would not be an “enum” type of data, you could use the multi-field feature.

A working Ruby version would look like this:

require 'tire'

Tire.index('myindex') do
  delete
  create mappings: {
    document: {
      properties: {
        status: { type: 'string', analyzer: 'keyword' }
      }
    }
  }

  store status: 'Test1'
  store status: 'Test2'

  refresh
end

search = Tire.search 'myindex' do
  query do
    filtered do
      query { all }
      filter :terms, status: ['Test1']
    end
  end
end

puts search.results.to_a.inspect

Note: It's rarely possible -- this case being an exception -- to offer reasonable advice when no index mappings, example data, etc. are provided.