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
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YjdhOTQ4ZmY2ZTY3OTFkM2YwZjQwNDI3MWI4NmEzYTYwMTc3YzkwZg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZDI1ODllMmMxOGMxMjg5MDI3MWEyYjIwZjQ5ODdkYWNhOGZjZTZhOA==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MzhhMjYwMTA5YjljZjFhZmU3M2RmOWViNjZkMzg3YzA2ODIxOTRlYzc2M2Yy
|
10
|
+
NWUyNDI2NzY1ZTY5YzQ1ZTJhMTNmNzlmOWJjYWM1MzJlYjUyY2RiZjNkNzIx
|
11
|
+
ZjVlNzMyZjBlNzBjM2ZjOTNkMmI5NmRkOTZhZGQxNjJiYmI5YzE=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZTlhMjE0NjczMjk0NDk1ZThmMzlkMGY0NWYwYzQ1OTU5NWVhMDA2NDY0N2Ux
|
14
|
+
YjE1ZGI5NTdiYTRmNGRjZmMyMmNjMzQ2ZWVlYjU4OTllN2FhNTlhYzNhMjk4
|
15
|
+
NDc1NjJmYTZhMGM0YTEzOTNkMjRmYmJmZDQzZTcxODQxMmI2Mjg=
|
data/README.md
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
ansr
|
2
|
+
====
|
3
|
+
|
4
|
+
ActiveRecord(No-SQL)::Relation + Blacklight
|
5
|
+
|
6
|
+
Ansr is a library for building ActiveRecord-style models and Relation implementations that query no-SQL data sources.
|
7
|
+
Ansr is motivated by a proposed refactoring of Blacklight at Code4Lib 2014.
|
8
|
+
|
9
|
+
[Blacklight](https://github.com/projectblacklight/blacklight) (BL) defines itself as “an open source Solr user interface discovery platform.” The coupling to Solr is evident in the structure: Solr querying facilities are sprinkled throughout several mixins that are included in BL controllers. This results in a codebase that cannot, as is regularly asked on the mailing lists, be used in front of another document store (eg ElasticSeach). But this is not necessarily the case.
|
10
|
+
|
11
|
+
BL might be refactored to locate the actual Solr querying machinery behind the core model of BL apps (currently called SolrDocument). Refactoring the codebase this way would realize several benefits:
|
12
|
+
|
13
|
+
1. Adherence to the Principle of Least Surprise: The BL document model would behave more like a Rails model backed by RDBMS. When bringing new developers into a BL project, familiarity with the standard patterns of Rails would translate more immediately to the BL context.
|
14
|
+
|
15
|
+
2. Flexible abstraction of the document store: Moving the specifics of querying the document store would make the introduction of models interacting with other stores possible. For example, the DPLA REST API exposes some Solr-like concepts, and a proof-of-concept model for an ActiveRecord-like approach to searching them can be seen at (https://github.com/barmintor/ansr/tree/master/ansr_dpla)
|
16
|
+
|
17
|
+
3. Clearer testing strategies and ease of console debugging
|
18
|
+
|
19
|
+
4. Clarification of BL’s relationship to RSolr as the provider to an analog for ActiveRecord::Relation
|
20
|
+
|
21
|
+
What would such a refactor require?
|
22
|
+
|
23
|
+
1. A definition of the backend requirements of BL beyond a reference to Solr per se: indexed documents with fields, a concept of facets corresponding to the Solr/Lucene definitions, the ability to expose Hash-like representations of results.
|
24
|
+
|
25
|
+
2. A relocation of the searching methods from Blacklight::Catalog and Blacklight::SolrHelper into a model generated to include Solr code
|
26
|
+
|
27
|
+
3. An accommodation of controller-specific Solr configuration, possibly resolved by having the BL config register Solr parms with the model a la SolrDocument extensions in BL 4
|
28
|
+
|
29
|
+
4. An abstraction of the fielded/faceted search parameters to mimic ActiveRecord limits
|
30
|
+
|
31
|
+
5. A partner institution capable of producing integration and system testing support for, at minimum, another Lucene-backed document store (ElasticSearch)
|
32
|
+
|
33
|
+
Since these changes are incompatible with current BL, they are proposed as a principal feature of BL 6.0.
|
34
|
+
|
35
|
+
An example of the kinds of models to be implemented can be seen in a [DPLA proof of concept](https://github.com/barmintor/ansr/tree/master/ansr_dpla).
|
data/ansr.gemspec
CHANGED
@@ -14,7 +14,8 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.require_paths = ["lib"]
|
15
15
|
|
16
16
|
spec.add_dependency 'loggable'
|
17
|
-
spec.add_dependency '
|
17
|
+
spec.add_dependency 'arel'
|
18
|
+
spec.add_dependency 'activerecord'
|
18
19
|
|
19
20
|
spec.add_development_dependency("rake")
|
20
21
|
spec.add_development_dependency("bundler", ">= 1.0.14")
|
@@ -0,0 +1,37 @@
|
|
1
|
+
Ansr::Blacklight
|
2
|
+
=================
|
3
|
+
|
4
|
+
A re-implementation of Blacklight's Solr model with find/search functionality moved behind ActiveRecord::Relation subclasses.
|
5
|
+
|
6
|
+
QUESTIONS
|
7
|
+
|
8
|
+
Is a closer conformation to the expectations from ActiveRecord valuable enough to forego use of Sunspot (https://github.com/sunspot/sunspot)?
|
9
|
+
|
10
|
+
REQUEST REQUIREMENTS
|
11
|
+
|
12
|
+
Considering the following block from the BL Solr request code:
|
13
|
+
SINGULAR_KEYS = %W{ facet fl q qt rows start spellcheck spellcheck.q sort
|
14
|
+
per_page wt hl group defType}
|
15
|
+
ARRAY_KEYS = %W{facet.field facet.query facet.pivot fq hl.fl }
|
16
|
+
|
17
|
+
facet : a boolean field indicating the requested presence of facet info in response
|
18
|
+
fl : the selected fields
|
19
|
+
q : the query (fielding?)
|
20
|
+
qt : query type; indicates queryHandler in Solr
|
21
|
+
rows : corresponds to limit
|
22
|
+
start : corresponds to offset
|
23
|
+
spellcheck : boolean?
|
24
|
+
spellcheck.q : ?
|
25
|
+
sort : ?
|
26
|
+
facet.field : the fields for which facet info is requested
|
27
|
+
facet.query : ?
|
28
|
+
facet.pivot : ?
|
29
|
+
fq : ?
|
30
|
+
hl.fl : field to highlight
|
31
|
+
How is facet query different from filter query (fq)?
|
32
|
+
|
33
|
+
Relations must be configurable with default parameters; this is fairly easy to do with a template Relation to spawn the default scope from.
|
34
|
+
|
35
|
+
RESPONSE REQUIREMENTS
|
36
|
+
|
37
|
+
tbd
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../lib/ansr/version')
|
2
|
+
version = Ansr.version
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = 'ansr_blacklight'
|
5
|
+
spec.version = version
|
6
|
+
spec.platform = Gem::Platform::RUBY
|
7
|
+
spec.authors = ["Benjamin Armintor"]
|
8
|
+
spec.email = ["armintor@gmail.com"]
|
9
|
+
spec.summary = 'ActiveRecord-style models and relations for Blacklight'
|
10
|
+
spec.description = 'Wrapping the Blacklight/RSolr in Rails-like models and relations'
|
11
|
+
spec.homepage = 'https://github.com/barmintor/ansr/tree/master/ansr_blacklight'
|
12
|
+
spec.files = `git ls-files`.split("\n")
|
13
|
+
spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
|
+
spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
15
|
+
spec.require_paths = ["lib"]
|
16
|
+
|
17
|
+
spec.add_dependency 'ansr', version
|
18
|
+
spec.add_dependency 'json-ld'
|
19
|
+
spec.add_dependency 'rest-client'
|
20
|
+
spec.add_dependency 'loggable'
|
21
|
+
spec.add_dependency "rails", ">= 3.2.6", "< 5"
|
22
|
+
# spec.add_dependency 'blacklight', '>=5.1.0'
|
23
|
+
spec.add_dependency 'sass-rails'
|
24
|
+
spec.add_development_dependency("rake")
|
25
|
+
spec.add_development_dependency("bundler", ">= 1.0.14")
|
26
|
+
spec.add_development_dependency "rspec-rails"
|
27
|
+
spec.add_development_dependency("yard")
|
28
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'ansr'
|
2
|
+
require 'rsolr'
|
3
|
+
module Ansr::Blacklight
|
4
|
+
extend ActiveSupport::Autoload
|
5
|
+
autoload :SolrProjectionMethods, 'ansr_blacklight/relation/solr_projection_methods'
|
6
|
+
require 'ansr_blacklight/solr'
|
7
|
+
require 'ansr_blacklight/request_builders'
|
8
|
+
require 'ansr_blacklight/arel'
|
9
|
+
require 'ansr_blacklight/connection_adapters/no_sql_adapter'
|
10
|
+
require 'ansr_blacklight/relation'
|
11
|
+
require 'ansr_blacklight/model/querying'
|
12
|
+
require 'ansr_blacklight/base'
|
13
|
+
|
14
|
+
def self.solr_file
|
15
|
+
"#{::Rails.root.to_s}/config/solr.yml"
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.solr
|
19
|
+
@solr ||= RSolr.connect(Ansr::Blacklight.solr_config)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.solr_config
|
23
|
+
@solr_config ||= begin
|
24
|
+
raise "The #{::Rails.env} environment settings were not found in the solr.yml config" unless solr_yml[::Rails.env]
|
25
|
+
solr_yml[::Rails.env].symbolize_keys
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.solr_yml
|
30
|
+
require 'erb'
|
31
|
+
require 'yaml'
|
32
|
+
|
33
|
+
return @solr_yml if @solr_yml
|
34
|
+
unless File.exists?(solr_file)
|
35
|
+
raise "You are missing a solr configuration file: #{solr_file}. Have you run \"rails generate blacklight:install\"?"
|
36
|
+
end
|
37
|
+
|
38
|
+
begin
|
39
|
+
@solr_erb = ERB.new(IO.read(solr_file)).result(binding)
|
40
|
+
rescue Exception => e
|
41
|
+
raise("solr.yml was found, but could not be parsed with ERB. \n#{$!.inspect}")
|
42
|
+
end
|
43
|
+
|
44
|
+
begin
|
45
|
+
@solr_yml = YAML::load(@solr_erb)
|
46
|
+
rescue StandardError => e
|
47
|
+
raise("solr.yml was found, but could not be parsed.\n")
|
48
|
+
end
|
49
|
+
|
50
|
+
if @solr_yml.nil? || !@solr_yml.is_a?(Hash)
|
51
|
+
raise("solr.yml was found, but was blank or malformed.\n")
|
52
|
+
end
|
53
|
+
|
54
|
+
return @solr_yml
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Ansr::Blacklight::Arel
|
2
|
+
class BigTable < Ansr::Arel::BigTable
|
3
|
+
attr_accessor :name
|
4
|
+
|
5
|
+
def initialize(klass, engine=nil, config=nil)
|
6
|
+
super(klass, engine)
|
7
|
+
@name = 'select'
|
8
|
+
self.config(config)
|
9
|
+
end
|
10
|
+
|
11
|
+
delegate :index_fields, to: :config
|
12
|
+
delegate :show_fields, to: :config
|
13
|
+
delegate :sort_fields, to: :config
|
14
|
+
|
15
|
+
def filterable
|
16
|
+
config.facet_fields.keys
|
17
|
+
end
|
18
|
+
|
19
|
+
alias_method :facets, :filterable
|
20
|
+
|
21
|
+
def filterable?(field)
|
22
|
+
filterable.include? field
|
23
|
+
end
|
24
|
+
|
25
|
+
def constrainable
|
26
|
+
index_fields.keys
|
27
|
+
end
|
28
|
+
|
29
|
+
def constrainable?(field)
|
30
|
+
index_fields.include?(field)
|
31
|
+
end
|
32
|
+
|
33
|
+
def selectable
|
34
|
+
show_fields.keys + index_fields.keys
|
35
|
+
end
|
36
|
+
|
37
|
+
def selectable?(field)
|
38
|
+
show_fields.include? field
|
39
|
+
end
|
40
|
+
|
41
|
+
def fields
|
42
|
+
(constrainable + selectable + filterable).uniq
|
43
|
+
end
|
44
|
+
|
45
|
+
def sortable
|
46
|
+
sort_fields.keys
|
47
|
+
end
|
48
|
+
|
49
|
+
def sortable?(field)
|
50
|
+
sort_fields.include? field
|
51
|
+
end
|
52
|
+
|
53
|
+
def primary_key
|
54
|
+
@primary_key ||= ::Arel::Attribute.new(self, config.document_unique_id_param.to_s)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,217 @@
|
|
1
|
+
module Ansr::Blacklight::Arel::Visitors
|
2
|
+
class QueryBuilder < Ansr::Arel::Visitors::QueryBuilder
|
3
|
+
include Ansr::Blacklight::RequestBuilders
|
4
|
+
attr_reader :solr_request
|
5
|
+
|
6
|
+
def initialize(table)
|
7
|
+
super(table)
|
8
|
+
@solr_request = Ansr::Blacklight::Solr::Request.new
|
9
|
+
table.configure_fields.each do |k,v|
|
10
|
+
unless v[:select].blank?
|
11
|
+
v[:select].each do |sk, sv|
|
12
|
+
key = "f.#{k}.#{sk}".to_sym
|
13
|
+
@solr_request[key] = sv
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
public
|
20
|
+
def query_opts
|
21
|
+
solr_request
|
22
|
+
end
|
23
|
+
|
24
|
+
# determines whether multiple values should accumulate or overwrite in merges
|
25
|
+
def multiple?(field_key)
|
26
|
+
true
|
27
|
+
end
|
28
|
+
|
29
|
+
def visit_String o, a
|
30
|
+
case a
|
31
|
+
when Ansr::Arel::Visitors::From
|
32
|
+
query_opts.path = o
|
33
|
+
when Ansr::Arel::Visitors::Filter
|
34
|
+
filter_field(o.to_sym)
|
35
|
+
when Ansr::Arel::Visitors::Order
|
36
|
+
order(o)
|
37
|
+
else
|
38
|
+
raise "visited String \"#{o}\" with #{a.to_s}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
def visit_Arel_Nodes_TableAlias(object, attribute)
|
44
|
+
solr_request[:qt] = object.name.to_s
|
45
|
+
opts = {qt: object.name.to_s}
|
46
|
+
if (cf = table[object.name]).is_a? Ansr::Arel::ConfiguredField
|
47
|
+
opts.merge!(cf.config.fetch(:query,{}))
|
48
|
+
end
|
49
|
+
solr_request.merge!(opts)
|
50
|
+
visit object.relation, attribute
|
51
|
+
end
|
52
|
+
|
53
|
+
def visit_Ansr_Arel_Nodes_ProjectionTraits(object, attribute)
|
54
|
+
solr_request[:wt] = object.wt if object.wt
|
55
|
+
solr_request[:defType] = object.defType if object.defType
|
56
|
+
visit(object.expr, attribute)
|
57
|
+
end
|
58
|
+
|
59
|
+
def visit_Arel_SqlLiteral(n, attribute)
|
60
|
+
select_val = n.to_s.split(" AS ")
|
61
|
+
if Ansr::Arel::Visitors::Filter === attribute
|
62
|
+
solr_request.append_facet_fields(select_val[0].to_sym)
|
63
|
+
else
|
64
|
+
field(select_val[0].to_sym)
|
65
|
+
if select_val[1]
|
66
|
+
query_opts.aliases ||= {}
|
67
|
+
query_opts.aliases[select_val[0]] = select_val[1]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def from(value)
|
73
|
+
if value.respond_to? :name
|
74
|
+
solr_request.path = value.name
|
75
|
+
else
|
76
|
+
solr_request.path = value.to_s
|
77
|
+
end
|
78
|
+
self.table=value if (value.is_a? Ansr::Arel::BigTable)
|
79
|
+
end
|
80
|
+
|
81
|
+
def field(field_name)
|
82
|
+
return unless field_name
|
83
|
+
old = query_opts[:fields] ? Array(query_opts[:fields]) : []
|
84
|
+
field_names = (old + Array(field_name)).uniq
|
85
|
+
if field_names[0]
|
86
|
+
query_opts[:fields] = field_names[1] ? field_names : field_names[0]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def filter_field(field_name)
|
91
|
+
return unless field_name
|
92
|
+
old = solr_request[:"facet.field"] ? Array(solr_request[:"facet.field"]) : []
|
93
|
+
fields = Array(field_name).delete_if {|x| old.include? x}
|
94
|
+
solr_request.append_facet_fields(fields)
|
95
|
+
end
|
96
|
+
|
97
|
+
def visit_Arel_Nodes_Equality(object, attribute)
|
98
|
+
field_key = (object.left.respond_to? :expr) ? field_key_from_node(object.left.expr) : field_key_from_node(object.left)
|
99
|
+
opts = {}
|
100
|
+
opts.merge!(local_field_params(field_key))
|
101
|
+
opts.merge!(object.left.config.fetch(:local,{})) if object.left.respond_to? :config
|
102
|
+
if Ansr::Arel::Visitors::Filter === attribute or Ansr::Arel::Nodes::Filter === object.left
|
103
|
+
add_filter_fq_to_solr(solr_request, f: {field_key => object.right}, opts: opts)
|
104
|
+
else
|
105
|
+
# check the table for configured fields
|
106
|
+
add_query_to_solr(field_key, object.right, opts)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def visit_Arel_Nodes_NotEqual(object, attribute)
|
111
|
+
end
|
112
|
+
|
113
|
+
def visit_Arel_Nodes_Or(object, attribute)
|
114
|
+
end
|
115
|
+
|
116
|
+
def visit_Arel_Nodes_Grouping(object, attribute)
|
117
|
+
visit object.expr, attribute
|
118
|
+
end
|
119
|
+
|
120
|
+
def visit_Arel_Nodes_Group(object, attribute)
|
121
|
+
solr_request[:group] = object.expr.to_s
|
122
|
+
end
|
123
|
+
|
124
|
+
def visit_Ansr_Arel_Nodes_Facet(object, attribute)
|
125
|
+
name = object.expr
|
126
|
+
name = name.name if name.respond_to? :name
|
127
|
+
default = false
|
128
|
+
if name == ::Arel.star
|
129
|
+
prefix = "facet."
|
130
|
+
default = true
|
131
|
+
else
|
132
|
+
filter_field(name.to_sym) unless default
|
133
|
+
solr_request.append_facet_fields(name.to_sym) unless default
|
134
|
+
prefix = "f.#{name}.facet."
|
135
|
+
end
|
136
|
+
# there's got to be a helper for this
|
137
|
+
if object.pivot
|
138
|
+
solr_request.append_facet_pivot with_ex_local_param(object.ex, object.pivot.join(","))
|
139
|
+
elsif object.query
|
140
|
+
solr_request.append_facet_query object.query.map { |k, x| with_ex_local_param(object.ex, x[:fq]) }
|
141
|
+
else
|
142
|
+
object.opts.each do |att, value|
|
143
|
+
solr_request["#{prefix}#{att.to_s}".to_sym] = value.to_s unless att == :ex
|
144
|
+
end
|
145
|
+
solr_request.append_facet_fields with_ex_local_param(object.ex, name.to_sym) unless default
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def visit_Ansr_Arel_Nodes_Spellcheck(object, attribute)
|
150
|
+
unless object.expr == false
|
151
|
+
solr_request[:spellcheck] = object.expr.to_s
|
152
|
+
end
|
153
|
+
object.opts.each do |att, val|
|
154
|
+
solr_request["spellcheck.#{att.to_s}".to_sym] = val if att != :select
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def visit_Ansr_Arel_Nodes_Highlight(object, attribute)
|
159
|
+
unless object.expr == false or object.expr == true
|
160
|
+
solr_request[:hl] = object.expr.to_s
|
161
|
+
end
|
162
|
+
object.opts.each do |att, val|
|
163
|
+
solr_request["hl.#{att.to_s}".to_sym] = val if att != :select
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def order(*arel_nodes)
|
168
|
+
direction = nil
|
169
|
+
nodes = []
|
170
|
+
arel_nodes.inject(nodes) do |c, n|
|
171
|
+
if ::Arel::Nodes::Ordering === n
|
172
|
+
c << n
|
173
|
+
elsif n.is_a? String
|
174
|
+
_ns = n.split(',')
|
175
|
+
_ns.each do |_n|
|
176
|
+
_p = _n.split(/\s+/)
|
177
|
+
if (_p[1])
|
178
|
+
_p[1] = _p[1].downcase.to_sym
|
179
|
+
else
|
180
|
+
_p[1] = :asc
|
181
|
+
end
|
182
|
+
c << table[_p[0].to_sym].send(_p[1])
|
183
|
+
end
|
184
|
+
end
|
185
|
+
c
|
186
|
+
end
|
187
|
+
nodes.each do |node|
|
188
|
+
if ::Arel::Nodes::Ordering === node
|
189
|
+
if solr_request[:sort_by]
|
190
|
+
solr_request[:sort_by] = Array[solr_request[:sort_by]] << node.expr.name
|
191
|
+
else
|
192
|
+
solr_request[:sort_by] = node.expr.name
|
193
|
+
end
|
194
|
+
direction = :asc if (::Arel::Nodes::Ascending === node and direction)
|
195
|
+
direction = :desc if (::Arel::Nodes::Descending === node)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
solr_request[:sort_order] = direction if direction
|
199
|
+
end
|
200
|
+
|
201
|
+
def visit_Arel_Nodes_Limit(object, attribute)
|
202
|
+
value = object.expr
|
203
|
+
if value and (value = value.to_i)
|
204
|
+
raise "Page size cannot be > 500 (#{value}" if value > 500
|
205
|
+
solr_request[:rows] = value.to_s
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def visit_Arel_Nodes_Offset(object, attribute)
|
210
|
+
value = object.expr
|
211
|
+
if value
|
212
|
+
solr_request[:start] = value.to_s
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
end
|
217
|
+
end
|