Search code examples
elasticsearchtire

Multi-word facets (ElasticSearch+Tire)


My model has a tags field, which is an array of tags. The problem I'm having is I want the tags to work like keywords, but ES is somehow breaking them into spaces for the purposes of faceting.

The mapping is:

indexes :tags, type: :array

The query for popular tags is:

tire.search do
  facet 'tags' do
    terms :tags, size: 100
  end
end

Now what results is individual words. e.g. A record tagged ["retro music", "awesome"] will end up having three separate tags. Similarly, if I do a query to search on "retro music" (must { term 'tags', options[:tag] }), that will fail, while a query on "retro" or "music" will succeed. The desired behaviour here is that the tag should be atomic, so only a "retro music" (or "awesome") tag search should succeed.


Solution

  • By default, elasticsearch analyzes strings using the "standard" analyzer, which converts strings to lowercase, splits them into words and removes some frequently occurring words (stopwords). You can prevent elasticsearch from doing all that by turning off analyzer for the field tags:

    indexes :tags, :type => 'string', :index => :not_analyzed