sunspot 0.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +83 -0
- data/LICENSE +18 -0
- data/README.rdoc +154 -0
- data/Rakefile +9 -0
- data/TODO +9 -0
- data/VERSION.yml +4 -0
- data/bin/sunspot-configure-solr +46 -0
- data/bin/sunspot-solr +62 -0
- data/lib/light_config.rb +40 -0
- data/lib/sunspot.rb +469 -0
- data/lib/sunspot/adapters.rb +265 -0
- data/lib/sunspot/composite_setup.rb +186 -0
- data/lib/sunspot/configuration.rb +38 -0
- data/lib/sunspot/data_extractor.rb +47 -0
- data/lib/sunspot/dsl.rb +3 -0
- data/lib/sunspot/dsl/field_query.rb +72 -0
- data/lib/sunspot/dsl/fields.rb +86 -0
- data/lib/sunspot/dsl/query.rb +59 -0
- data/lib/sunspot/dsl/query_facet.rb +31 -0
- data/lib/sunspot/dsl/restriction.rb +25 -0
- data/lib/sunspot/dsl/scope.rb +193 -0
- data/lib/sunspot/dsl/search.rb +30 -0
- data/lib/sunspot/facet.rb +16 -0
- data/lib/sunspot/facet_data.rb +120 -0
- data/lib/sunspot/facet_row.rb +10 -0
- data/lib/sunspot/field.rb +157 -0
- data/lib/sunspot/field_factory.rb +126 -0
- data/lib/sunspot/indexer.rb +123 -0
- data/lib/sunspot/instantiated_facet.rb +42 -0
- data/lib/sunspot/instantiated_facet_row.rb +22 -0
- data/lib/sunspot/query.rb +191 -0
- data/lib/sunspot/query/base_query.rb +90 -0
- data/lib/sunspot/query/connective.rb +126 -0
- data/lib/sunspot/query/dynamic_query.rb +69 -0
- data/lib/sunspot/query/field_facet.rb +151 -0
- data/lib/sunspot/query/field_query.rb +63 -0
- data/lib/sunspot/query/pagination.rb +39 -0
- data/lib/sunspot/query/query_facet.rb +73 -0
- data/lib/sunspot/query/query_facet_row.rb +19 -0
- data/lib/sunspot/query/query_field_facet.rb +13 -0
- data/lib/sunspot/query/restriction.rb +233 -0
- data/lib/sunspot/query/scope.rb +165 -0
- data/lib/sunspot/query/sort.rb +36 -0
- data/lib/sunspot/query/sort_composite.rb +33 -0
- data/lib/sunspot/schema.rb +165 -0
- data/lib/sunspot/search.rb +219 -0
- data/lib/sunspot/search/hit.rb +66 -0
- data/lib/sunspot/session.rb +201 -0
- data/lib/sunspot/setup.rb +271 -0
- data/lib/sunspot/type.rb +200 -0
- data/lib/sunspot/util.rb +164 -0
- data/solr/etc/jetty.xml +212 -0
- data/solr/etc/webdefault.xml +379 -0
- data/solr/lib/jetty-6.1.3.jar +0 -0
- data/solr/lib/jetty-util-6.1.3.jar +0 -0
- data/solr/lib/jsp-2.1/ant-1.6.5.jar +0 -0
- data/solr/lib/jsp-2.1/core-3.1.1.jar +0 -0
- data/solr/lib/jsp-2.1/jsp-2.1.jar +0 -0
- data/solr/lib/jsp-2.1/jsp-api-2.1.jar +0 -0
- data/solr/lib/servlet-api-2.5-6.1.3.jar +0 -0
- data/solr/solr/conf/elevate.xml +36 -0
- data/solr/solr/conf/protwords.txt +21 -0
- data/solr/solr/conf/schema.xml +50 -0
- data/solr/solr/conf/solrconfig.xml +696 -0
- data/solr/solr/conf/stopwords.txt +57 -0
- data/solr/solr/conf/synonyms.txt +31 -0
- data/solr/start.jar +0 -0
- data/solr/webapps/solr.war +0 -0
- data/spec/api/adapters_spec.rb +33 -0
- data/spec/api/build_search_spec.rb +1039 -0
- data/spec/api/indexer_spec.rb +311 -0
- data/spec/api/query_spec.rb +153 -0
- data/spec/api/search_retrieval_spec.rb +362 -0
- data/spec/api/session_spec.rb +157 -0
- data/spec/api/spec_helper.rb +1 -0
- data/spec/api/sunspot_spec.rb +18 -0
- data/spec/integration/dynamic_fields_spec.rb +55 -0
- data/spec/integration/faceting_spec.rb +169 -0
- data/spec/integration/keyword_search_spec.rb +83 -0
- data/spec/integration/scoped_search_spec.rb +289 -0
- data/spec/integration/spec_helper.rb +1 -0
- data/spec/integration/stored_fields_spec.rb +10 -0
- data/spec/integration/test_pagination.rb +32 -0
- data/spec/mocks/adapters.rb +32 -0
- data/spec/mocks/blog.rb +3 -0
- data/spec/mocks/comment.rb +19 -0
- data/spec/mocks/connection.rb +84 -0
- data/spec/mocks/mock_adapter.rb +30 -0
- data/spec/mocks/mock_record.rb +48 -0
- data/spec/mocks/photo.rb +8 -0
- data/spec/mocks/post.rb +73 -0
- data/spec/mocks/user.rb +8 -0
- data/spec/spec_helper.rb +47 -0
- data/tasks/gemspec.rake +25 -0
- data/tasks/rcov.rake +28 -0
- data/tasks/rdoc.rake +22 -0
- data/tasks/schema.rake +19 -0
- data/tasks/spec.rake +24 -0
- data/tasks/todo.rake +4 -0
- data/templates/schema.xml.haml +24 -0
- metadata +246 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
module Sunspot
|
2
|
+
module Query
|
3
|
+
#
|
4
|
+
# The Sort class is a query component representing a sort by a given field.
|
5
|
+
#
|
6
|
+
class Sort #:nodoc:
|
7
|
+
DIRECTIONS = {
|
8
|
+
:asc => 'asc',
|
9
|
+
:ascending => 'asc',
|
10
|
+
:desc => 'desc',
|
11
|
+
:descending => 'desc'
|
12
|
+
}
|
13
|
+
|
14
|
+
def initialize(field, direction = nil)
|
15
|
+
if field.multiple?
|
16
|
+
raise(ArgumentError, "#{field.name} cannot be used for ordering because it is a multiple-value field")
|
17
|
+
end
|
18
|
+
@field, @direction = field, (direction || :asc).to_sym
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_param
|
22
|
+
"#{@field.indexed_name.to_sym} #{direction_for_solr}"
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def direction_for_solr
|
28
|
+
DIRECTIONS[@direction] ||
|
29
|
+
raise(
|
30
|
+
ArgumentError,
|
31
|
+
"Unknown sort direction #{@direction}. Acceptable input is: #{DIRECTIONS.keys.map { |input| input.inspect } * ', '}"
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Sunspot
|
2
|
+
module Query
|
3
|
+
#
|
4
|
+
# The SortComposite class encapsulates an ordered collection of Sort
|
5
|
+
# objects. It's necessary to keep this as a separate class as Solr takes
|
6
|
+
# the sort as a single parameter, so adding sorts as regular components
|
7
|
+
# would not merge correctly in the #to_params method.
|
8
|
+
#
|
9
|
+
class SortComposite #:nodoc:
|
10
|
+
def initialize
|
11
|
+
@sorts = []
|
12
|
+
end
|
13
|
+
|
14
|
+
#
|
15
|
+
# Add a sort to the composite
|
16
|
+
#
|
17
|
+
def <<(sort)
|
18
|
+
@sorts << sort
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# Combine the sorts into a single param by joining them
|
23
|
+
#
|
24
|
+
def to_params
|
25
|
+
unless @sorts.empty?
|
26
|
+
{ :sort => @sorts.map { |sort| sort.to_param } * ', ' }
|
27
|
+
else
|
28
|
+
{}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
using_rubygems = false
|
2
|
+
begin
|
3
|
+
require 'haml'
|
4
|
+
rescue LoadError => e
|
5
|
+
if using_rubygems
|
6
|
+
raise(e)
|
7
|
+
else
|
8
|
+
using_rubygems = true
|
9
|
+
require 'rubygems'
|
10
|
+
retry
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module Sunspot
|
15
|
+
#
|
16
|
+
# Object that encapsulates schema information for building a Solr schema.xml
|
17
|
+
# file. This class is used by the schema:compile task as well as the
|
18
|
+
# sunspot-configure-solr executable.
|
19
|
+
#
|
20
|
+
class Schema #:nodoc:all
|
21
|
+
FieldType = Struct.new(:name, :class_name, :suffix)
|
22
|
+
FieldVariant = Struct.new(:attribute, :suffix)
|
23
|
+
|
24
|
+
DEFAULT_TOKENIZER = 'solr.StandardTokenizerFactory'
|
25
|
+
DEFAULT_FILTERS = %w(solr.StandardFilterFactory solr.LowerCaseFilterFactory)
|
26
|
+
|
27
|
+
FIELD_TYPES = [
|
28
|
+
FieldType.new('boolean', 'Bool', 'b'),
|
29
|
+
FieldType.new('sfloat', 'SortableFloat', 'f'),
|
30
|
+
FieldType.new('date', 'Date', 'd'),
|
31
|
+
FieldType.new('sint', 'SortableInt', 'i'),
|
32
|
+
FieldType.new('string', 'Str', 's')
|
33
|
+
]
|
34
|
+
|
35
|
+
FIELD_VARIANTS = [
|
36
|
+
FieldVariant.new('multiValued', 'm'),
|
37
|
+
FieldVariant.new('stored', 's')
|
38
|
+
]
|
39
|
+
|
40
|
+
attr_reader :tokenizer, :filters
|
41
|
+
|
42
|
+
def initialize
|
43
|
+
@tokenizer = DEFAULT_TOKENIZER
|
44
|
+
@filters = DEFAULT_FILTERS.dup
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# Attribute field types defined in the schema
|
49
|
+
#
|
50
|
+
def types
|
51
|
+
FIELD_TYPES
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# DynamicField instances representing all the available types and variants
|
56
|
+
#
|
57
|
+
def dynamic_fields
|
58
|
+
fields = []
|
59
|
+
for field_variants in variant_combinations
|
60
|
+
for type in FIELD_TYPES
|
61
|
+
fields << DynamicField.new(type, field_variants)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
fields
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# Which tokenizer to use for text fields
|
69
|
+
#
|
70
|
+
def tokenizer=(tokenizer)
|
71
|
+
@tokenizer =
|
72
|
+
if tokenizer =~ /\./
|
73
|
+
tokenizer
|
74
|
+
else
|
75
|
+
"solr.#{tokenizer}TokenizerFactory"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
# Add a filter for text field tokenization
|
81
|
+
#
|
82
|
+
def add_filter(filter)
|
83
|
+
@filters <<
|
84
|
+
if filter =~ /\./
|
85
|
+
filter
|
86
|
+
else
|
87
|
+
"solr.#{filter}FilterFactory"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
#
|
92
|
+
# Return an XML representation of this schema using the Haml template
|
93
|
+
#
|
94
|
+
def to_xml
|
95
|
+
template = File.read(
|
96
|
+
File.join(
|
97
|
+
File.dirname(__FILE__),
|
98
|
+
'..',
|
99
|
+
'..',
|
100
|
+
'templates',
|
101
|
+
'schema.xml.haml'
|
102
|
+
)
|
103
|
+
)
|
104
|
+
engine = Haml::Engine.new(template)
|
105
|
+
engine.render(Object.new, :schema => self)
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
#
|
111
|
+
# All of the possible combinations of variants
|
112
|
+
#
|
113
|
+
def variant_combinations
|
114
|
+
combinations = []
|
115
|
+
0.upto(2 ** FIELD_VARIANTS.length - 1) do |b|
|
116
|
+
combinations << combination = []
|
117
|
+
FIELD_VARIANTS.each_with_index do |variant, i|
|
118
|
+
combination << variant if b & 1<<i > 0
|
119
|
+
end
|
120
|
+
end
|
121
|
+
combinations
|
122
|
+
end
|
123
|
+
|
124
|
+
#
|
125
|
+
# Represents a dynamic field (in the Solr schema sense, not the Sunspot
|
126
|
+
# sense).
|
127
|
+
#
|
128
|
+
class DynamicField
|
129
|
+
def initialize(type, field_variants)
|
130
|
+
@type, @field_variants = type, field_variants
|
131
|
+
end
|
132
|
+
|
133
|
+
#
|
134
|
+
# Name of the field in the schema
|
135
|
+
#
|
136
|
+
def name
|
137
|
+
variant_suffixes = @field_variants.map { |variant| variant.suffix }.join
|
138
|
+
"*_#{@type.suffix}#{variant_suffixes}"
|
139
|
+
end
|
140
|
+
|
141
|
+
#
|
142
|
+
# Name of the type as defined in the schema
|
143
|
+
#
|
144
|
+
def type
|
145
|
+
@type.name
|
146
|
+
end
|
147
|
+
|
148
|
+
#
|
149
|
+
# Implement magic methods to ask if a field is of a particular variant.
|
150
|
+
# Returns "true" if the field is of that variant and "false" otherwise.
|
151
|
+
#
|
152
|
+
def method_missing(name, *args, &block)
|
153
|
+
if name.to_s =~ /\?$/ && args.empty?
|
154
|
+
if @field_variants.any? { |variant| "#{variant.attribute}?" == name.to_s }
|
155
|
+
'true'
|
156
|
+
else
|
157
|
+
'false'
|
158
|
+
end
|
159
|
+
else
|
160
|
+
super(name.to_sym, *args, &block)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
@@ -0,0 +1,219 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'search', 'hit')
|
2
|
+
|
3
|
+
module Sunspot
|
4
|
+
#
|
5
|
+
# This class encapsulates the results of a Solr search. It provides access
|
6
|
+
# to search results, total result count, facets, and pagination information.
|
7
|
+
# Instances of Search are returned by the Sunspot.search and
|
8
|
+
# Sunspot.new_search methods.
|
9
|
+
#
|
10
|
+
class Search
|
11
|
+
# Query information for this search. If you wish to build the query without
|
12
|
+
# using the search DSL, this method allows you to access the query API
|
13
|
+
# directly. See Sunspot#new_search for how to construct the search object
|
14
|
+
# in this case.
|
15
|
+
attr_reader :query
|
16
|
+
|
17
|
+
def initialize(connection, setup, query) #:nodoc:
|
18
|
+
@connection, @setup, @query = connection, setup, query
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# Execute the search on the Solr instance and store the results. If you
|
23
|
+
# use Sunspot#search() to construct your searches, there is no need to call
|
24
|
+
# this method as it has already been called. If you use
|
25
|
+
# Sunspot#new_search(), you will need to call this method after building the
|
26
|
+
# query.
|
27
|
+
#
|
28
|
+
def execute!
|
29
|
+
params = @query.to_params
|
30
|
+
@solr_result = @connection.select(params)
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# Get the collection of results as instantiated objects. If WillPaginate is
|
36
|
+
# available, the results will be a WillPaginate::Collection instance; if
|
37
|
+
# not, it will be a vanilla Array.
|
38
|
+
#
|
39
|
+
# ==== Returns
|
40
|
+
#
|
41
|
+
# WillPaginate::Collection or Array:: Instantiated result objects
|
42
|
+
#
|
43
|
+
def results
|
44
|
+
@results ||= if @query.page && defined?(WillPaginate::Collection)
|
45
|
+
WillPaginate::Collection.create(@query.page, @query.per_page, total) do |pager|
|
46
|
+
pager.replace(hits.map { |hit| hit.instance })
|
47
|
+
end
|
48
|
+
else
|
49
|
+
hits.map { |hit| hit.instance }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# Access raw Solr result information. Returns a collection of Hit objects
|
55
|
+
# that contain the class name, primary key, keyword relevance score (if
|
56
|
+
# applicable), and any stored fields.
|
57
|
+
#
|
58
|
+
# ==== Returns
|
59
|
+
#
|
60
|
+
# Array:: Ordered collection of Hit objects
|
61
|
+
#
|
62
|
+
def hits
|
63
|
+
@hits ||= solr_response['docs'].map { |doc| Hit.new(doc, self) }
|
64
|
+
end
|
65
|
+
alias_method :raw_results, :hits
|
66
|
+
|
67
|
+
#
|
68
|
+
# The total number of documents matching the query parameters
|
69
|
+
#
|
70
|
+
# ==== Returns
|
71
|
+
#
|
72
|
+
# Integer:: Total matching documents
|
73
|
+
#
|
74
|
+
def total
|
75
|
+
@total ||= solr_response['numFound']
|
76
|
+
end
|
77
|
+
|
78
|
+
#
|
79
|
+
# Get the facet object for the given field. This field will need to have
|
80
|
+
# been requested as a field facet inside the search block.
|
81
|
+
#
|
82
|
+
# ==== Parameters
|
83
|
+
#
|
84
|
+
# field_name<Symbol>:: field name for which to get the facet
|
85
|
+
#
|
86
|
+
# ==== Returns
|
87
|
+
#
|
88
|
+
# Sunspot::Facet:: Facet object for the given field
|
89
|
+
#
|
90
|
+
def facet(field_name)
|
91
|
+
(@facets_cache ||= {})[field_name.to_sym] ||=
|
92
|
+
begin
|
93
|
+
facet_data = query_facet_data(field_name) ||
|
94
|
+
begin
|
95
|
+
field = field(field_name)
|
96
|
+
date_facet_data(field) ||
|
97
|
+
FacetData::FieldFacetData.new(@solr_result['facet_counts']['facet_fields'][field.indexed_name], field)
|
98
|
+
end
|
99
|
+
facet_class = facet_data.reference ? InstantiatedFacet : Facet
|
100
|
+
facet_class.new(facet_data)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
#
|
105
|
+
# Get the facet object for a given dynamic field. This dynamic field will
|
106
|
+
# need to have been requested as a field facet inside the search block.
|
107
|
+
#
|
108
|
+
# ==== Parameters
|
109
|
+
#
|
110
|
+
# base_name<Symbol>::
|
111
|
+
# Base name of the dynamic field definiton (as specified in the setup
|
112
|
+
# block)
|
113
|
+
# dynamic_name<Symbol>::
|
114
|
+
# Dynamic field name to facet on
|
115
|
+
#
|
116
|
+
# ==== Returns
|
117
|
+
#
|
118
|
+
# Sunspot::Facet:: Facet object for given dynamic field
|
119
|
+
#
|
120
|
+
# ==== Example
|
121
|
+
#
|
122
|
+
# search = Sunspot.search(Post) do
|
123
|
+
# dynamic :custom do
|
124
|
+
# facet :cuisine
|
125
|
+
# end
|
126
|
+
# end
|
127
|
+
# search.dynamic_facet(:custom, :cuisine)
|
128
|
+
# #=> Facet for the dynamic field :cuisine in the :custom field definition
|
129
|
+
#
|
130
|
+
def dynamic_facet(base_name, dynamic_name)
|
131
|
+
(@dynamic_facets_cache ||= {})[[base_name.to_sym, dynamic_name.to_sym]] ||=
|
132
|
+
begin
|
133
|
+
field = @setup.dynamic_field_factory(base_name).build(dynamic_name)
|
134
|
+
Facet.new(FacetData::FieldFacetData.new(@solr_result['facet_counts']['facet_fields'][field.indexed_name], field))
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
#
|
139
|
+
# Get the data accessor that will be used to load a particular class out of
|
140
|
+
# persistent storage. Data accessors can implement any methods that may be
|
141
|
+
# useful for refining how data is loaded out of storage. When building a
|
142
|
+
# search manually (e.g., using the Sunspot#new_search method), this should
|
143
|
+
# be used before calling #execute(). Use the
|
144
|
+
# Sunspot::DSL::Search#data_accessor_for method when building searches using
|
145
|
+
# the block DSL.
|
146
|
+
#
|
147
|
+
def data_accessor_for(clazz)
|
148
|
+
(@data_accessors ||= {})[clazz.name.to_sym] ||=
|
149
|
+
Adapters::DataAccessor.create(clazz)
|
150
|
+
end
|
151
|
+
|
152
|
+
#
|
153
|
+
# Build this search using a DSL block.
|
154
|
+
#
|
155
|
+
def build(&block) #:nodoc:
|
156
|
+
Util.instance_eval_or_call(dsl, &block)
|
157
|
+
self
|
158
|
+
end
|
159
|
+
|
160
|
+
def populate_hits! #:nodoc:
|
161
|
+
id_hit_hash = Hash.new { |h, k| h[k] = {} }
|
162
|
+
hits.each do |hit|
|
163
|
+
id_hit_hash[hit.class_name][hit.primary_key] = hit
|
164
|
+
end
|
165
|
+
id_hit_hash.each_pair do |class_name, hits|
|
166
|
+
ids = hits.map { |id, hit| hit.primary_key }
|
167
|
+
data_accessor_for(Util.full_const_get(class_name)).load_all(ids).each do |instance|
|
168
|
+
hit = id_hit_hash[class_name][Adapters::InstanceAdapter.adapt(instance).id.to_s]
|
169
|
+
hit.instance = instance
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
private
|
175
|
+
|
176
|
+
def solr_response
|
177
|
+
@solr_response ||= @solr_result['response']
|
178
|
+
end
|
179
|
+
|
180
|
+
def doc_ids
|
181
|
+
@doc_ids ||= solr_response['docs'].map { |doc| doc['id'] }
|
182
|
+
end
|
183
|
+
|
184
|
+
def dsl
|
185
|
+
DSL::Search.new(self)
|
186
|
+
end
|
187
|
+
|
188
|
+
def raw_facet(field)
|
189
|
+
if field.type == Type::TimeType
|
190
|
+
@solr_result['facet_counts']['facet_dates'][field.indexed_name]
|
191
|
+
end || @solr_result['facet_counts']['facet_fields'][field.indexed_name]
|
192
|
+
end
|
193
|
+
|
194
|
+
def date_facet_data(field)
|
195
|
+
if field.type == Type::TimeType
|
196
|
+
if @solr_result['facet_counts'].has_key?('facet_dates')
|
197
|
+
if facet_result = @solr_result['facet_counts']['facet_dates'][field.indexed_name]
|
198
|
+
FacetData::DateFacetData.new(facet_result, field)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def query_facet_data(name)
|
205
|
+
if query_facet = @query.query_facet(name.to_sym)
|
206
|
+
if @solr_result['facet_counts'].has_key?('facet_queries')
|
207
|
+
FacetData::QueryFacetData.new(
|
208
|
+
query_facet,
|
209
|
+
@solr_result['facet_counts']['facet_queries']
|
210
|
+
)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
def field(name)
|
216
|
+
@setup.field(name)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|