solrb 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.circleci/config.yml +69 -0
- data/.circleci/run-with-local-config.sh +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.rubocop.yml +30 -0
- data/.ruby-version +1 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +83 -0
- data/LICENSE.txt +21 -0
- data/README.md +259 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/solr/commit/request.rb +15 -0
- data/lib/solr/configuration.rb +66 -0
- data/lib/solr/connection.rb +33 -0
- data/lib/solr/core_configuration/core_config.rb +44 -0
- data/lib/solr/core_configuration/core_config_builder.rb +51 -0
- data/lib/solr/core_configuration/dynamic_field.rb +17 -0
- data/lib/solr/core_configuration/field.rb +20 -0
- data/lib/solr/delete/request.rb +34 -0
- data/lib/solr/document.rb +26 -0
- data/lib/solr/document_collection.rb +55 -0
- data/lib/solr/errors/ambiguous_core_error.rb +9 -0
- data/lib/solr/errors/solr_query_error.rb +4 -0
- data/lib/solr/errors/solr_url_not_defined_error.rb +16 -0
- data/lib/solr/grouped_document_collection.rb +38 -0
- data/lib/solr/indexing/document.rb +25 -0
- data/lib/solr/indexing/request.rb +22 -0
- data/lib/solr/query/request/boost_magnitude.rb +9 -0
- data/lib/solr/query/request/boosting/dictionary_boost_function.rb +36 -0
- data/lib/solr/query/request/boosting/exists_boost_function.rb +27 -0
- data/lib/solr/query/request/boosting/field_value_less_than_boost_function.rb +25 -0
- data/lib/solr/query/request/boosting/field_value_match_boost_function.rb +24 -0
- data/lib/solr/query/request/boosting/geodist_function.rb +37 -0
- data/lib/solr/query/request/boosting/ln_function_boost.rb +28 -0
- data/lib/solr/query/request/boosting/numeric_field_value_match_boost_function.rb +13 -0
- data/lib/solr/query/request/boosting/phrase_proximity_boost.rb +27 -0
- data/lib/solr/query/request/boosting/ranking_field_boost_function.rb +20 -0
- data/lib/solr/query/request/boosting/recent_field_value_boost_function.rb +26 -0
- data/lib/solr/query/request/boosting/scale_function_boost.rb +28 -0
- data/lib/solr/query/request/boosting/textual_field_value_match_boost_function.rb +13 -0
- data/lib/solr/query/request/boosting.rb +46 -0
- data/lib/solr/query/request/edismax_adapter.rb +163 -0
- data/lib/solr/query/request/facet.rb +68 -0
- data/lib/solr/query/request/field_with_boost.rb +18 -0
- data/lib/solr/query/request/filter.rb +73 -0
- data/lib/solr/query/request/geo_filter.rb +26 -0
- data/lib/solr/query/request/grouping.rb +37 -0
- data/lib/solr/query/request/or_filter.rb +16 -0
- data/lib/solr/query/request/runner.rb +46 -0
- data/lib/solr/query/request/sorting/field.rb +16 -0
- data/lib/solr/query/request/sorting.rb +34 -0
- data/lib/solr/query/request/spellcheck.rb +74 -0
- data/lib/solr/query/request.rb +49 -0
- data/lib/solr/query/response/facet_value.rb +16 -0
- data/lib/solr/query/response/field_facets.rb +25 -0
- data/lib/solr/query/response/parser.rb +154 -0
- data/lib/solr/query/response/spellcheck.rb +42 -0
- data/lib/solr/query/response.rb +48 -0
- data/lib/solr/response/header.rb +25 -0
- data/lib/solr/response/http_status.rb +27 -0
- data/lib/solr/response/parser.rb +47 -0
- data/lib/solr/response/solr_error.rb +31 -0
- data/lib/solr/response.rb +52 -0
- data/lib/solr/support/connection_helper.rb +12 -0
- data/lib/solr/support/hash_extensions.rb +29 -0
- data/lib/solr/support/schema_helper.rb +11 -0
- data/lib/solr/support/string_extensions.rb +12 -0
- data/lib/solr/support/url_helper.rb +12 -0
- data/lib/solr/support.rb +5 -0
- data/lib/solr/testing.rb +19 -0
- data/lib/solr/version.rb +3 -0
- data/lib/solr.rb +65 -0
- data/solrb.gemspec +36 -0
- metadata +261 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
module Solr
|
2
|
+
module Query
|
3
|
+
class Response
|
4
|
+
class FacetValue
|
5
|
+
attr_reader :text, :count, :subfacets
|
6
|
+
|
7
|
+
def initialize(text:, count:, subfacets: [])
|
8
|
+
@text = text
|
9
|
+
@count = count
|
10
|
+
@subfacets = subfacets
|
11
|
+
freeze
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Solr
|
2
|
+
module Query
|
3
|
+
class Response
|
4
|
+
class FieldFacets
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
attr_reader :field, :facet_values, :count, :subfacets
|
8
|
+
|
9
|
+
def initialize(field:, facet_values:, count:, subfacets: [])
|
10
|
+
@field = field
|
11
|
+
@facet_values = facet_values
|
12
|
+
@count = count
|
13
|
+
@subfacets = subfacets
|
14
|
+
|
15
|
+
freeze
|
16
|
+
end
|
17
|
+
|
18
|
+
def each(&b)
|
19
|
+
return enum_for(:each) unless block_given?
|
20
|
+
facet_values.each(&b)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
module Solr
|
2
|
+
module Query
|
3
|
+
class Response
|
4
|
+
class Parser
|
5
|
+
SOLR_INFINITY = '*'.freeze # for cases like [100000 TO *]
|
6
|
+
|
7
|
+
include Solr::Support::SchemaHelper
|
8
|
+
|
9
|
+
attr_reader :request, :solr_response
|
10
|
+
|
11
|
+
def initialize(request:, solr_response:)
|
12
|
+
@request = request
|
13
|
+
@solr_response = solr_response
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_response
|
17
|
+
documents = parse_documents
|
18
|
+
total_count = parse_total_count
|
19
|
+
if !request.grouping.empty?
|
20
|
+
group_counts = parse_group_counts
|
21
|
+
document_collection = Solr::GroupedDocumentCollection.new(documents: documents,
|
22
|
+
total_count: total_count,
|
23
|
+
group_counts: group_counts)
|
24
|
+
else
|
25
|
+
document_collection = Solr::DocumentCollection.new(documents: documents, total_count: total_count)
|
26
|
+
end
|
27
|
+
Solr::Query::Response.new(
|
28
|
+
documents: document_collection,
|
29
|
+
available_facets: field_facet_collection,
|
30
|
+
spellcheck: spellcheck
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def parse_total_count
|
37
|
+
if !request.grouping.empty?
|
38
|
+
parse_grouped_total_count(solr_grouping_field)
|
39
|
+
else
|
40
|
+
parse_regular_total_count
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def parse_grouped_total_count(solr_grouping_field)
|
45
|
+
solr_response['grouped'][solr_grouping_field]['groups'].reduce(0) do |acc, group|
|
46
|
+
acc + group['doclist']['numFound'].to_i
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def parse_regular_total_count
|
51
|
+
solr_response.dig('response', 'numFound').to_i
|
52
|
+
end
|
53
|
+
|
54
|
+
def parse_group_counts
|
55
|
+
group_counts = {}
|
56
|
+
unless request.grouping.empty?
|
57
|
+
Array(solr_response.dig('grouped', solr_grouping_field, 'groups')).each do |group|
|
58
|
+
group_counts[group['groupValue']] = group['doclist']['numFound']
|
59
|
+
end
|
60
|
+
end
|
61
|
+
group_counts
|
62
|
+
end
|
63
|
+
|
64
|
+
def parse_documents
|
65
|
+
if !request.grouping.empty?
|
66
|
+
parse_grouped_documents(solr_grouping_field)
|
67
|
+
else
|
68
|
+
parse_regular_documents
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def parse_regular_documents
|
73
|
+
solr_response['response']['docs'].map do |d|
|
74
|
+
debug_info = solr_response.dig('debug', 'explain', d['id'])
|
75
|
+
Document.new(id: d['id'], score: d['score'], debug_info: debug_info)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def parse_grouped_documents(solr_grouping_field)
|
80
|
+
Array(solr_response.dig('grouped', solr_grouping_field, 'groups')).map do |group|
|
81
|
+
Array(group.dig('doclist', 'docs')).map do |doc|
|
82
|
+
next unless doc
|
83
|
+
debug_info = solr_response.dig('debug', 'explain', doc['id'])
|
84
|
+
group_information = Document::GroupInformation.new(key: solr_grouping_field, value: group['groupValue'])
|
85
|
+
Document.new(id: doc['id'], score: doc['score'],
|
86
|
+
debug_info: debug_info, group: group_information)
|
87
|
+
end
|
88
|
+
end.flatten.compact
|
89
|
+
end
|
90
|
+
|
91
|
+
def solr_grouping_field
|
92
|
+
grouping_field = request.grouping.field
|
93
|
+
solarize_field(grouping_field)
|
94
|
+
end
|
95
|
+
|
96
|
+
def field_facet_collection
|
97
|
+
return [] unless solr_response_has_facet_data?
|
98
|
+
|
99
|
+
raw_facet_data = solr_response['facets'].except('count')
|
100
|
+
|
101
|
+
parse_facets(raw_facet_data)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Each facet could contain subfacets.
|
105
|
+
# We need to parse them recursively and store in subfacets array.
|
106
|
+
def parse_facets(raw_facet_data)
|
107
|
+
raw_facet_data.map do |field_name, facet_data|
|
108
|
+
# We need to handle use case when facet_data is not a hash
|
109
|
+
# (e.g. query facet request with aggregate function)
|
110
|
+
if facet_data.is_a?(Hash)
|
111
|
+
parse_facet_hash(field_name, facet_data)
|
112
|
+
else
|
113
|
+
parse_facet_count(field_name, facet_data)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def parse_facet_hash(field_name, facet_data)
|
119
|
+
count = facet_data.delete('count')
|
120
|
+
facets = facet_data.delete('buckets')
|
121
|
+
|
122
|
+
facet_values =
|
123
|
+
Array(facets).map do |facet|
|
124
|
+
text = facet.delete('val')
|
125
|
+
count = facet.delete('count')
|
126
|
+
|
127
|
+
Solr::Query::Response::FacetValue.new(text: text, count: count, subfacets: parse_facets(facet))
|
128
|
+
end
|
129
|
+
|
130
|
+
Solr::Query::Response::FieldFacets.new(field: field_name,
|
131
|
+
facet_values: facet_values,
|
132
|
+
count: count.to_i,
|
133
|
+
subfacets: parse_facets(facet_data))
|
134
|
+
end
|
135
|
+
|
136
|
+
def parse_facet_count(field_name, count)
|
137
|
+
Solr::Query::Response::FieldFacets.new(field: field_name,
|
138
|
+
facet_values: [],
|
139
|
+
count: count.to_i,
|
140
|
+
subfacets: [])
|
141
|
+
end
|
142
|
+
|
143
|
+
def solr_response_has_facet_data?
|
144
|
+
solr_response['facets']
|
145
|
+
end
|
146
|
+
|
147
|
+
def spellcheck
|
148
|
+
return Solr::Query::Response::Spellcheck.empty unless solr_response['spellcheck']
|
149
|
+
Solr::Query::Response::Spellcheck.new(solr_response['spellcheck'])
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Solr
|
2
|
+
module Query
|
3
|
+
class Response
|
4
|
+
class Spellcheck
|
5
|
+
attr_reader :response
|
6
|
+
|
7
|
+
class Collation
|
8
|
+
def initialize(data)
|
9
|
+
@data = data
|
10
|
+
end
|
11
|
+
|
12
|
+
def collation_query
|
13
|
+
@data['collationQuery']
|
14
|
+
end
|
15
|
+
|
16
|
+
def hits
|
17
|
+
@data['hits']
|
18
|
+
end
|
19
|
+
|
20
|
+
def misspellings_and_corrections
|
21
|
+
return {} unless @data['misspellingsAndCorrections']
|
22
|
+
@data['misspellingsAndCorrections'].in_groups_of(2).to_h
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.empty
|
27
|
+
new({})
|
28
|
+
end
|
29
|
+
|
30
|
+
def initialize(response)
|
31
|
+
@response = response || {}
|
32
|
+
end
|
33
|
+
|
34
|
+
def collations
|
35
|
+
Array(response['collations']).flatten(1).in_groups_of(2).map do |_, collation|
|
36
|
+
Collation.new(collation)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'solr/query/response/facet_value'
|
2
|
+
require 'solr/query/response/field_facets'
|
3
|
+
require 'solr/query/response/parser'
|
4
|
+
require 'solr/query/response/spellcheck'
|
5
|
+
|
6
|
+
module Solr
|
7
|
+
module Query
|
8
|
+
class Response
|
9
|
+
attr_reader :documents, :available_facets, :spellcheck
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def empty
|
13
|
+
new(documents: Solr::DocumentCollection.empty)
|
14
|
+
end
|
15
|
+
|
16
|
+
def empty_grouped
|
17
|
+
new(documents: Solr::GroupedDocumentCollection.empty)
|
18
|
+
end
|
19
|
+
|
20
|
+
def manual_grouped_documents(ids)
|
21
|
+
documents = ids.map { |id| Solr::Document.new(id: id) }
|
22
|
+
group_counts = ids.each_with_object({}) do |id, acc|
|
23
|
+
acc[id] = 1
|
24
|
+
end
|
25
|
+
new(documents: Solr::GroupedDocumentCollection.new(
|
26
|
+
documents: documents,
|
27
|
+
total_count: ids.count,
|
28
|
+
group_counts: group_counts
|
29
|
+
))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(documents:, available_facets: [], spellcheck: Solr::Query::Response::Spellcheck.empty)
|
34
|
+
@documents = documents
|
35
|
+
@available_facets = available_facets
|
36
|
+
@spellcheck = spellcheck
|
37
|
+
end
|
38
|
+
|
39
|
+
def total_count
|
40
|
+
@documents.total_count
|
41
|
+
end
|
42
|
+
|
43
|
+
def empty?
|
44
|
+
total_count.zero?
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Solr
|
2
|
+
class Response
|
3
|
+
class Header
|
4
|
+
attr_reader :status, :time
|
5
|
+
|
6
|
+
def initialize(status:, time: 0)
|
7
|
+
@status = status
|
8
|
+
@time = time
|
9
|
+
freeze
|
10
|
+
end
|
11
|
+
|
12
|
+
def ok?
|
13
|
+
status.zero?
|
14
|
+
end
|
15
|
+
|
16
|
+
def inspect
|
17
|
+
if ok?
|
18
|
+
'OK'
|
19
|
+
else
|
20
|
+
status.to_s
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Solr
|
2
|
+
class Response
|
3
|
+
class HttpStatus
|
4
|
+
class << self
|
5
|
+
def ok
|
6
|
+
new(status: 200, message: 'OK')
|
7
|
+
end
|
8
|
+
|
9
|
+
def not_found
|
10
|
+
new(status: 404, message: 'Not Found')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :status, :message
|
15
|
+
|
16
|
+
def initialize(status:, message:)
|
17
|
+
@status = status
|
18
|
+
@message = message
|
19
|
+
freeze
|
20
|
+
end
|
21
|
+
|
22
|
+
def inspect
|
23
|
+
"#{status} (#{message})"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Solr
|
2
|
+
class Response
|
3
|
+
class Parser
|
4
|
+
def initialize(raw_response)
|
5
|
+
@raw_response = raw_response
|
6
|
+
end
|
7
|
+
|
8
|
+
def parse
|
9
|
+
# 404 is a special case, it didn't hit Solr (more likely than not)
|
10
|
+
return not_found_response if @raw_response.status == 404
|
11
|
+
parsed_body = JSON.parse(@raw_response.body).freeze
|
12
|
+
http_status = parse_http_status
|
13
|
+
header = parse_header(parsed_body)
|
14
|
+
solr_error = parse_solr_error(parsed_body)
|
15
|
+
Solr::Response.new(header: header, http_status: http_status, solr_error: solr_error, body: parsed_body)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def not_found_response
|
21
|
+
Solr::Response.new(
|
22
|
+
header: Solr::Response::Header.new(status: 404),
|
23
|
+
http_status: Solr::Response::HttpStatus.not_found,
|
24
|
+
solr_error: nil
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
def parse_header(parsed_body)
|
29
|
+
parsed_header = parsed_body['responseHeader']
|
30
|
+
status = parsed_header['status'].to_i
|
31
|
+
time = parsed_header['QTime'].to_i
|
32
|
+
Solr::Response::Header.new(status: status, time: time)
|
33
|
+
end
|
34
|
+
|
35
|
+
def parse_http_status
|
36
|
+
HttpStatus.new(status: @raw_response.status, message: @raw_response.reason_phrase)
|
37
|
+
end
|
38
|
+
|
39
|
+
def parse_solr_error(parsed_body)
|
40
|
+
return Solr::Response::SolrError.none unless parsed_body['error']
|
41
|
+
code = parsed_body['error']['code'].to_i
|
42
|
+
message = parsed_body['error']['msg']
|
43
|
+
Solr::Response::SolrError.new(code: code, message: message)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Solr
|
2
|
+
class Response
|
3
|
+
class SolrError
|
4
|
+
class None < SolrError
|
5
|
+
def initialize
|
6
|
+
super(code: nil, message: nil)
|
7
|
+
freeze
|
8
|
+
end
|
9
|
+
|
10
|
+
def inspect
|
11
|
+
'SolrError: None'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.none
|
16
|
+
None.new
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :code, :message
|
20
|
+
def initialize(code:, message:)
|
21
|
+
@code = code
|
22
|
+
@message = message
|
23
|
+
freeze
|
24
|
+
end
|
25
|
+
|
26
|
+
def inspect
|
27
|
+
"#{message} (#{code})"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'solr/response/header'
|
2
|
+
require 'solr/response/http_status'
|
3
|
+
require 'solr/response/solr_error'
|
4
|
+
require 'solr/response/parser'
|
5
|
+
|
6
|
+
module Solr
|
7
|
+
class Response
|
8
|
+
OK = 'OK'.freeze
|
9
|
+
|
10
|
+
def self.from_raw_response(response)
|
11
|
+
Solr::Response::Parser.new(response).parse
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :header, :http_status, :solr_error, :body
|
15
|
+
|
16
|
+
def initialize(header:, http_status: HttpStatus.ok, solr_error: SolrError.none, body: {})
|
17
|
+
@header = header
|
18
|
+
@http_status = http_status
|
19
|
+
@solr_error = solr_error
|
20
|
+
@body = body
|
21
|
+
freeze
|
22
|
+
end
|
23
|
+
|
24
|
+
def ok?
|
25
|
+
header.ok?
|
26
|
+
end
|
27
|
+
|
28
|
+
def error?
|
29
|
+
!ok?
|
30
|
+
end
|
31
|
+
|
32
|
+
def status
|
33
|
+
if header.status.zero?
|
34
|
+
OK
|
35
|
+
else
|
36
|
+
header.status
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def error_message
|
41
|
+
return if ok?
|
42
|
+
solr_error ? solr_error.message : http_status.inspect
|
43
|
+
end
|
44
|
+
|
45
|
+
def inspect
|
46
|
+
return OK if ok?
|
47
|
+
str = "Error: #{http_status.inspect}"
|
48
|
+
str << "\n#{solr_error.inspect}" if solr_error
|
49
|
+
str
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Solr
|
2
|
+
module Support
|
3
|
+
module ConnectionHelper
|
4
|
+
def connection(path, commit: false)
|
5
|
+
url_params = {}
|
6
|
+
url_params[:commit] = true if commit
|
7
|
+
url = Solr::Support::UrlHelper.solr_url(path, url_params: url_params)
|
8
|
+
Solr::Connection.new(url)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Solr
|
2
|
+
module Support
|
3
|
+
module HashExtensions
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def symbolize_recursive(hash)
|
7
|
+
{}.tap do |h|
|
8
|
+
hash.each { |key, value| h[key.to_sym] = transform(value) }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def transform(thing)
|
15
|
+
case thing
|
16
|
+
when Hash then symbolize_recursive(thing)
|
17
|
+
when Array then thing.map { |v| transform(v) }
|
18
|
+
else; thing
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
refine Hash do
|
23
|
+
def deep_symbolize_keys
|
24
|
+
HashExtensions.symbolize_recursive(self)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Solr
|
2
|
+
module Support
|
3
|
+
module UrlHelper
|
4
|
+
def self.solr_url(path, url_params: {})
|
5
|
+
full_url = File.join(Solr.current_core_config.uri, path)
|
6
|
+
full_uri = Addressable::URI.parse(full_url)
|
7
|
+
full_uri.query_values = url_params if url_params.any?
|
8
|
+
full_uri
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/solr/support.rb
ADDED
data/lib/solr/testing.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Solr
|
2
|
+
module Testing
|
3
|
+
class << self
|
4
|
+
attr_reader :last_solr_request_params, :last_solr_response
|
5
|
+
|
6
|
+
def subscribe_to_events
|
7
|
+
if defined? ActiveSupport::Notifications
|
8
|
+
ActiveSupport::Notifications.subscribe('solrb.request_response_cycle') do |*args|
|
9
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
10
|
+
@last_solr_request_params = event.payload[:request][:params]
|
11
|
+
@last_solr_response = event.payload[:response]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
Solr::Testing.subscribe_to_events
|
data/lib/solr/version.rb
ADDED
data/lib/solr.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'faraday'
|
3
|
+
require 'addressable/uri'
|
4
|
+
require 'solr/support'
|
5
|
+
require 'solr/configuration'
|
6
|
+
require 'solr/version'
|
7
|
+
require 'solr/connection'
|
8
|
+
require 'solr/document'
|
9
|
+
require 'solr/document_collection'
|
10
|
+
require 'solr/grouped_document_collection'
|
11
|
+
require 'solr/response'
|
12
|
+
require 'solr/query/request'
|
13
|
+
require 'solr/indexing/document'
|
14
|
+
require 'solr/indexing/request'
|
15
|
+
require 'solr/delete/request'
|
16
|
+
require 'solr/commit/request'
|
17
|
+
|
18
|
+
module Solr
|
19
|
+
class << self
|
20
|
+
CURRENT_CORE_CONFIG_VARIABLE_NAME = :solrb_current_core_config
|
21
|
+
|
22
|
+
attr_accessor :configuration
|
23
|
+
|
24
|
+
Solr.configuration = Configuration.new
|
25
|
+
|
26
|
+
def configure
|
27
|
+
yield configuration
|
28
|
+
end
|
29
|
+
|
30
|
+
def current_core_config
|
31
|
+
Thread.current[CURRENT_CORE_CONFIG_VARIABLE_NAME] || Solr.configuration.default_core_config
|
32
|
+
end
|
33
|
+
|
34
|
+
def commit
|
35
|
+
Solr::Commit::Request.new.run
|
36
|
+
end
|
37
|
+
|
38
|
+
def delete_by_id(id, commit: false)
|
39
|
+
Solr::Delete::Request.new(id: id).run(commit: commit)
|
40
|
+
end
|
41
|
+
|
42
|
+
def delete_by_query(query, commit: false)
|
43
|
+
Solr::Delete::Request.new(query: query).run(commit: commit)
|
44
|
+
end
|
45
|
+
|
46
|
+
def with_core(core)
|
47
|
+
core_config = Solr.configuration.core_config_by_name(core)
|
48
|
+
old_core_config = Thread.current[CURRENT_CORE_CONFIG_VARIABLE_NAME]
|
49
|
+
Thread.current[CURRENT_CORE_CONFIG_VARIABLE_NAME] = core_config
|
50
|
+
yield
|
51
|
+
ensure
|
52
|
+
Thread.current[CURRENT_CORE_CONFIG_VARIABLE_NAME] = old_core_config
|
53
|
+
end
|
54
|
+
|
55
|
+
def instrument(name:, data: {})
|
56
|
+
if defined? ActiveSupport::Notifications
|
57
|
+
ActiveSupport::Notifications.instrument(name, data) do
|
58
|
+
yield if block_given?
|
59
|
+
end
|
60
|
+
else
|
61
|
+
yield if block_given?
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/solrb.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'solr/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'solrb'
|
7
|
+
spec.version = Solr::VERSION
|
8
|
+
spec.authors = ['Adriano Luz', 'Valentin Vasilyev']
|
9
|
+
spec.email = ['adriano.luz@machinio.com', 'valentin@machinio.com']
|
10
|
+
|
11
|
+
spec.summary = 'Solr Ruby client with a nice object-oriented API'
|
12
|
+
spec.homepage = 'https://github.com/machinio/solrb'
|
13
|
+
spec.license = 'MIT'
|
14
|
+
|
15
|
+
# Specify which files should be added to the gem when it is released.
|
16
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
17
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
18
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
19
|
+
end
|
20
|
+
|
21
|
+
spec.bindir = 'exe'
|
22
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
|
+
spec.require_paths = ['lib']
|
24
|
+
|
25
|
+
spec.add_runtime_dependency 'addressable'
|
26
|
+
spec.add_runtime_dependency 'faraday'
|
27
|
+
|
28
|
+
spec.add_development_dependency 'bundler', '~> 1.16'
|
29
|
+
spec.add_development_dependency 'pry'
|
30
|
+
spec.add_development_dependency 'pry-byebug'
|
31
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
32
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
33
|
+
spec.add_development_dependency 'rspec_junit_formatter'
|
34
|
+
spec.add_development_dependency 'rubocop'
|
35
|
+
spec.add_development_dependency 'simplecov'
|
36
|
+
end
|