Skip to content
This repository
tag: v4.12.8
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 92 lines (78 sloc) 2.925 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
module Picky

  class Search

    # Returns a list/hash of filtered facets.
    #
    # Params
    # category: The category whose facets to return.
    #
    # Options
    # counts: Whether you want counts (returns a Hash) or not (returns an Array). (Default true)
    # at_least: A minimum count a facet needs to have (inclusive). (Default 1)
    # filter: A query to filter the facets with.
    #
    # Usage:
    # search.facets :name, filter: 'surname:peter', at_least: 2
    #
    def facets category_identifier, options = {}
      # TODO Make it work. How should it work with multiple indexes?
      #
      raise "#{__method__} cannot be used on searches with more than 1 index yet. Sorry!" if indexes.size > 1
      index = indexes.first
      
      # Get index-specific facet counts.
      #
      counts = index.facets category_identifier, options
      
      # We're done if there is no filter.
      #
      return counts unless filter_query = options[:filter]
      
      # Pre-tokenize query token category.
      #
      predefined_categories = [index[category_identifier]]
      
      # Pre-tokenize key token – replace text below.
      # Note: The original is not important.
      #
      # TODO Don't use predefined.
      #
      key_token = Query::Token.new '', nil, predefined_categories
      
      # Pre-tokenize filter for reuse.
      #
      tokenized_filter_query = tokenized filter_query, false
      tokenized_filter_query.tokens.push key_token
      
      # Extract options.
      #
      no_counts = options[:counts] == false
      minimal_counts = options[:at_least] || 1 # Default needs at least one.
      
      # Get actual counts.
      #
      if no_counts
        facets_without_counts counts, minimal_counts, tokenized_filter_query, key_token.text
      else
        facets_with_counts counts, minimal_counts, tokenized_filter_query, key_token.text
      end
    end
    def facets_without_counts counts, minimal_counts, tokenized_filter_query, last_token_text
      counts.inject([]) do |result, (key, _)|
        # Replace only the key token text because that
        # is the only information that changes in between
        # queries.
        #
        last_token_text.replace key
        total = search_with(tokenized_filter_query, 0, 0).total
        
        next result unless total >= minimal_counts
        result << key
      end
    end
    def facets_with_counts counts, minimal_counts, tokenized_filter_query, last_token_text
      counts.inject({}) do |result, (key, _)|
        # Replace only the key token text because that
        # is the only information that changes in between
        # queries.
        #
        last_token_text.replace key
        total = search_with(tokenized_filter_query, 0, 0).total
        
        next result unless total >= minimal_counts
        result[key] = total
        result
      end
    end

  end

end
Something went wrong with that request. Please try again.