Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

elasticsearch-facetedsearch

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

elasticsearch-facetedsearch

  • 0.0.4
  • Rubygems
  • Socket score

Version published
Maintainers
1
Created
Source

Elasticsearch::FacetedSearch

Code Climate Test Coverage Build Status

Quickly add faceted searching to your Rails app. This gem is opinionated as to how faceted searching works. Filters are applied to the counts so the counts themselves will change while different filters are applied.

Installation

Add this line to your application's Gemfile:

gem 'elasticsearch-facetedsearch'

And then execute:

$ bundle

Create config/initializers/elasticsearch.rb. We normally namespace our indexed like below.

ELASTICSEARCH_INDEX = [
  Rails.env.development? && `whoami`.strip,
  Rails.env,
  Rails.application.class.to_s.split("::").first.downcase
].reject(&:blank?).join('_')

# Optional concepts to help with indexing / connection
ELASTICSEARCH_MODELS = []
ELASTICSEARCH_SERVER = 'http://lalaland.com:9200'

Elasticsearch::Model.client = Elasticsearch::Client.new({
  log: false,
  host: ELASTICSEARCH_SERVER,
  retry_on_failure: 5,
  reload_connections: true
})

Dependencies

Usage

Controller

# Good idea to prefilter the params with strong_params
#
def search
  @search = FruitFacetsSearch.new(params)

  # Fetch results
  # @search.results

  # Fetch facets
  # @search.facets
end

Facet Search Class

class FruitFacetsSearch
  include Elasticsearch::FacetedSearch::FacetBase

  # ... include other facet classes (examples below) ...
  include Elasticsearch::FacetedSearch::FacetColor

  # *required
  # The type to search for (Elasticsearch Type)
  # Can be an Array or String
  def type
    'fruit'
  end

  # Use this to add a query search or something
  # Probably best to cache the results
  def query
    @query ||= super
  end

  # Apply additional pre-filters
  # If overwriting this method, ensure to call super, and ensure to cache the results
  # => require color to be 'blue'
  def filter_query
    @filter_query ||= begin
      fq = super
      fq << { term: { color: 'blue' } }
      fq
    end
  end

  # Force specific limit or allow changable #s
  #
  def limit
    33
  end

  # Whitelisted collection of sortable options
  def sorts
    [
      {
        label: "Relevant",
        value: "relevant",
        search: [
          "_score"
        ],
        default: true
      }
    ]
  end

  # Want to always keep facet counts the same regardless of filters applied?
  # pass true to keep counts scoped to search, & false to remove filters entirely
  #
  def build_facets
    super(false)
  end
end

Facet Creation Class

module Elasticsearch
  module FacetedSearch
    module FacetColor
      extend ActiveSupport::Concern

      included do
        # Adds the facet to the class.facets collection
        #
        # Available types:
        # => facet_multivalue
        # => facet_multivalue_and(:ident, 'elasticsearch_field', 'Human String')
        #     - Allows multiple values, but filters with :and execution
        # => facet_multivalue_or(:ident, 'elasticsearch_field', 'Human String')
        #     - Allows multiple values, but filters with :or execution
        # => facet_exclusive_or(:ident, 'elasticsearch_field', 'Human String')
        #     - Allows single value only
        #
        facet_multivalue_or(:color, 'color_field', 'Skin Color')
      end

      # *required
      # Should we apply the filter for this facet?
      # __Replace 'color' with the :ident value of your facet key
      def filter_color?
        valid_color?
      end

      # *required
      # Returns the array of selected values
      # __Replace 'color' with the :ident value of your facet key
      # __You should really take this time to whitelist the values and remove any noise. Elasticsearch can be picky if you're searching a number field and pass it an alpha character
      def color_value
        return unless valid_color?
        search_params[:color].split( operator_for(:color) )
      end

      # (optional)
      # By default, Elasticsearch only returns terms that are pertaining to the specific search. If a result was filtered out, that term would not show up.
      # Normally this isn't optimal... create this method and return an array of hashes with id and term keys.
      #
      # __Replace 'color' with the :ident value of your facet key
      def color_collection
        @color_collection ||= begin
          Color.all.map{|x| {id: x.id, term: x.name}}
        end
      end

      # (concept)
      # Use these type of helper methods to validate the information given to you by users
      #
      def valid_color?
        search_params[:color].present? && !!(search_params[:color] =~ /[\|[0-9]+]/)
      end
    end
  end
end

Using Sortable

The only requirement to change sort options is to apply a :sort http param

Pagniation

Pagination is supported, but only tested with Kaminari.

HTML

Facets

%ul
  -@search.facets.each do |group|
    %li.title=group.title
    -group.items.each do |item|
      - # Assuming you have some dynamic urls, you can use the url_for and merge in the params
      %li=item.link_to("#{item.term} (#{item.count})", url_for(params.merge(item.params_for)))

Results

%ul
  -@search.results.each do |item|
    - # item is now direct reference to the elastic search _source
    - # item also contains item._type that displays the Elasticsearch type field
    %li=item.id

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

TODO

  • Setup facet generator

FAQs

Package last updated on 18 Jan 2016

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc