Class: Solr::Facet

Inherits:
Object show all
Includes:
Comparable
Defined in:
lib/solr/facet.rb

Overview

A representation of a Solr facet

Solr facets arrive in a variety of formats, and thus have to be parsed in a variety of ways. This class attempts to handle all of that in the most generic and extensible way possible.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Facet

Create a new facet

We can either get a string-format query, or (from RSolr::Ext) a facet object and an item object. This handles dealing with all of that. We will get either :name, :value, and :hits (a facet parameter), or :query and :hits (a facet query).

Options Hash (options):

  • :name (Symbol)

    The field being faceted on

  • :value (String)

    The facet value

  • :hits (Integer)

    Number of hits for this facet

  • :query (String)

    Facet as a string query



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
92
# File 'lib/solr/facet.rb', line 39

def initialize(options = {})
  if options[:query]
    # We already have a query here, so go ahead and save the query
    @query = options[:query]

    fail ArgumentError, 'facet query specified without hits' unless options[:hits]
    @hits = Integer(options[:hits])

    # Basic format: "field:QUERY"
    parts = @query.split(':')
    fail ArgumentError, 'facet query not separated by colon' unless parts.count == 2

    @field = parts[0].to_sym
    @value = parts[1]

    # Strip quotes from the value if present
    @value = @value[1..-2] if @value[0] == '"' && @value[-1] == '"'

    # Format the label according to the field type -- for now, the only
    # argument type is year, so raise an error otherwise
    fail ArgumentError, "do not know how to handle facet queries for #{@field}" unless @field == :year
    format_year_label

    return
  end

  # We need to have name, value, and hits
  fail ArgumentError, 'facet specified without name' unless options[:name]
  @field = options[:name].to_sym

  fail ArgumentError, 'facet specified without value' unless options[:value]
  @value = options[:value]

  # Strip quotes from the value if present
  @value = @value[1..-2] if @value[0] == '"' && @value[-1] == '"'

  fail ArgumentError, 'facet specified without hits' unless options[:hits]
  @hits = Integer(options[:hits])

  # Construct the query
  @query = "#{field.to_s}:\"#{value}\""

  # Format the label
  case @field
  when :authors_facet
    @label = @value
    @field_label = I18n.t('search.index.authors_facet_short')
  when :journal_facet
    @label = @value
    @field_label = I18n.t('search.index.journal_facet_short')
  else
    fail ArgumentError, "do not know how to handle facets on #{@field}"
  end
end

Instance Attribute Details

#fieldSymbol



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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/solr/facet.rb', line 24

