solrb 0.1.0
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.
- 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
|