ansr 0.0.1 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/README.md +35 -0
- data/ansr.gemspec +2 -1
- data/ansr_blacklight/Gemfile +3 -0
- data/ansr_blacklight/README.md +37 -0
- data/ansr_blacklight/ansr_blacklight.gemspec +28 -0
- data/ansr_blacklight/lib/ansr_blacklight.rb +57 -0
- data/ansr_blacklight/lib/ansr_blacklight/arel.rb +6 -0
- data/ansr_blacklight/lib/ansr_blacklight/arel/big_table.rb +57 -0
- data/ansr_blacklight/lib/ansr_blacklight/arel/visitors.rb +6 -0
- data/ansr_blacklight/lib/ansr_blacklight/arel/visitors/query_builder.rb +217 -0
- data/ansr_blacklight/lib/ansr_blacklight/arel/visitors/to_no_sql.rb +14 -0
- data/ansr_blacklight/lib/ansr_blacklight/base.rb +21 -0
- data/ansr_blacklight/lib/ansr_blacklight/connection_adapters/no_sql_adapter.rb +38 -0
- data/ansr_blacklight/lib/ansr_blacklight/model/querying.rb +29 -0
- data/ansr_blacklight/lib/ansr_blacklight/relation.rb +50 -0
- data/ansr_blacklight/lib/ansr_blacklight/relation/solr_projection_methods.rb +55 -0
- data/ansr_blacklight/lib/ansr_blacklight/request_builders.rb +141 -0
- data/ansr_blacklight/lib/ansr_blacklight/solr.rb +4 -0
- data/ansr_blacklight/lib/ansr_blacklight/solr/request.rb +46 -0
- data/ansr_blacklight/lib/ansr_blacklight/solr/response.rb +94 -0
- data/ansr_blacklight/lib/ansr_blacklight/solr/response/group.rb +32 -0
- data/ansr_blacklight/lib/ansr_blacklight/solr/response/group_response.rb +50 -0
- data/ansr_blacklight/lib/ansr_blacklight/solr/response/more_like_this.rb +14 -0
- data/ansr_blacklight/lib/ansr_blacklight/solr/response/pagination_methods.rb +35 -0
- data/ansr_blacklight/lib/ansr_blacklight/solr/response/spelling.rb +92 -0
- data/ansr_blacklight/spec/fixtures/config.yml +0 -0
- data/ansr_blacklight/spec/lib/loaded_relation_spec.rb +223 -0
- data/ansr_blacklight/spec/lib/queryable_relation_spec.rb +133 -0
- data/ansr_blacklight/spec/lib/relation/faceting_spec.rb +475 -0
- data/ansr_blacklight/spec/lib/relation/grouping_spec.rb +159 -0
- data/ansr_blacklight/spec/spec_helper.rb +72 -0
- data/ansr_dpla/Gemfile +3 -0
- data/ansr_dpla/Gemfile.lock +138 -0
- data/ansr_dpla/README.md +2 -2
- data/ansr_dpla/ansr_dpla.gemspec +2 -2
- data/ansr_dpla/lib/ansr_dpla.rb +3 -0
- data/ansr_dpla/lib/ansr_dpla/api.rb +3 -3
- data/ansr_dpla/lib/ansr_dpla/arel.rb +1 -2
- data/ansr_dpla/lib/ansr_dpla/arel/big_table.rb +4 -0
- data/ansr_dpla/lib/ansr_dpla/arel/visitors.rb +6 -0
- data/ansr_dpla/lib/ansr_dpla/arel/visitors/query_builder.rb +188 -0
- data/ansr_dpla/lib/ansr_dpla/arel/visitors/to_no_sql.rb +9 -0
- data/ansr_dpla/lib/ansr_dpla/connection_adapters/no_sql_adapter.rb +58 -0
- data/ansr_dpla/lib/ansr_dpla/model/base.rb +7 -0
- data/ansr_dpla/lib/ansr_dpla/model/querying.rb +6 -10
- data/ansr_dpla/lib/ansr_dpla/relation.rb +61 -0
- data/ansr_dpla/lib/ansr_dpla/request.rb +5 -0
- data/ansr_dpla/spec/lib/api_spec.rb +8 -5
- data/ansr_dpla/spec/lib/item_spec.rb +2 -2
- data/ansr_dpla/spec/lib/relation/facet_spec.rb +27 -19
- data/ansr_dpla/spec/lib/relation/select_spec.rb +10 -8
- data/ansr_dpla/spec/lib/relation/where_spec.rb +1 -1
- data/ansr_dpla/spec/lib/relation_spec.rb +31 -29
- data/ansr_dpla/test/system.rb +4 -2
- data/lib/ansr.rb +7 -0
- data/lib/ansr/arel.rb +3 -0
- data/lib/ansr/arel/big_table.rb +43 -3
- data/lib/ansr/arel/configured_field.rb +19 -0
- data/lib/ansr/arel/nodes.rb +41 -0
- data/lib/ansr/arel/visitors.rb +7 -0
- data/lib/ansr/arel/visitors/context.rb +13 -0
- data/lib/ansr/arel/visitors/query_builder.rb +47 -0
- data/lib/ansr/arel/visitors/to_no_sql.rb +41 -0
- data/lib/ansr/base.rb +29 -1
- data/lib/ansr/configurable.rb +6 -12
- data/lib/ansr/connection_adapters.rb +5 -0
- data/lib/ansr/connection_adapters/no_sql_adapter.rb +80 -0
- data/lib/ansr/dummy_associations.rb +105 -0
- data/lib/ansr/facets.rb +103 -0
- data/lib/ansr/model.rb +17 -107
- data/lib/ansr/model/connection_handler.rb +6 -0
- data/lib/ansr/relation.rb +40 -23
- data/lib/ansr/relation/group.rb +31 -0
- data/lib/ansr/relation/predicate_builder.rb +106 -0
- data/lib/ansr/relation/query_methods.rb +192 -45
- data/lib/ansr/sanitization.rb +5 -18
- data/lib/ansr/utils.rb +89 -0
- data/lib/ansr/version.rb +1 -1
- metadata +73 -25
- data/ansr_dpla/lib/ansr_dpla/arel/connection.rb +0 -81
- data/ansr_dpla/lib/ansr_dpla/arel/query_builder.rb +0 -131
- data/lib/ansr/model/connection.rb +0 -103
@@ -0,0 +1,13 @@
|
|
1
|
+
module Ansr::Arel::Visitors
|
2
|
+
class Context
|
3
|
+
attr_reader :attribute
|
4
|
+
def initialize(attribute)
|
5
|
+
@attribute = attribute
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
# create some thin subclasses in this module
|
10
|
+
%W(Facet Filter From Order).each do |name|
|
11
|
+
const_set(name, Class.new(Context))
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Ansr::Arel::Visitors
|
2
|
+
class QueryBuilder < Arel::Visitors::Visitor
|
3
|
+
attr_reader :table
|
4
|
+
def initialize(table)
|
5
|
+
@table = table
|
6
|
+
end
|
7
|
+
|
8
|
+
def visit(object, attribute=nil)
|
9
|
+
super(object, attribute)
|
10
|
+
end
|
11
|
+
|
12
|
+
def visit_Ansr_Arel_BigTable(object, attribute)
|
13
|
+
visit object.name, attribute if Ansr::Arel::Visitors::From === attribute
|
14
|
+
@table = object if Ansr::Arel::BigTable === object and Ansr::Arel::Visitors::From === attribute
|
15
|
+
end
|
16
|
+
|
17
|
+
def visit_Arel_Nodes_SelectCore(object, attribute)
|
18
|
+
visit(object.froms, From.new(attribute)) if object.froms
|
19
|
+
object.projections.each { |x| visit(x, attribute) }
|
20
|
+
object.wheres.each { |x| visit(x, attribute) }
|
21
|
+
object.groups.each {|x| visit(x, attribute) if x}
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def visit_Symbol o, a
|
26
|
+
visit o.to_s, a
|
27
|
+
end
|
28
|
+
|
29
|
+
def visit_Array o, a
|
30
|
+
o.map { |x| visit x, a }
|
31
|
+
end
|
32
|
+
|
33
|
+
def visit_Arel_Nodes_And(object, attribute)
|
34
|
+
visit(object.children, attribute)
|
35
|
+
end
|
36
|
+
|
37
|
+
def field_key_from_node(node)
|
38
|
+
table.model.field_name(node)
|
39
|
+
end
|
40
|
+
|
41
|
+
# determines whether multiple values should accumulate or overwrite in merges
|
42
|
+
def multiple?(field_key)
|
43
|
+
false
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Ansr::Arel::Visitors
|
2
|
+
class ToNoSql < Arel::Visitors::Visitor
|
3
|
+
attr_reader :table
|
4
|
+
|
5
|
+
def initialize(big_table)
|
6
|
+
super()
|
7
|
+
@table = big_table
|
8
|
+
end
|
9
|
+
|
10
|
+
def query_builder(opts = nil)
|
11
|
+
Ansr::Arel::Visitors::QueryBuilder.new(table, opts)
|
12
|
+
end
|
13
|
+
|
14
|
+
# the object generated by this method will be passed to the NoSqlAdapter#execute
|
15
|
+
def visit_Arel_Nodes_SelectStatement(object, attribute)
|
16
|
+
builder = query_builder
|
17
|
+
|
18
|
+
if object.with
|
19
|
+
builder.visit(object.with, attribute)
|
20
|
+
end
|
21
|
+
|
22
|
+
object.cores.each { |x| builder.visit_Arel_Nodes_SelectCore(x, attribute) }
|
23
|
+
|
24
|
+
unless object.orders.empty?
|
25
|
+
|
26
|
+
object.orders.each do |x|
|
27
|
+
oa = Ansr::Arel::Visitors::Order.new(attribute)
|
28
|
+
builder.visit x, oa
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
builder.visit(object.limit, attribute) if object.limit
|
33
|
+
builder.visit(object.offset, attribute) if object.offset
|
34
|
+
# not relevant
|
35
|
+
|
36
|
+
builder.query_opts
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
data/lib/ansr/base.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
|
+
require 'active_record'
|
1
2
|
module Ansr
|
2
3
|
class Base < ActiveRecord::Base
|
3
|
-
|
4
|
+
include Ansr::Model
|
4
5
|
extend Ansr::Configurable
|
5
6
|
extend Ansr::QueryMethods
|
6
7
|
extend Ansr::ArelMethods
|
7
8
|
include Ansr::Sanitization
|
9
|
+
#TODO remove the dummy associations
|
10
|
+
include Ansr::DummyAssociations
|
8
11
|
|
9
12
|
self.abstract_class = true
|
10
13
|
|
@@ -13,6 +16,27 @@ module Ansr
|
|
13
16
|
@source_doc = doc
|
14
17
|
end
|
15
18
|
|
19
|
+
def core_initialize(attributes = nil, options = {})
|
20
|
+
defaults = self.class.column_defaults.dup
|
21
|
+
defaults.each { |k, v| defaults[k] = v.dup if v.duplicable? }
|
22
|
+
|
23
|
+
@attributes = self.class.initialize_attributes(defaults)
|
24
|
+
@column_types_override = nil
|
25
|
+
@column_types = self.class.column_types
|
26
|
+
|
27
|
+
init_internals
|
28
|
+
init_changed_attributes
|
29
|
+
ensure_proper_type
|
30
|
+
populate_with_current_scope_attributes
|
31
|
+
|
32
|
+
# +options+ argument is only needed to make protected_attributes gem easier to hook.
|
33
|
+
# Remove it when we drop support to this gem.
|
34
|
+
init_attributes(attributes, options) if attributes
|
35
|
+
|
36
|
+
yield self if block_given?
|
37
|
+
run_callbacks :initialize unless _initialize_callbacks.empty?
|
38
|
+
end
|
39
|
+
|
16
40
|
def filter_source_hash(doc)
|
17
41
|
fields = self.class.model().table().fields()
|
18
42
|
filtered = doc.select do |k,v|
|
@@ -21,6 +45,10 @@ module Ansr
|
|
21
45
|
filtered.with_indifferent_access
|
22
46
|
end
|
23
47
|
|
48
|
+
def columns(name=self.name)
|
49
|
+
super(name)
|
50
|
+
end
|
51
|
+
|
24
52
|
def [](key)
|
25
53
|
@source_doc[key]
|
26
54
|
end
|
data/lib/ansr/configurable.rb
CHANGED
@@ -1,17 +1,11 @@
|
|
1
1
|
module Ansr
|
2
2
|
module Configurable
|
3
|
-
def config
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
else
|
10
|
-
yaml
|
11
|
-
end
|
12
|
-
end
|
13
|
-
y
|
14
|
-
end : @config
|
3
|
+
def config
|
4
|
+
@config ||= {}
|
5
|
+
if block_given?
|
6
|
+
yield @config
|
7
|
+
end
|
8
|
+
@config
|
15
9
|
end
|
16
10
|
|
17
11
|
alias_method :configure, :config
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'arel/visitors/bind_visitor'
|
3
|
+
module Ansr
|
4
|
+
module ConnectionAdapters
|
5
|
+
class NoSqlAdapter < ActiveRecord::ConnectionAdapters::AbstractAdapter
|
6
|
+
attr_reader :table
|
7
|
+
def initialize(klass, connection, logger = nil, pool = nil)
|
8
|
+
super(connection, logger, pool)
|
9
|
+
@table = klass.table
|
10
|
+
@visitor = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
# Converts an arel AST to NOSQL Query
|
14
|
+
def to_nosql(arel, binds = [])
|
15
|
+
arel = arel.ast if arel.respond_to?(:ast)
|
16
|
+
if arel.is_a? ::Arel::Nodes::Node
|
17
|
+
binds = binds.dup
|
18
|
+
visitor.accept(arel) do
|
19
|
+
quote(*binds.shift.reverse)
|
20
|
+
end
|
21
|
+
else # assume it is already serialized
|
22
|
+
arel
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# attr_accessor :visitor is a self.class::BindSubstitution in unprepared contexts
|
27
|
+
class BindSubstitution < ::Arel::Visitors::MySQL # :nodoc:
|
28
|
+
include ::Arel::Visitors::BindVisitor
|
29
|
+
end
|
30
|
+
|
31
|
+
# Executes +query+ statement in the context of this connection using
|
32
|
+
# +binds+ as the bind substitutes. +name+ is logged along with
|
33
|
+
# the executed +query+ statement.
|
34
|
+
def execute(query, name = 'ANSR-NOSQL')
|
35
|
+
end
|
36
|
+
|
37
|
+
# called back from ::Arel::Table
|
38
|
+
def primary_key(table_name)
|
39
|
+
'id' # table.primary_key || 'id'
|
40
|
+
end
|
41
|
+
|
42
|
+
def table_exists?(name)
|
43
|
+
true
|
44
|
+
end
|
45
|
+
|
46
|
+
def schema_cache
|
47
|
+
ActiveRecord::ConnectionAdapters::SchemaCache.new(self)
|
48
|
+
end
|
49
|
+
|
50
|
+
# this is called by the BigTable impl
|
51
|
+
# should it be retired in favor of the more domain-appropriate 'fields'? Not usually seen by clients anyway.
|
52
|
+
def columns(table_name, *rest)
|
53
|
+
@table.fields.map {|s| ::ActiveRecord::ConnectionAdapters::Column.new(s.to_s, nil, String)}
|
54
|
+
end
|
55
|
+
|
56
|
+
def sanitize_limit(limit_value)
|
57
|
+
if limit_value.to_s.to_i >= 0
|
58
|
+
limit_value
|
59
|
+
else
|
60
|
+
Ansr::Relation::DEFAULT_PAGE_SIZE
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def sanitize_filter_name(filter_value)
|
65
|
+
if filter_value.is_a? Array
|
66
|
+
return filter_value.collect {|x| sanitize_filter_name(x)}.compact
|
67
|
+
else
|
68
|
+
if @table.facets.include? filter_value.to_sym
|
69
|
+
return filter_value
|
70
|
+
else
|
71
|
+
raise "#{filter_value} is not a filterable field"
|
72
|
+
#Rails.logger.warn "Ignoring #{filter_value} (not a filterable field)" if Rails.logger
|
73
|
+
#return nil
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Ansr
|
2
|
+
module DummyAssociations
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
module ClassMethods
|
5
|
+
def create_reflection(macro, name, scope, options, active_record)
|
6
|
+
case macro
|
7
|
+
when :has_many, :belongs_to, :has_one, :has_and_belongs_to_many
|
8
|
+
klass = options[:through] ? DummyThroughReflection : DummyAssociationReflection
|
9
|
+
reflection = klass.new(macro, name, scope, options, active_record)
|
10
|
+
when :composed_of
|
11
|
+
reflection = DummyAggregateReflection.new(macro, name, scope, options, active_record)
|
12
|
+
end
|
13
|
+
|
14
|
+
self.reflections = self.reflections.merge(name => reflection)
|
15
|
+
reflection
|
16
|
+
end
|
17
|
+
|
18
|
+
# Returns an array of AggregateReflection objects for all the aggregations in the class.
|
19
|
+
def reflect_on_all_aggregations
|
20
|
+
reflections.values.grep(DummyAggregateReflection)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns the AggregateReflection object for the named +aggregation+ (use the symbol).
|
24
|
+
#
|
25
|
+
# Account.reflect_on_aggregation(:balance) # => the balance AggregateReflection
|
26
|
+
#
|
27
|
+
def reflect_on_aggregation(aggregation)
|
28
|
+
reflection = reflections[aggregation]
|
29
|
+
reflection if reflection.is_a?(DummyAggregateReflection)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns an array of DummyAssociationReflection objects for all the
|
33
|
+
# associations in the class. If you only want to reflect on a certain
|
34
|
+
# association type, pass in the symbol (<tt>:has_many</tt>, <tt>:has_one</tt>,
|
35
|
+
# <tt>:belongs_to</tt>) as the first parameter.
|
36
|
+
#
|
37
|
+
# Example:
|
38
|
+
#
|
39
|
+
# Account.reflect_on_all_associations # returns an array of all associations
|
40
|
+
# Account.reflect_on_all_associations(:has_many) # returns an array of all has_many associations
|
41
|
+
#
|
42
|
+
def reflect_on_all_associations(macro = nil)
|
43
|
+
association_reflections = reflections.values.grep(DummyAssociationReflection)
|
44
|
+
macro ? association_reflections.select { |reflection| reflection.macro == macro } : association_reflections
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns the DummyAssociationReflection object for the +association+ (use the symbol).
|
48
|
+
#
|
49
|
+
# Account.reflect_on_association(:owner) # returns the owner AssociationReflection
|
50
|
+
# Invoice.reflect_on_association(:line_items).macro # returns :has_many
|
51
|
+
#
|
52
|
+
def reflect_on_association(association)
|
53
|
+
reflection = reflections[association]
|
54
|
+
reflection if reflection.is_a?(DummyAssociationReflection)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Returns an array of AssociationReflection objects for all associations which have <tt>:autosave</tt> enabled.
|
58
|
+
def reflect_on_all_autosave_associations
|
59
|
+
reflections.values.select { |reflection| reflection.options[:autosave] }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
class DummyReflection < ActiveRecord::Reflection::AggregateReflection
|
63
|
+
def initialize(macro, name, scope, options, active_record)
|
64
|
+
super(macro, name, scope, options, active_record)
|
65
|
+
@symbol = name
|
66
|
+
end
|
67
|
+
|
68
|
+
def polymorphic?
|
69
|
+
false
|
70
|
+
end
|
71
|
+
|
72
|
+
def foreign_key
|
73
|
+
@symbol # ??
|
74
|
+
end
|
75
|
+
def collection?
|
76
|
+
[:has_one, :has_many, :has_and_belongs_to_many].include? macro
|
77
|
+
end
|
78
|
+
def validate?
|
79
|
+
false
|
80
|
+
end
|
81
|
+
def association_class
|
82
|
+
DummyAssociation
|
83
|
+
end
|
84
|
+
|
85
|
+
def check_validity!
|
86
|
+
true
|
87
|
+
end
|
88
|
+
end
|
89
|
+
class DummyAssociationReflection < DummyReflection; end
|
90
|
+
class DummyAggregateReflection < DummyReflection; end
|
91
|
+
class DummyThroughReflection < DummyReflection; end
|
92
|
+
class DummyAssociation < ActiveRecord::Associations::Association
|
93
|
+
def writer(*args); end
|
94
|
+
def reader(*args)
|
95
|
+
self
|
96
|
+
end
|
97
|
+
def loaded?
|
98
|
+
true
|
99
|
+
end
|
100
|
+
def identifier
|
101
|
+
nil
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
data/lib/ansr/facets.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module Ansr::Facets
|
4
|
+
|
5
|
+
# represents a facet value; which is a field value and its hit count
|
6
|
+
class FacetItem < OpenStruct
|
7
|
+
def initialize *args
|
8
|
+
options = args.extract_options!
|
9
|
+
|
10
|
+
# Backwards-compat method signature
|
11
|
+
value = args.shift
|
12
|
+
hits = args.shift
|
13
|
+
|
14
|
+
options[:value] = value if value
|
15
|
+
options[:hits] = hits if hits
|
16
|
+
|
17
|
+
super(options)
|
18
|
+
end
|
19
|
+
|
20
|
+
def label
|
21
|
+
super || value
|
22
|
+
end
|
23
|
+
|
24
|
+
def as_json(props = nil)
|
25
|
+
table.as_json(props)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# represents a facet; which is a field and its values
|
30
|
+
class FacetField
|
31
|
+
attr_reader :name, :items
|
32
|
+
def initialize name, items, options = {}
|
33
|
+
@name, @items = name, items
|
34
|
+
@options = options
|
35
|
+
end
|
36
|
+
|
37
|
+
def limit
|
38
|
+
@options[:limit]
|
39
|
+
end
|
40
|
+
|
41
|
+
def sort
|
42
|
+
@options[:sort] || 'index'
|
43
|
+
end
|
44
|
+
|
45
|
+
def offset
|
46
|
+
@options[:offset] || 0
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# @response.facets.each do |facet|
|
51
|
+
# facet.name
|
52
|
+
# facet.items
|
53
|
+
# end
|
54
|
+
# "caches" the result in the @facets instance var
|
55
|
+
def facets
|
56
|
+
@facets ||= begin
|
57
|
+
facet_fields.map do |(facet_field_name,values_and_hits)|
|
58
|
+
items = []
|
59
|
+
options = {}
|
60
|
+
values_and_hits.each_slice(2) do |k,v|
|
61
|
+
items << FacetItem.new(:value => k, :hits => v)
|
62
|
+
end
|
63
|
+
options[:sort] = (params[:"f.#{facet_field_name}.facet.sort"] || params[:'facet.sort'])
|
64
|
+
if params[:"f.#{facet_field_name}.facet.limit"] || params[:"facet.limit"]
|
65
|
+
options[:limit] = (params[:"f.#{facet_field_name}.facet.limit"] || params[:"facet.limit"]).to_i
|
66
|
+
end
|
67
|
+
|
68
|
+
if params[:"f.#{facet_field_name}.facet.offset"] || params[:'facet.offset']
|
69
|
+
options[:offset] = (params[:"f.#{facet_field_name}.facet.offset"] || params[:'facet.offset']).to_i
|
70
|
+
end
|
71
|
+
FacetField.new(facet_field_name, items, options)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# pass in a facet field name and get back a Facet instance
|
77
|
+
def facet_by_field_name(name)
|
78
|
+
@facets_by_field_name ||= {}
|
79
|
+
@facets_by_field_name[name] ||= (
|
80
|
+
facets.detect{|facet|facet.name.to_s == name.to_s}
|
81
|
+
)
|
82
|
+
end
|
83
|
+
|
84
|
+
def facet_counts
|
85
|
+
@facet_counts ||= self['facet_counts'] || {}
|
86
|
+
end
|
87
|
+
|
88
|
+
# Returns the hash of all the facet_fields (ie: {'instock_b' => ['true', 123, 'false', 20]}
|
89
|
+
def facet_fields
|
90
|
+
@facet_fields ||= facet_counts['facet_fields'] || {}
|
91
|
+
end
|
92
|
+
|
93
|
+
# Returns all of the facet queries
|
94
|
+
def facet_queries
|
95
|
+
@facet_queries ||= facet_counts['facet_queries'] || {}
|
96
|
+
end
|
97
|
+
|
98
|
+
# Returns all of the facet queries
|
99
|
+
def facet_pivot
|
100
|
+
@facet_pivot ||= facet_counts['facet_pivot'] || {}
|
101
|
+
end
|
102
|
+
|
103
|
+
end # end Facets
|