class Facet
  attr_accessor :query, :field, :value, :hits, :label, :field_label

  # Create a new facet
  #
  # We can either get a string-format query, or (from RSolr::Ext) a facet
  # object and an item object.  This handles dealing with all of that.  We
  # will get either +:name+, +:value+, and +:hits+ (a facet parameter), or
  # +:query+ and +:hits+ (a facet query).
  #
  # @param [Hash] options specification of the new facet
  # @option options [Symbol] :name The field being faceted on
  # @option options [String] :value The facet value
  # @option options [Integer] :hits Number of hits for this facet
  # @option options [String] :query Facet as a string query
  def initialize(options = {})
    if options[:query]
      # We already have a query here, so go ahead and save the query
      @query = options[:query]

      fail ArgumentError, 'facet query specified without hits' unless options[:hits]
      @hits = Integer(options[:hits])

      # Basic format: "field:QUERY"
      parts = @query.split(':')
      fail ArgumentError, 'facet query not separated by colon' unless parts.count == 2

      @field = parts[0].to_sym
      @value = parts[1]

      # Strip quotes from the value if present
      @value = @value[1..-2] if @value[0] == '"' && @value[-1] == '"'

      # Format the label according to the field type -- for now, the only
      # argument type is year, so raise an error otherwise
      fail ArgumentError, "do not know how to handle facet queries for #{@field}" unless @field == :year
      format_year_label

      return
    end

    # We need to have name, value, and hits
    fail ArgumentError, 'facet specified without name' unless options[:name]
    @field = options[:name].to_sym

    fail ArgumentError, 'facet specified without value' unless options[:value]
    @value = options[:value]

    # Strip quotes from the value if present
    @value = @value[1..-2] if @value[0] == '"' && @value[-1] == '"'

    fail ArgumentError, 'facet specified without hits' unless options[:hits]
    @hits = Integer(options[:hits])

    # Construct the query
    @query = "#{field.to_s}:\"#{value}\""

    # Format the label
    case @field
    when :authors_facet
      @label = @value
      @field_label = I18n.t('search.index.authors_facet_short')
    when :journal_facet
      @label = @value
      @field_label = I18n.t('search.index.journal_facet_short')
    else
      fail ArgumentError, "do not know how to handle facets on #{@field}"
    end
  end

  include Comparable

  # Compare facet objects appropriately given their field
  #
  # In general, this sorts first by count and then by value.
  #
  # @param [Facet] other object for comparison
  # @return [Integer] -1, 0, or 1, appropriately
  def <=>(other)
    return -(@hits <=> other.hits) if hits != other.hits

    # We want years to sort inverse, while we want others normal.
    return -(@value <=> other.value) if field == :year
    (@value <=> other.value)
  end

  private

  # Format a label suitable for displaying a year facet
  #
  # Requires @value to be set, and will set @label and @field_label.
  #
  # @api private
  def format_year_label
    # We need to parse the decade out of "[X TO Y]"
    value_without_brackets = @value[1..-2]

    parts = value_without_brackets.split
    fail ArgumentError, 'year query does not follow correct format' unless parts.count == 3

    decade = parts[0]
    decade = '1790' if decade == '*'
    decade = Integer(decade)

    if decade == 1790
      @label = I18n.t('search.index.year_before_1800')
    elsif decade == 2010
      @label = I18n.t('search.index.year_after_2010')
    else
      @label = "#{decade}#{decade + 9}"
    end

    @field_label = I18n.t('search.index.year_facet_short')
  end
end

#field_labelString



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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/solr/facet.rb', line 24

class Facet
  attr_accessor :query, :field, :value, :hits, :label, :field_label

  # Create a new facet
  #
  # We can either get a string-format query, or (from RSolr::Ext) a facet
  # object and an item object.  This handles dealing with all of that.  We
  # will get either +:name+, +:value+, and +:hits+ (a facet parameter), or
  # +:query+ and +:hits+ (a facet query).
  #
  # @param [Hash] options specification of the new facet
  # @option options [Symbol] :name The field being faceted on
  # @option options [String] :value The facet value
  # @option options [Integer] :hits Number of hits for this facet
  # @option options [String] :query Facet as a string query
  def initialize(options = {})
    if options[:query]
      # We already have a query here, so go ahead and save the query
      @query = options[:query]

      fail ArgumentError, 'facet query specified without hits' unless options[:hits]
      @hits = Integer(options[:hits])

      # Basic format: "field:QUERY"
      parts = @query.split(':')
      fail ArgumentError, 'facet query not separated by colon' unless parts.count == 2

      @field = parts[0].to_sym
      @value = parts[1]

      # Strip quotes from the value if present
      @value = @value[1..-2] if @value[0] == '"' && @value[-1] == '"'

      # Format the label according to the field type -- for now, the only
      # argument type is year, so raise an error otherwise
      fail ArgumentError, "do not know how to handle facet queries for #{@field}" unless @field == :year
      format_year_label

      return
    end

    # We need to have name, value, and hits
    fail ArgumentError, 'facet specified without name' unless options[:name]
    @field = options[:name].to_sym

    fail ArgumentError, 'facet specified without value' unless options[:value]
    @value = options[:value]

    # Strip quotes from the value if present
    @value = @value[1..-2] if @value[0] == '"' && @value[-1] == '"'

    fail ArgumentError, 'facet specified without hits' unless options[:hits]
    @hits = Integer(options[:hits])

    # Construct the query
    @query = "#{field.to_s}:\"#{value}\""

    # Format the label
    case @field
    when :authors_facet
      @label = @value
      @field_label = I18n.t('search.index.authors_facet_short')
    when :journal_facet
      @label = @value
      @field_label = I18n.t('search.index.journal_facet_short')
    else
      fail ArgumentError, "do not know how to handle facets on #{@field}"
    end
  end

  include Comparable

  # Compare facet objects appropriately given their field
  #
  # In general, this sorts first by count and then by value.
  #
  # @param [Facet] other object for comparison
  # @return [Integer] -1, 0, or 1, appropriately
  def <=>(other)
    return -(@hits <=> other.hits) if hits != other.hits

    # We want years to sort inverse, while we want others normal.
    return -(@value <=> other.value) if field == :year
    (@value <=> other.value)
  end

  private

  # Format a label suitable for displaying a year facet
  #
  # Requires @value to be set, and will set @label and @field_label.
  #
  # @api private
  def format_year_label
    # We need to parse the decade out of "[X TO Y]"
    value_without_brackets = @value[1..-2]

    parts = value_without_brackets.split
    fail ArgumentError, 'year query does not follow correct format' unless parts.count == 3

    decade = parts[0]
    decade = '1790' if decade == '*'
    decade = Integer(decade)

    if decade == 1790
      @label = I18n.t('search.index.year_before_1800')
    elsif decade == 2010
      @label = I18n.t('search.index.year_after_2010')
    else
      @label = "#{decade}#{decade + 9}"
    end

    @field_label = I18n.t('search.index.year_facet_short')
  end
end

#hitsInteger



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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/solr/facet.rb', line 24

class Facet
  attr_accessor :query, :field, :value, :hits, :label, :field_label

  # Create a new facet
  #
  # We can either get a string-format query, or (from RSolr::Ext) a facet
  # object and an item object.  This handles dealing with all of that.  We
  # will get either +:name+, +:value+, and +:hits+ (a facet parameter), or
  # +:query+ and +:hits+ (a facet query).
  #
  # @param [Hash] options specification of the new facet
  # @option options [Symbol] :name The field being faceted on
  # @option options [String] :value The facet value
  # @option options [Integer] :hits Number of hits for this facet
  # @option options [String] :query Facet as a string query
  def initialize(options = {})
    if options[:query]
      # We already have a query here, so go ahead and save the query
      @query = options[:query]

      fail ArgumentError, 'facet query specified without hits' unless options[:hits]
      @hits = Integer(options[:hits])

      # Basic format: "field:QUERY"
      parts = @query.split(':')
      fail ArgumentError, 'facet query not separated by colon' unless parts.count == 2

      @field = parts[0].to_sym
      @value = parts[1]

      # Strip quotes from the value if present
      @value = @value[1..-2] if @value[0] == '"' && @value[-1] == '"'

      # Format the label according to the field type -- for now, the only
      # argument type is year, so raise an error otherwise
      fail ArgumentError, "do not know how to handle facet queries for #{@field}" unless @field == :year
      format_year_label

      return
    end

    # We need to have name, value, and hits
    fail ArgumentError, 'facet specified without name' unless options[:name]
    @field = options[:name].to_sym

    fail ArgumentError, 'facet specified without value' unless options[:value]
    @value = options[:value]

    # Strip quotes from the value if present
    @value = @value[1..-2] if @value[0] == '"' && @value[-1] == '"'

    fail ArgumentError, 'facet specified without hits' unless options[:hits]
    @hits = Integer(options[:hits])

    # Construct the query
    @query = "#{field.to_s}:\"#{value}\""

    # Format the label
    case @field
    when :authors_facet
      @label = @value
      @field_label = I18n.t('search.index.authors_facet_short')
    when :journal_facet
      @label = @value
      @field_label = I18n.t('search.index.journal_facet_short')
    else
      fail ArgumentError, "do not know how to handle facets on #{@field}"
    end
  end

  include Comparable

  # Compare facet objects appropriately given their field
  #
  # In general, this sorts first by count and then by value.
  #
  # @param [Facet] other object for comparison
  # @return [Integer] -1, 0, or 1, appropriately
  def <=>(other)
    return -(@hits <=> other.hits) if hits != other.hits

    # We want years to sort inverse, while we want others normal.
    return -(@value <=> other.value) if field == :year
    (@value <=> other.value)
  end

  private

  # Format a label suitable for displaying a year facet
  #
  # Requires @value to be set, and will set @label and @field_label.
  #
  # @api private
  def format_year_label
    # We need to parse the decade out of "[X TO Y]"
    value_without_brackets = @value[1..-2]

    parts = value_without_brackets.split
    fail ArgumentError, 'year query does not follow correct format' unless parts.count == 3

    decade = parts[0]
    decade = '1790' if decade == '*'
    decade = Integer(decade)

    if decade == 1790
      @label = I18n.t('search.index.year_before_1800')
    elsif decade == 2010
      @label = I18n.t('search.index.year_after_2010')
    else
      @label = "#{decade}#{decade + 9}"
    end

    @field_label = I18n.t('search.index.year_facet_short')
  end
end

#labelString



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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/solr/facet.rb', line 24

class Facet
  attr_accessor :query, :field, :value, :hits, :label, :field_label

  # Create a new facet
  #
  # We can either get a string-format query, or (from RSolr::Ext) a facet
  # object and an item object.  This handles dealing with all of that.  We
  # will get either +:name+, +:value+, and +:hits+ (a facet parameter), or
  # +:query+ and +:hits+ (a facet query).
  #
  # @param [Hash] options specification of the new facet
  # @option options [Symbol] :name The field being faceted on
  # @option options [String] :value The facet value
  # @option options [Integer] :hits Number of hits for this facet
  # @option options [String] :query Facet as a string query
  def initialize(options = {})
    if options[:query]
      # We already have a query here, so go ahead and save the query
      @query = options[:query]

      fail ArgumentError, 'facet query specified without hits' unless options[:hits]
      @hits = Integer(options[:hits])

      # Basic format: "field:QUERY"
      parts = @query.split(':')
      fail ArgumentError, 'facet query not separated by colon' unless parts.count == 2

      @field = parts[0].to_sym
      @value = parts[1]

      # Strip quotes from the value if present
      @value = @value[1..-2] if @value[0] == '"' && @value[-1] == '"'

      # Format the label according to the field type -- for now, the only
      # argument type is year, so raise an error otherwise
      fail ArgumentError, "do not know how to handle facet queries for #{@field}" unless @field == :year
      format_year_label

      return
    end

    # We need to have name, value, and hits
    fail ArgumentError, 'facet specified without name' unless options[:name]
    @field = options[:name].to_sym

    fail ArgumentError, 'facet specified without value' unless options[:value]
    @value = options[:value]

    # Strip quotes from the value if present
    @value = @value[1..-2] if @value[0] == '"' && @value[-1] == '"'

    fail ArgumentError, 'facet specified without hits' unless options[:hits]
    @hits = Integer(options[:hits])

    # Construct the query
    @query = "#{field.to_s}:\"#{value}\""

    # Format the label
    case @field
    when :authors_facet
      @label = @value
      @field_label = I18n.t('search.index.authors_facet_short')
    when :journal_facet
      @label = @value
      @field_label = I18n.t('search.index.journal_facet_short')
    else
      fail ArgumentError, "do not know how to handle facets on #{@field}"
    end
  end

  include Comparable

  # Compare facet objects appropriately given their field
  #
  # In general, this sorts first by count and then by value.
  #
  # @param [Facet] other object for comparison
  # @return [Integer] -1, 0, or 1, appropriately
  def <=>(other)
    return -(@hits <=> other.hits) if hits != other.hits

    # We want years to sort inverse, while we want others normal.
    return -(@value <=> other.value) if field == :year
    (@value <=> other.value)
  end

  private

  # Format a label suitable for displaying a year facet
  #
  # Requires @value to be set, and will set @label and @field_label.
  #
  # @api private
  def format_year_label
    # We need to parse the decade out of "[X TO Y]"
    value_without_brackets = @value[1..-2]

    parts = value_without_brackets.split
    fail ArgumentError, 'year query does not follow correct format' unless parts.count == 3

    decade = parts[0]
    decade = '1790' if decade == '*'
    decade = Integer(decade)

    if decade == 1790
      @label = I18n.t('search.index.year_before_1800')
    elsif decade == 2010
      @label = I18n.t('search.index.year_after_2010')
    else
      @label = "#{decade}#{decade + 9}"
    end

    @field_label = I18n.t('search.index.year_facet_short')
  end
end

#queryString



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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/solr/facet.rb', line 24

class Facet
  attr_accessor :query, :field, :value, :hits, :label, :field_label

  # Create a new facet
  #
  # We can either get a string-format query, or (from RSolr::Ext) a facet
  # object and an item object.  This handles dealing with all of that.  We
  # will get either +:name+, +:value+, and +:hits+ (a facet parameter), or
  # +:query+ and +:hits+ (a facet query).
  #
  # @param [Hash] options specification of the new facet
  # @option options [Symbol] :name The field being faceted on
  # @option options [String] :value The facet value
  # @option options [Integer] :hits Number of hits for this facet
  # @option options [String] :query Facet as a string query
  def initialize(options = {})
    if options[:query]
      # We already have a query here, so go ahead and save the query
      @query = options[:query]

      fail ArgumentError, 'facet query specified without hits' unless options[:hits]
      @hits = Integer(options[:hits])

      # Basic format: "field:QUERY"
      parts = @query.split(':')
      fail ArgumentError, 'facet query not separated by colon' unless parts.count == 2

      @field = parts[0].to_sym
      @value = parts[1]

      # Strip quotes from the value if present
      @value = @value[1..-2] if @value[0] == '"' && @value[-1] == '"'

      # Format the label according to the field type -- for now, the only
      # argument type is year, so raise an error otherwise
      fail ArgumentError, "do not know how to handle facet queries for #{@field}" unless @field == :year
      format_year_label

      return
    end

    # We need to have name, value, and hits
    fail ArgumentError, 'facet specified without name' unless options[:name]
    @field = options[:name].to_sym

    fail ArgumentError, 'facet specified without value' unless options[:value]
    @value = options[:value]

    # Strip quotes from the value if present
    @value = @value[1..-2] if @value[0] == '"' && @value[-1] == '"'

    fail ArgumentError, 'facet specified without hits' unless options[:hits]
    @hits = Integer(options[:hits])

    # Construct the query
    @query = "#{field.to_s}:\"#{value}\""

    # Format the label
    case @field
    when :authors_facet
      @label = @value
      @field_label = I18n.t('search.index.authors_facet_short')
    when :journal_facet
      @label = @value
      @field_label = I18n.t('search.index.journal_facet_short')
    else
      fail ArgumentError, "do not know how to handle facets on #{@field}"
    end
  end

  include Comparable

  # Compare facet objects appropriately given their field
  #
  # In general, this sorts first by count and then by value.
  #
  # @param [Facet] other object for comparison
  # @return [Integer] -1, 0, or 1, appropriately
  def <=>(other)
    return -(@hits <=> other.hits) if hits != other.hits

    # We want years to sort inverse, while we want others normal.
    return -(@value <=> other.value) if field == :year
    (@value <=> other.value)
  end

  private

  # Format a label suitable for displaying a year facet
  #
  # Requires @value to be set, and will set @label and @field_label.
  #
  # @api private
  def format_year_label
    # We need to parse the decade out of "[X TO Y]"
    value_without_brackets = @value[1..-2]

    parts = value_without_brackets.split
    fail ArgumentError, 'year query does not follow correct format' unless parts.count == 3

    decade = parts[0]
    decade = '1790' if decade == '*'
    decade = Integer(decade)

    if decade == 1790
      @label = I18n.t('search.index.year_before_1800')
    elsif decade == 2010
      @label = I18n.t('search.index.year_after_2010')
    else
      @label = "#{decade}#{decade + 9}"
    end

    @field_label = I18n.t('search.index.year_facet_short')
  end
end

#valueString



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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/solr/facet.rb', line 24

class Facet
  attr_accessor :query, :field, :value, :hits, :label, :field_label

  # Create a new facet
  #
  # We can either get a string-format query, or (from RSolr::Ext) a facet
  # object and an item object.  This handles dealing with all of that.  We
  # will get either +:name+, +:value+, and +:hits+ (a facet parameter), or
  # +:query+ and +:hits+ (a facet query).
  #
  # @param [Hash] options specification of the new facet
  # @option options [Symbol] :name The field being faceted on
  # @option options [String] :value The facet value
  # @option options [Integer] :hits Number of hits for this facet
  # @option options [String] :query Facet as a string query
  def initialize(options = {})
    if options[:query]
      # We already have a query here, so go ahead and save the query
      @query = options[:query]

      fail ArgumentError, 'facet query specified without hits' unless options[:hits]
      @hits = Integer(options[:hits])

      # Basic format: "field:QUERY"
      parts = @query.split(':')
      fail ArgumentError, 'facet query not separated by colon' unless parts.count == 2

      @field = parts[0].to_sym
      @value = parts[1]

      # Strip quotes from the value if present
      @value = @value[1..-2] if @value[0] == '"' && @value[-1] == '"'

      # Format the label according to the field type -- for now, the only
      # argument type is year, so raise an error otherwise
      fail ArgumentError, "do not know how to handle facet queries for #{@field}" unless @field == :year
      format_year_label

      return
    end

    # We need to have name, value, and hits
    fail ArgumentError, 'facet specified without name' unless options[:name]
    @field = options[:name].to_sym

    fail ArgumentError, 'facet specified without value' unless options[:value]
    @value = options[:value]

    # Strip quotes from the value if present
    @value = @value[1..-2] if @value[0] == '"' && @value[-1] == '"'

    fail ArgumentError, 'facet specified without hits' unless options[:hits]
    @hits = Integer(options[:hits])

    # Construct the query
    @query = "#{field.to_s}:\"#{value}\""

    # Format the label
    case @field
    when :authors_facet
      @label = @value
      @field_label = I18n.t('search.index.authors_facet_short')
    when :journal_facet
      @label = @value
      @field_label = I18n.t('search.index.journal_facet_short')
    else
      fail ArgumentError, "do not know how to handle facets on #{@field}"
    end
  end

  include Comparable

  # Compare facet objects appropriately given their field
  #
  # In general, this sorts first by count and then by value.
  #
  # @param [Facet] other object for comparison
  # @return [Integer] -1, 0, or 1, appropriately
  def <=>(other)
    return -(@hits <=> other.hits) if hits != other.hits

    # We want years to sort inverse, while we want others normal.
    return -(@value <=> other.value) if field == :year
    (@value <=> other.value)
  end

  private

  # Format a label suitable for displaying a year facet
  #
  # Requires @value to be set, and will set @label and @field_label.
  #
  # @api private
  def format_year_label
    # We need to parse the decade out of "[X TO Y]"
    value_without_brackets = @value[1..-2]

    parts = value_without_brackets.split
    fail ArgumentError, 'year query does not follow correct format' unless parts.count == 3

    decade = parts[0]
    decade = '1790' if decade == '*'
    decade = Integer(decade)

    if decade == 1790
      @label = I18n.t('search.index.year_before_1800')
    elsif decade == 2010
      @label = I18n.t('search.index.year_after_2010')
    else
      @label = "#{decade}#{decade + 9}"
    end

    @field_label = I18n.t('search.index.year_facet_short')
  end
end

Instance Method Details

#<=>(other) ⇒ Integer

Compare facet objects appropriately given their field

In general, this sorts first by count and then by value.



102
103
104
105
106
107
108
# File 'lib/solr/facet.rb', line 102

def <=>(other)
  return -(@hits <=> other.hits) if hits != other.hits

  # We want years to sort inverse, while we want others normal.
  return -(@value <=> other.value) if field == :year
  (@value <=> other.value)
end

#format_year_labelObject (private)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Format a label suitable for displaying a year facet

Requires @value to be set, and will set @label and @field_label.



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/solr/facet.rb', line 117

def format_year_label
  # We need to parse the decade out of "[X TO Y]"
  value_without_brackets = @value[1..-2]

  parts = value_without_brackets.split
  fail ArgumentError, 'year query does not follow correct format' unless parts.count == 3

  decade = parts[0]
  decade = '1790' if decade == '*'
  decade = Integer(decade)

  if decade == 1790
    @label = I18n.t('search.index.year_before_1800')
  elsif decade == 2010
    @label = I18n.t('search.index.year_after_2010')
  else
    @label = "#{decade}#{decade + 9}"
  end

  @field_label = I18n.t('search.index.year_facet_short')
end