solrb 0.1.8 → 0.1.9
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 +4 -4
- data/.gitignore +1 -0
- data/Gemfile.lock +3 -3
- data/README.md +56 -3
- data/lib/solr/cloud/collections_state_manager.rb +48 -0
- data/lib/solr/cloud/configuration.rb +27 -0
- data/lib/solr/cloud/helper_methods.rb +37 -0
- data/lib/solr/cloud/zookeeper_connection.rb +64 -0
- data/lib/solr/commands.rb +24 -0
- data/lib/solr/commit/request.rb +2 -5
- data/lib/solr/configuration.rb +28 -3
- data/lib/solr/connection.rb +17 -10
- data/lib/solr/core_configuration/core_config_builder.rb +1 -1
- data/lib/solr/data_import/request.rb +27 -0
- data/lib/solr/delete/request.rb +6 -4
- data/lib/solr/errors/ambiguous_core_error.rb +7 -5
- data/lib/solr/errors/could_not_infer_implicit_core_name.rb +15 -0
- data/lib/solr/errors/no_active_solr_nodes_error.rb +6 -0
- data/lib/solr/errors/solr_connection_failed_error.rb +13 -0
- data/lib/solr/errors/solr_query_error.rb +4 -2
- data/lib/solr/errors/solr_url_not_defined_error.rb +24 -11
- data/lib/solr/errors/zookeeper_required.rb +19 -0
- data/lib/solr/indexing/request.rb +10 -6
- data/lib/solr/query/handler.rb +27 -0
- data/lib/solr/query/http_request_builder.rb +44 -0
- data/lib/solr/query/request/filter.rb +9 -7
- data/lib/solr/query/request.rb +6 -9
- data/lib/solr/request/default_node_selection_strategy.rb +19 -0
- data/lib/solr/request/first_shard_leader_node_selection_strategy.rb +32 -0
- data/lib/solr/request/http_request.rb +14 -0
- data/lib/solr/request/runner.rb +70 -0
- data/lib/solr/response/parser.rb +5 -1
- data/lib/solr/response.rb +0 -4
- data/lib/solr/support/url_helper.rb +23 -2
- data/lib/solr/testing.rb +5 -5
- data/lib/solr/version.rb +1 -1
- data/lib/solr.rb +17 -15
- metadata +19 -5
- data/.ruby-version +0 -1
- data/lib/solr/query/request/runner.rb +0 -44
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9ec22b8f3fb8d4af1362389b30173de437f3a66e0a56fd11189a66aa28c0a4f2
|
4
|
+
data.tar.gz: 36ae13f391bc00291bd4661c1ac910b6cdc2242f0c090a64d11c2385bca39274
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef11a6e93954a9b5245861b4753f722aa6f936f91fe2523ac4c31b685cf300cb37ae07247b24e70515914053d2e96330501bcb213c07aeef15cc6168c5540c71
|
7
|
+
data.tar.gz: 743961e7ae4540f4e67362554470bc3485ddab0ddfc557d4b0d27fd99b51c91b64c333e2a24a9a7839b9d87d7b514142e4302a701ba73f4a51be20a213f12c8c
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
solrb (0.1.
|
4
|
+
solrb (0.1.9)
|
5
5
|
addressable
|
6
6
|
faraday
|
7
7
|
|
@@ -15,7 +15,7 @@ GEM
|
|
15
15
|
coderay (1.1.2)
|
16
16
|
diff-lcs (1.3)
|
17
17
|
docile (1.3.1)
|
18
|
-
faraday (0.15.
|
18
|
+
faraday (0.15.3)
|
19
19
|
multipart-post (>= 1.2, < 3)
|
20
20
|
jaro_winkler (1.5.1)
|
21
21
|
json (2.1.0)
|
@@ -80,4 +80,4 @@ DEPENDENCIES
|
|
80
80
|
solrb!
|
81
81
|
|
82
82
|
BUNDLED WITH
|
83
|
-
1.16.
|
83
|
+
1.16.6
|
data/README.md
CHANGED
@@ -7,15 +7,15 @@ Solrb
|
|
7
7
|
|
8
8
|
Object-Oriented approach to Solr in Ruby.
|
9
9
|
|
10
|
-
Installation: `gem install solrb`
|
11
|
-
|
12
10
|
## Table of contents
|
13
11
|
|
14
|
-
|
12
|
+
* [Installation](#installation)
|
15
13
|
* [Configuration](#configuration)
|
16
14
|
* [Setting Solr URL via environment variable](#setting-solr-url-via-environment-variable)
|
17
15
|
* [Single core configuration](#single-core-configuration)
|
18
16
|
* [Multiple core configuration](#multiple-core-configuration)
|
17
|
+
* [Solr Cloud](#solr-cloud)
|
18
|
+
* [Basic Authentication](#basic-authentication)
|
19
19
|
* [Indexing](#indexing)
|
20
20
|
* [Querying](#querying)
|
21
21
|
* [Simple Query](#simple-query)
|
@@ -34,6 +34,20 @@ Installation: `gem install solrb`
|
|
34
34
|
* [Running specs](#running-specs)
|
35
35
|
|
36
36
|
|
37
|
+
# Installation
|
38
|
+
|
39
|
+
Add `solrb` to your Gemfile:
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
gem solrb
|
43
|
+
```
|
44
|
+
|
45
|
+
If you are going to use solrb with solr cloud:
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
gem zk # required for solrb solr-cloud integration
|
49
|
+
gem solrb
|
50
|
+
```
|
37
51
|
|
38
52
|
# Configuration
|
39
53
|
|
@@ -122,6 +136,45 @@ end
|
|
122
136
|
...
|
123
137
|
```
|
124
138
|
|
139
|
+
## Solr Cloud
|
140
|
+
|
141
|
+
To enable solr cloud mode you must define a zookeeper url on solr config block.
|
142
|
+
In solr cloud mode you don't need to provide a solr url (`config.url` or `ENV['SOLR_URL']`).
|
143
|
+
Solrb will watch the zookeeper state to receive up-to-date information about active solr nodes including the solr urls.
|
144
|
+
|
145
|
+
|
146
|
+
You can also specify the ACL credentials for Zookeeper. [More Information](https://lucene.apache.org/solr/guide/7_6/zookeeper-access-control.html#ZooKeeperAccessControl-AboutZooKeeperACLs)
|
147
|
+
|
148
|
+
|
149
|
+
```ruby
|
150
|
+
Solr.configure do |config|
|
151
|
+
config.zookeeper_urls = ['localhost:2181', 'localhost:2182', 'localhost:2183']
|
152
|
+
config.zookeeper_auth_user = 'zk_acl_user'
|
153
|
+
config.zookeeper_auth_password = 'zk_acl_password'
|
154
|
+
end
|
155
|
+
```
|
156
|
+
|
157
|
+
If you are using puma web server in clustered mode you must call `enable_solr_cloud!` on `on_worker_boot`
|
158
|
+
callback to make each puma worker connect with zookeeper.
|
159
|
+
|
160
|
+
|
161
|
+
```ruby
|
162
|
+
on_worker_boot do
|
163
|
+
Solr.enable_solr_cloud!
|
164
|
+
end
|
165
|
+
```
|
166
|
+
|
167
|
+
## Basic Authentication
|
168
|
+
|
169
|
+
Basic authentication is supported by solrb. You can enable it by providing `auth_user` and `auth_password`
|
170
|
+
on the config block.
|
171
|
+
|
172
|
+
```ruby
|
173
|
+
Solr.configure do |config|
|
174
|
+
config.auth_user = 'user'
|
175
|
+
config.auth_password = 'password'
|
176
|
+
end
|
177
|
+
```
|
125
178
|
|
126
179
|
# Indexing
|
127
180
|
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Solr
|
2
|
+
module Cloud
|
3
|
+
class CollectionsStateManager
|
4
|
+
attr_reader :zookeeper, :collections, :collections_state
|
5
|
+
|
6
|
+
def initialize(zookeeper:, collections:)
|
7
|
+
@zookeeper = zookeeper
|
8
|
+
@collections = collections
|
9
|
+
@collections_state = {}
|
10
|
+
watch_solr_collections_state
|
11
|
+
end
|
12
|
+
|
13
|
+
def shards_for(collection:)
|
14
|
+
collections_state.dig(collection.to_s, 'shards').keys
|
15
|
+
end
|
16
|
+
|
17
|
+
def active_nodes_for(collection:)
|
18
|
+
shards = collections_state.dig(collection.to_s, 'shards')
|
19
|
+
return unless shards
|
20
|
+
shards.flat_map do |_, shard|
|
21
|
+
shard['replicas'].select do |_, replica|
|
22
|
+
replica['state'] == 'active'
|
23
|
+
end.flat_map do |_, replica|
|
24
|
+
replica['base_url']
|
25
|
+
end
|
26
|
+
end.uniq
|
27
|
+
end
|
28
|
+
|
29
|
+
def leader_replica_node_for(collection:, shard:)
|
30
|
+
shards = collections_state.dig(collection.to_s, 'shards')
|
31
|
+
return unless shards
|
32
|
+
shard_replicas = shards[shard.to_s]
|
33
|
+
leader_replica = shard_replicas['replicas'].detect do |_, replica|
|
34
|
+
replica['state'] == 'active' && replica['leader'] == 'true'
|
35
|
+
end
|
36
|
+
leader_replica.last['base_url'] if leader_replica
|
37
|
+
end
|
38
|
+
|
39
|
+
def watch_solr_collections_state
|
40
|
+
collections.each do |collection_name|
|
41
|
+
zookeeper.watch_collection_state(collection_name) do |state|
|
42
|
+
@collections_state[collection_name.to_s] = state
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'solr/cloud/zookeeper_connection'
|
2
|
+
require 'solr/cloud/collections_state_manager'
|
3
|
+
|
4
|
+
module Solr
|
5
|
+
module Cloud
|
6
|
+
class Configuration
|
7
|
+
attr_accessor :zookeeper_url, :zookeeper_auth_user, :zookeeper_auth_password
|
8
|
+
|
9
|
+
attr_reader :collections_state_manager
|
10
|
+
|
11
|
+
def enable_solr_cloud!(collections)
|
12
|
+
@collections_state_manager = Solr::Cloud::CollectionsStateManager.new(zookeeper: build_zookeeper_connection,
|
13
|
+
collections: collections)
|
14
|
+
end
|
15
|
+
|
16
|
+
def cloud_enabled?
|
17
|
+
!@collections_state_manager.nil?
|
18
|
+
end
|
19
|
+
|
20
|
+
def build_zookeeper_connection
|
21
|
+
Solr::Cloud::ZookeeperConnection.new(zookeeper_url: zookeeper_url.is_a?(Array) ? zookeeper_url.join(',') : zookeeper_url,
|
22
|
+
zookeeper_auth_user: zookeeper_auth_user,
|
23
|
+
zookeeper_auth_password: zookeeper_auth_password)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'solr/cloud/configuration'
|
2
|
+
|
3
|
+
module Solr
|
4
|
+
module Cloud
|
5
|
+
module HelperMethods
|
6
|
+
def active_nodes_for(collection:)
|
7
|
+
collections_state_manager.active_nodes_for(collection: collection)
|
8
|
+
end
|
9
|
+
|
10
|
+
def leader_replica_node_for(collection:, shard:)
|
11
|
+
collections_state_manager.leader_replica_node_for(collection: collection, shard: shard)
|
12
|
+
end
|
13
|
+
|
14
|
+
def shards_for(collection:)
|
15
|
+
collections_state_manager.shards_for(collection: collection)
|
16
|
+
end
|
17
|
+
|
18
|
+
def cloud_enabled?
|
19
|
+
cloud_configuration.cloud_enabled?
|
20
|
+
end
|
21
|
+
|
22
|
+
def enable_solr_cloud!
|
23
|
+
cloud_configuration.enable_solr_cloud!(configuration.cores.keys)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def collections_state_manager
|
29
|
+
cloud_configuration.collections_state_manager
|
30
|
+
end
|
31
|
+
|
32
|
+
def cloud_configuration
|
33
|
+
configuration.cloud_configuration
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'solr/errors/zookeeper_required'
|
2
|
+
|
3
|
+
module Solr
|
4
|
+
module Cloud
|
5
|
+
class ZookeeperConnection
|
6
|
+
attr_reader :zookeeper_url, :zookeeper_auth_user, :zookeeper_auth_password
|
7
|
+
|
8
|
+
def initialize(zookeeper_url:, zookeeper_auth_user: nil, zookeeper_auth_password: nil)
|
9
|
+
@zookeeper_url = zookeeper_url
|
10
|
+
@zookeeper_auth_user = zookeeper_auth_user
|
11
|
+
@zookeeper_auth_password = zookeeper_auth_password
|
12
|
+
end
|
13
|
+
|
14
|
+
def watch_collection_state(collection_name, &block)
|
15
|
+
collection_state_znode = collection_state_znode_path(collection_name)
|
16
|
+
zookeeper_connection.register(collection_state_znode) do |event|
|
17
|
+
state = get_collection_state(collection_name, watch: true)
|
18
|
+
block.call(state)
|
19
|
+
end
|
20
|
+
state = get_collection_state(collection_name, watch: true)
|
21
|
+
block.call(state)
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_collection_state(collection_name, watch: true)
|
25
|
+
collection_state_znode = collection_state_znode_path(collection_name)
|
26
|
+
znode_data = zookeeper_connection.get(collection_state_znode, watch: watch)
|
27
|
+
return unless znode_data
|
28
|
+
JSON.parse(znode_data.first)[collection_name.to_s]
|
29
|
+
end
|
30
|
+
|
31
|
+
def collection_state_znode_path(collection_name)
|
32
|
+
"/collections/#{collection_name}/state.json"
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def zookeeper_connection
|
38
|
+
@zookeeper_connection ||= build_zookeeper_connection
|
39
|
+
end
|
40
|
+
|
41
|
+
def build_zookeeper_connection
|
42
|
+
raise 'You must provide a ZooKeeper URL to enable solr cloud mode' unless zookeeper_url
|
43
|
+
raise Solr::Errors::ZookeeperRequired unless require_zk
|
44
|
+
|
45
|
+
zk = ZK.new(zookeeper_url)
|
46
|
+
zk.add_auth(scheme: 'digest', cert: zookeeper_auth) if zookeeper_auth
|
47
|
+
zk
|
48
|
+
end
|
49
|
+
|
50
|
+
def zookeeper_auth
|
51
|
+
if zookeeper_auth_user && zookeeper_auth_password
|
52
|
+
"#{zookeeper_auth_user}:#{zookeeper_auth_password}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def require_zk
|
57
|
+
require 'zk'
|
58
|
+
true
|
59
|
+
rescue LoadError
|
60
|
+
false
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'solr/delete/request'
|
2
|
+
require 'solr/commit/request'
|
3
|
+
require 'solr/query/request'
|
4
|
+
require 'solr/data_import/request'
|
5
|
+
|
6
|
+
module Solr
|
7
|
+
module Commands
|
8
|
+
def commit
|
9
|
+
Solr::Commit::Request.new.run
|
10
|
+
end
|
11
|
+
|
12
|
+
def delete_by_id(id, commit: false)
|
13
|
+
Solr::Delete::Request.new(id: id).run(commit: commit)
|
14
|
+
end
|
15
|
+
|
16
|
+
def delete_by_query(query, commit: false)
|
17
|
+
Solr::Delete::Request.new(query: query).run(commit: commit)
|
18
|
+
end
|
19
|
+
|
20
|
+
def data_import(params)
|
21
|
+
Solr::DataImport::Request.new(params).run
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/solr/commit/request.rb
CHANGED
@@ -1,14 +1,11 @@
|
|
1
1
|
module Solr
|
2
2
|
module Commit
|
3
3
|
class Request
|
4
|
-
include Solr::Support::ConnectionHelper
|
5
4
|
PATH = '/update'.freeze
|
6
5
|
|
7
6
|
def run
|
8
|
-
|
9
|
-
|
10
|
-
raw_response = connection(PATH, commit: true).post
|
11
|
-
Solr::Response.from_raw_response(raw_response)
|
7
|
+
http_request = Solr::Request::HttpRequest.new(path: PATH, url_params: { commit: true }, method: :post)
|
8
|
+
Solr::Request::Runner.call(request: http_request)
|
12
9
|
end
|
13
10
|
end
|
14
11
|
end
|
data/lib/solr/configuration.rb
CHANGED
@@ -4,13 +4,19 @@ require 'solr/core_configuration/core_config'
|
|
4
4
|
require 'solr/core_configuration/core_config_builder'
|
5
5
|
require 'solr/errors/solr_url_not_defined_error'
|
6
6
|
require 'solr/errors/ambiguous_core_error'
|
7
|
+
require 'solr/errors/could_not_infer_implicit_core_name'
|
7
8
|
|
8
9
|
module Solr
|
9
10
|
class Configuration
|
11
|
+
extend Forwardable
|
12
|
+
|
13
|
+
delegate [:zookeeper_url, :zookeeper_url=, :zookeeper_auth_user=, :zookeeper_auth_password=] => :@cloud_configuration
|
14
|
+
|
10
15
|
SOLRB_USER_AGENT_HEADER = { user_agent: "Solrb v#{Solr::VERSION}" }.freeze
|
11
16
|
|
12
|
-
attr_accessor :cores, :test_connection
|
13
|
-
|
17
|
+
attr_accessor :cores, :test_connection, :auth_user, :auth_password
|
18
|
+
|
19
|
+
attr_reader :url, :faraday_options, :cloud_configuration
|
14
20
|
|
15
21
|
def initialize
|
16
22
|
@faraday_options = {
|
@@ -18,6 +24,7 @@ module Solr
|
|
18
24
|
headers: SOLRB_USER_AGENT_HEADER
|
19
25
|
}
|
20
26
|
@cores = {}
|
27
|
+
@cloud_configuration = Solr::Cloud::Configuration.new
|
21
28
|
end
|
22
29
|
|
23
30
|
def faraday_options=(options)
|
@@ -41,7 +48,7 @@ module Solr
|
|
41
48
|
def default_core_config
|
42
49
|
defined_default_core_config = cores.values.detect(&:default?)
|
43
50
|
return defined_default_core_config if defined_default_core_config
|
44
|
-
raise Errors::AmbiguousCoreError if cores.count > 1
|
51
|
+
raise Solr::Errors::AmbiguousCoreError if cores.count > 1
|
45
52
|
cores.values.first || build_env_url_core_config
|
46
53
|
end
|
47
54
|
|
@@ -60,7 +67,19 @@ module Solr
|
|
60
67
|
end
|
61
68
|
end
|
62
69
|
|
70
|
+
def core_name_from_solr_url_env
|
71
|
+
full_solr_core_uri = URI.parse(ENV['SOLR_URL'])
|
72
|
+
core_name = full_solr_core_uri.path.gsub('/solr', '').delete('/')
|
73
|
+
|
74
|
+
if !core_name || core_name == ''
|
75
|
+
raise Solr::Errors::CouldNotInferImplicitCoreName
|
76
|
+
end
|
77
|
+
|
78
|
+
core_name
|
79
|
+
end
|
80
|
+
|
63
81
|
def build_env_url_core_config(name: nil)
|
82
|
+
name ||= core_name_from_solr_url_env
|
64
83
|
Solr::CoreConfiguration::EnvUrlCoreConfig.new(name: name)
|
65
84
|
end
|
66
85
|
|
@@ -70,5 +89,11 @@ module Solr
|
|
70
89
|
raise ArgumentError, 'Only one default core can be specified'
|
71
90
|
end
|
72
91
|
end
|
92
|
+
|
93
|
+
def validate!
|
94
|
+
if !(url || @cloud_configuration.zookeeper_url || ENV['SOLR_URL'])
|
95
|
+
raise Solr::Errors::SolrUrlNotDefinedError
|
96
|
+
end
|
97
|
+
end
|
73
98
|
end
|
74
99
|
end
|
data/lib/solr/connection.rb
CHANGED
@@ -5,23 +5,20 @@ module Solr
|
|
5
5
|
|
6
6
|
def initialize(url, faraday_options: Solr.configuration.faraday_options)
|
7
7
|
# Allow mock the connection for testing
|
8
|
-
@raw_connection = Solr.configuration.test_connection ||
|
8
|
+
@raw_connection = Solr.configuration.test_connection || build_faraday_connection(url, faraday_options)
|
9
9
|
freeze
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
13
|
-
|
12
|
+
def self.call(url:, method:, body:)
|
13
|
+
raise "HTTP method not supported: #{method}" unless [:get, :post].include?(method.to_sym)
|
14
|
+
new(url).public_send(method, body)
|
14
15
|
end
|
15
16
|
|
16
|
-
def
|
17
|
-
Solr.instrument(name: INSTRUMENT_KEY)
|
18
|
-
@raw_connection.post do |req|
|
19
|
-
req.body = data
|
20
|
-
end
|
21
|
-
end
|
17
|
+
def get(_)
|
18
|
+
Solr.instrument(name: INSTRUMENT_KEY) { @raw_connection.get }
|
22
19
|
end
|
23
20
|
|
24
|
-
def
|
21
|
+
def post(data)
|
25
22
|
Solr.instrument(name: INSTRUMENT_KEY, data: data) do
|
26
23
|
@raw_connection.post do |req|
|
27
24
|
req.headers['Content-Type'] = 'application/json'.freeze
|
@@ -29,5 +26,15 @@ module Solr
|
|
29
26
|
end
|
30
27
|
end
|
31
28
|
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def build_faraday_connection(url, faraday_options)
|
33
|
+
connection = Faraday.new(url, faraday_options)
|
34
|
+
if Solr.configuration.auth_user && Solr.configuration.auth_password
|
35
|
+
connection.basic_auth(Solr.configuration.auth_user, Solr.configuration.auth_password)
|
36
|
+
end
|
37
|
+
connection
|
38
|
+
end
|
32
39
|
end
|
33
40
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'solr/request/first_shard_leader_node_selection_strategy'
|
2
|
+
|
3
|
+
module Solr
|
4
|
+
module DataImport
|
5
|
+
class Request
|
6
|
+
PATH = '/dataimport'.freeze
|
7
|
+
|
8
|
+
attr_reader :params
|
9
|
+
|
10
|
+
def initialize(params)
|
11
|
+
@params = params
|
12
|
+
end
|
13
|
+
|
14
|
+
# We want to make sure we send every dataimport request to the same node because this same class
|
15
|
+
# could be used to start a dataimport and to get dataimport progress data afterwards.
|
16
|
+
# To make it consistent we will send dataimport requests only to the first shard leader replica
|
17
|
+
def run
|
18
|
+
http_request = Solr::Request::HttpRequest.new(path: PATH, url_params: params, method: :get)
|
19
|
+
Solr::Request::Runner.call(request: http_request, node_selection_strategy: build_node_selection_strategy)
|
20
|
+
end
|
21
|
+
|
22
|
+
def build_node_selection_strategy
|
23
|
+
Solr::Request::FirstShardLeaderNodeSelectionStrategy
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/solr/delete/request.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
module Solr
|
2
2
|
module Delete
|
3
3
|
class Request
|
4
|
-
include Solr::Support::ConnectionHelper
|
5
4
|
using Solr::Support::HashExtensions
|
6
5
|
|
7
6
|
PATH = '/update'.freeze
|
@@ -14,13 +13,16 @@ module Solr
|
|
14
13
|
end
|
15
14
|
|
16
15
|
def run(commit: false)
|
17
|
-
|
18
|
-
|
19
|
-
Solr::Response.from_raw_response(raw_response)
|
16
|
+
http_request = build_http_request(commit)
|
17
|
+
Solr::Request::Runner.call(request: http_request)
|
20
18
|
end
|
21
19
|
|
22
20
|
private
|
23
21
|
|
22
|
+
def build_http_request(commit)
|
23
|
+
Solr::Request::HttpRequest.new(path: PATH, body: delete_command, url_params: { commit: commit }, method: :post)
|
24
|
+
end
|
25
|
+
|
24
26
|
def validate_delete_options!(options)
|
25
27
|
options = options.deep_symbolize_keys
|
26
28
|
id, query = options.values_at(:id, :query)
|
@@ -1,9 +1,11 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
|
1
|
+
module Solr
|
2
|
+
module Errors
|
3
|
+
class AmbiguousCoreError < StandardError
|
4
|
+
ERROR_MESSAGE = 'Multiple cores defined: default core can\'t be found'.freeze
|
4
5
|
|
5
|
-
|
6
|
-
|
6
|
+
def initialize
|
7
|
+
super(ERROR_MESSAGE)
|
8
|
+
end
|
7
9
|
end
|
8
10
|
end
|
9
11
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Solr
|
2
|
+
module Errors
|
3
|
+
class SolrConnectionFailedError < StandardError
|
4
|
+
def initialize(solr_urls)
|
5
|
+
message = <<~MESSAGE
|
6
|
+
Could not connection to any available solr instance:
|
7
|
+
#{solr_urls.join(', ')}
|
8
|
+
MESSAGE
|
9
|
+
super(message)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -1,16 +1,29 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
module Solr
|
2
|
+
module Errors
|
3
|
+
class SolrUrlNotDefinedError < StandardError
|
4
|
+
SOLR_URL_NOT_DEFINED_MESSAGE = '
|
5
|
+
Solrb gem requires you to set the URL of your Solr instance
|
6
|
+
either through SOLR_URL environmental variable or explicitly inside the configure block:
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
Solr.configure do |config|
|
9
|
+
config.url = "http://localhost:8983/solr/core"
|
10
|
+
end
|
11
|
+
|
12
|
+
If you are using Solr cloud you can specify the zookeeper ensemble urls inside the configure block
|
13
|
+
and solrb will automatically get the solr urls from ZK:
|
14
|
+
|
15
|
+
Solr.configure do |config|
|
16
|
+
config.zookeeper_url = ["localhost:2181","localhost:2182","localhost:2183"]
|
17
|
+
end
|
18
|
+
|
19
|
+
For more information please check the solrb README file.
|
11
20
|
|
12
|
-
|
13
|
-
|
21
|
+
'.freeze
|
22
|
+
|
23
|
+
def initialize
|
24
|
+
super(SOLR_URL_NOT_DEFINED_MESSAGE)
|
25
|
+
end
|
14
26
|
end
|
15
27
|
end
|
16
28
|
end
|
29
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Solr
|
2
|
+
module Errors
|
3
|
+
class ZookeeperRequired < StandardError
|
4
|
+
ZOOKEEPER_REQUIRED_MESSAGE = '
|
5
|
+
|
6
|
+
Solrb gem requires zookeeper for solr-cloud support.
|
7
|
+
Please add "zk" gem to your Gemfile and run bundle install:
|
8
|
+
|
9
|
+
gem "zk"
|
10
|
+
|
11
|
+
'.freeze
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
super(ZOOKEEPER_REQUIRED_MESSAGE)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
@@ -1,9 +1,8 @@
|
|
1
|
+
require 'solr/request/http_request'
|
2
|
+
|
1
3
|
module Solr
|
2
4
|
module Indexing
|
3
5
|
class Request
|
4
|
-
include Solr::Support::ConnectionHelper
|
5
|
-
|
6
|
-
# TODO: potentially make handlers configurable and have them handle the path
|
7
6
|
PATH = '/update'.freeze
|
8
7
|
|
9
8
|
attr_reader :documents
|
@@ -13,9 +12,14 @@ module Solr
|
|
13
12
|
end
|
14
13
|
|
15
14
|
def run(commit: false)
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
http_request = build_http_request(commit)
|
16
|
+
Solr::Request::Runner.call(request: http_request)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def build_http_request(commit)
|
22
|
+
Solr::Request::HttpRequest.new(path: PATH, body: documents, url_params: { commit: commit }, method: :post)
|
19
23
|
end
|
20
24
|
end
|
21
25
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'solr/query/response'
|
2
|
+
require 'solr/request/runner'
|
3
|
+
require 'solr/query/http_request_builder'
|
4
|
+
|
5
|
+
module Solr
|
6
|
+
module Query
|
7
|
+
class Handler
|
8
|
+
attr_reader :query, :page, :page_size
|
9
|
+
|
10
|
+
def self.call(opts)
|
11
|
+
new(opts).call
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(query:, page:, page_size:)
|
15
|
+
@query = query
|
16
|
+
@page = page
|
17
|
+
@page_size = page_size
|
18
|
+
end
|
19
|
+
|
20
|
+
def call
|
21
|
+
http_request = Solr::Query::HttpRequestBuilder.call(query: query, page: page, page_size: page_size)
|
22
|
+
solr_response = Solr::Request::Runner.call(request: http_request)
|
23
|
+
Solr::Query::Response::Parser.new(request: query, solr_response: solr_response.body).to_response
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'solr/request/http_request'
|
2
|
+
|
3
|
+
module Solr
|
4
|
+
module Query
|
5
|
+
class HttpRequestBuilder
|
6
|
+
PATH = '/select'.freeze
|
7
|
+
|
8
|
+
attr_reader :query, :page, :page_size
|
9
|
+
|
10
|
+
def self.call(opts)
|
11
|
+
new(opts).call
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(query:, page:, page_size:)
|
15
|
+
@query = query
|
16
|
+
@page = page
|
17
|
+
@page_size = page_size
|
18
|
+
end
|
19
|
+
|
20
|
+
def call
|
21
|
+
Solr::Request::HttpRequest.new(path: PATH,
|
22
|
+
body: build_body,
|
23
|
+
method: :post)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
# 🏋️
|
29
|
+
def build_body
|
30
|
+
@request_params ||= { params: solr_params.merge(wt: :json, rows: page_size.to_i, start: start) }
|
31
|
+
end
|
32
|
+
|
33
|
+
def start
|
34
|
+
start_page = page.to_i - 1
|
35
|
+
start_page = start_page < 1 ? 0 : start_page
|
36
|
+
start_page * page_size
|
37
|
+
end
|
38
|
+
|
39
|
+
def solr_params
|
40
|
+
query.to_h
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -38,21 +38,19 @@ module Solr
|
|
38
38
|
private
|
39
39
|
|
40
40
|
def solr_prefix
|
41
|
-
'-' if NOT_EQUAL_TYPE ==
|
41
|
+
'-' if NOT_EQUAL_TYPE == type
|
42
42
|
end
|
43
43
|
|
44
44
|
def to_interval_solr_value(range)
|
45
45
|
solr_min = to_primitive_solr_value(range.first)
|
46
|
-
solr_max =
|
47
|
-
'*'
|
48
|
-
else
|
49
|
-
to_primitive_solr_value(range.last)
|
50
|
-
end
|
46
|
+
solr_max = to_primitive_solr_value(range.last)
|
51
47
|
"[#{solr_min} TO #{solr_max}]"
|
52
48
|
end
|
53
49
|
|
54
50
|
def to_primitive_solr_value(value)
|
55
|
-
if
|
51
|
+
if date_infinity?(value) || numeric_infinity?(value)
|
52
|
+
'*'
|
53
|
+
elsif date_or_time?(value)
|
56
54
|
value.strftime('%Y-%m-%dT%H:%M:%SZ')
|
57
55
|
else
|
58
56
|
%("#{value.to_s.solr_escape}")
|
@@ -63,6 +61,10 @@ module Solr
|
|
63
61
|
value.is_a?(DateTime::Infinity)
|
64
62
|
end
|
65
63
|
|
64
|
+
def numeric_infinity?(value)
|
65
|
+
value.is_a?(Numeric) && value.infinite?
|
66
|
+
end
|
67
|
+
|
66
68
|
def date_or_time?(value)
|
67
69
|
return false unless value
|
68
70
|
value.is_a?(::Date) || value.is_a?(::Time)
|
data/lib/solr/query/request.rb
CHANGED
@@ -12,9 +12,7 @@ require 'solr/query/request/sorting/function'
|
|
12
12
|
require 'solr/query/request/field_with_boost'
|
13
13
|
require 'solr/query/request/or_filter'
|
14
14
|
require 'solr/query/request/and_filter'
|
15
|
-
require 'solr/query/
|
16
|
-
require 'solr/query/response'
|
17
|
-
require 'solr/errors/solr_query_error'
|
15
|
+
require 'solr/query/handler'
|
18
16
|
|
19
17
|
module Solr
|
20
18
|
module Query
|
@@ -30,13 +28,8 @@ module Solr
|
|
30
28
|
@filters = filters
|
31
29
|
end
|
32
30
|
|
33
|
-
# Runs this Solr::Request against Solr and
|
34
|
-
# returns [Solr::Response]
|
35
31
|
def run(page: 1, page_size: 10)
|
36
|
-
|
37
|
-
solr_response = Solr::Query::Request::Runner.run(page: page, page_size: page_size, solr_params: solr_params)
|
38
|
-
raise Errors::SolrQueryError, solr_response.error_message unless solr_response.ok?
|
39
|
-
Solr::Query::Response::Parser.new(request: self, solr_response: solr_response.body).to_response
|
32
|
+
Solr::Query::Handler.call(query: self, page: page, page_size: page_size)
|
40
33
|
end
|
41
34
|
|
42
35
|
def grouping
|
@@ -46,6 +39,10 @@ module Solr
|
|
46
39
|
def sorting
|
47
40
|
@sorting ||= Solr::Query::Request::Sorting.none
|
48
41
|
end
|
42
|
+
|
43
|
+
def to_h
|
44
|
+
Solr::Query::Request::EdismaxAdapter.new(self).to_h
|
45
|
+
end
|
49
46
|
end
|
50
47
|
end
|
51
48
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Solr
|
2
|
+
module Request
|
3
|
+
class DefaultNodeSelectionStrategy
|
4
|
+
attr_reader :collection_name
|
5
|
+
|
6
|
+
def self.call(collection_name)
|
7
|
+
new(collection_name).call
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(collection_name)
|
11
|
+
@collection_name = collection_name
|
12
|
+
end
|
13
|
+
|
14
|
+
def call
|
15
|
+
Solr.active_nodes_for(collection: collection_name).shuffle
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Solr
|
2
|
+
module Request
|
3
|
+
class FirstShardLeaderNodeSelectionStrategy
|
4
|
+
def self.call(collection_name)
|
5
|
+
new(collection_name).call
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize(collection_name)
|
9
|
+
@collection_name = collection_name
|
10
|
+
end
|
11
|
+
|
12
|
+
def call
|
13
|
+
return [solr_url] unless Solr.cloud_enabled?
|
14
|
+
|
15
|
+
([first_shard_leader_replica_node_for(collection: @collection_name)] + solr_cloud_active_nodes_urls.shuffle).flatten.uniq
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def first_shard_leader_replica_node_for(collection:)
|
21
|
+
shards = Solr.shards_for(collection: collection)
|
22
|
+
return unless shards
|
23
|
+
first_shard_name = shards.sort.first
|
24
|
+
Solr.leader_replica_node_for(collection: collection, shard: first_shard_name)
|
25
|
+
end
|
26
|
+
|
27
|
+
def solr_cloud_active_nodes_urls
|
28
|
+
Solr.active_nodes_for(collection: @collection_name)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Solr
|
2
|
+
module Request
|
3
|
+
class HttpRequest
|
4
|
+
attr_reader :path, :body, :url_params, :method
|
5
|
+
|
6
|
+
def initialize(path: '/', body: {}, url_params: {}, method: :get)
|
7
|
+
@path = path
|
8
|
+
@body = body
|
9
|
+
@url_params = url_params
|
10
|
+
@method = method
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'solr/request/default_node_selection_strategy'
|
2
|
+
require 'solr/errors/solr_query_error'
|
3
|
+
require 'solr/errors/solr_connection_failed_error'
|
4
|
+
require 'solr/errors/no_active_solr_nodes_error'
|
5
|
+
|
6
|
+
module Solr
|
7
|
+
module Request
|
8
|
+
# TODO: Add documentation about request running
|
9
|
+
class Runner
|
10
|
+
include Solr::Support::UrlHelper
|
11
|
+
|
12
|
+
attr_reader :request, :response_parser, :node_selection_strategy
|
13
|
+
|
14
|
+
def self.call(opts)
|
15
|
+
new(opts).call
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(request:,
|
19
|
+
node_selection_strategy: Solr::Request::DefaultNodeSelectionStrategy,
|
20
|
+
solr_connection: Solr::Connection)
|
21
|
+
@request = request
|
22
|
+
@response_parser = response_parser
|
23
|
+
@node_selection_strategy = node_selection_strategy
|
24
|
+
@solr_connection = solr_connection
|
25
|
+
end
|
26
|
+
|
27
|
+
def call
|
28
|
+
solr_urls.each do |node_url|
|
29
|
+
request_url = build_request_url(url: node_url,
|
30
|
+
path: request.path,
|
31
|
+
url_params: request.url_params)
|
32
|
+
begin
|
33
|
+
raw_response = @solr_connection.call(url: request_url.to_s, method: request.method, body: request.body)
|
34
|
+
solr_response = Solr::Response::Parser.call(raw_response)
|
35
|
+
raise Solr::Errors::SolrQueryError, solr_response.error_message unless solr_response.ok?
|
36
|
+
return solr_response
|
37
|
+
rescue Faraday::ConnectionFailed, Faraday::TimeoutError, Errno::EADDRNOTAVAIL => e
|
38
|
+
# Try next node
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
raise Solr::Errors::SolrConnectionFailedError.new(solr_urls)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def solr_urls
|
48
|
+
@solr_urls ||= begin
|
49
|
+
urls = Solr.cloud_enabled? ? solr_cloud_collection_urls : [Solr.current_core_config.url]
|
50
|
+
unless urls && urls.any?
|
51
|
+
raise Solr::Errors::NoActiveSolrNodesError
|
52
|
+
end
|
53
|
+
urls
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def solr_cloud_collection_urls
|
58
|
+
urls = node_selection_strategy.call(collection_name)
|
59
|
+
return unless urls
|
60
|
+
urls.map do |url|
|
61
|
+
File.join(url, collection_name.to_s)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def collection_name
|
66
|
+
Solr.current_core_config.name
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/solr/response/parser.rb
CHANGED
@@ -1,11 +1,15 @@
|
|
1
1
|
module Solr
|
2
2
|
class Response
|
3
3
|
class Parser
|
4
|
+
def self.call(raw_response)
|
5
|
+
new(raw_response).call
|
6
|
+
end
|
7
|
+
|
4
8
|
def initialize(raw_response)
|
5
9
|
@raw_response = raw_response
|
6
10
|
end
|
7
11
|
|
8
|
-
def
|
12
|
+
def call
|
9
13
|
# 404 is a special case, it didn't hit Solr (more likely than not)
|
10
14
|
return not_found_response if @raw_response.status == 404
|
11
15
|
parsed_body = JSON.parse(@raw_response.body).freeze
|
data/lib/solr/response.rb
CHANGED
@@ -7,10 +7,6 @@ module Solr
|
|
7
7
|
class Response
|
8
8
|
OK = 'OK'.freeze
|
9
9
|
|
10
|
-
def self.from_raw_response(response)
|
11
|
-
Solr::Response::Parser.new(response).parse
|
12
|
-
end
|
13
|
-
|
14
10
|
attr_reader :header, :http_status, :solr_error, :body
|
15
11
|
|
16
12
|
def initialize(header:, http_status: HttpStatus.ok, solr_error: SolrError.none, body: {})
|
@@ -1,12 +1,33 @@
|
|
1
1
|
module Solr
|
2
2
|
module Support
|
3
3
|
module UrlHelper
|
4
|
-
|
5
|
-
|
4
|
+
module_function
|
5
|
+
|
6
|
+
def solr_url(path, url_params: {})
|
7
|
+
full_url = File.join(core_url, path)
|
6
8
|
full_uri = Addressable::URI.parse(full_url)
|
7
9
|
full_uri.query_values = url_params if url_params.any?
|
8
10
|
full_uri
|
9
11
|
end
|
12
|
+
|
13
|
+
def build_request_url(url:,path:, url_params: {})
|
14
|
+
action_url = File.join(url, path).chomp('/')
|
15
|
+
full_uri = Addressable::URI.parse(action_url)
|
16
|
+
full_uri.query_values = url_params if url_params && url_params.any?
|
17
|
+
full_uri
|
18
|
+
end
|
19
|
+
|
20
|
+
def core_url
|
21
|
+
Solr.cloud_enabled? ? solr_cloud_url : current_core.uri
|
22
|
+
end
|
23
|
+
|
24
|
+
def solr_cloud_url
|
25
|
+
File.join(Solr.active_nodes_for(collection: current_core.name.to_s).first, current_core.name.to_s)
|
26
|
+
end
|
27
|
+
|
28
|
+
def current_core
|
29
|
+
Solr.current_core_config
|
30
|
+
end
|
10
31
|
end
|
11
32
|
end
|
12
33
|
end
|
data/lib/solr/testing.rb
CHANGED
@@ -6,14 +6,14 @@ module Solr
|
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
|
-
module Solr::
|
10
|
-
def
|
9
|
+
module Solr::Request::RunnerExtension
|
10
|
+
def call
|
11
11
|
response = super
|
12
|
-
Solr::Testing.last_solr_request_params =
|
12
|
+
Solr::Testing.last_solr_request_params = request.body ? request.body[:params] : nil
|
13
13
|
response
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
class Solr::
|
18
|
-
prepend Solr::
|
17
|
+
class Solr::Request::Runner
|
18
|
+
prepend Solr::Request::RunnerExtension
|
19
19
|
end
|
data/lib/solr/version.rb
CHANGED
data/lib/solr.rb
CHANGED
@@ -9,14 +9,19 @@ require 'solr/document'
|
|
9
9
|
require 'solr/document_collection'
|
10
10
|
require 'solr/grouped_document_collection'
|
11
11
|
require 'solr/response'
|
12
|
+
require 'solr/request/runner'
|
12
13
|
require 'solr/query/request'
|
13
14
|
require 'solr/indexing/document'
|
14
15
|
require 'solr/indexing/request'
|
15
|
-
|
16
|
-
require 'solr/
|
16
|
+
|
17
|
+
require 'solr/cloud/helper_methods'
|
18
|
+
require 'solr/commands'
|
17
19
|
|
18
20
|
module Solr
|
19
21
|
class << self
|
22
|
+
include Solr::Commands
|
23
|
+
include Solr::Cloud::HelperMethods
|
24
|
+
|
20
25
|
CURRENT_CORE_CONFIG_VARIABLE_NAME = :solrb_current_core_config
|
21
26
|
|
22
27
|
attr_accessor :configuration
|
@@ -25,24 +30,15 @@ module Solr
|
|
25
30
|
|
26
31
|
def configure
|
27
32
|
yield configuration
|
33
|
+
configuration.validate!
|
34
|
+
enable_solr_cloud! unless configuration.zookeeper_url.nil?
|
35
|
+
configuration
|
28
36
|
end
|
29
37
|
|
30
38
|
def current_core_config
|
31
39
|
Thread.current[CURRENT_CORE_CONFIG_VARIABLE_NAME] || Solr.configuration.default_core_config
|
32
40
|
end
|
33
41
|
|
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
42
|
def with_core(core)
|
47
43
|
core_config = Solr.configuration.core_config_by_name(core)
|
48
44
|
old_core_config = Thread.current[CURRENT_CORE_CONFIG_VARIABLE_NAME]
|
@@ -52,9 +48,15 @@ module Solr
|
|
52
48
|
Thread.current[CURRENT_CORE_CONFIG_VARIABLE_NAME] = old_core_config
|
53
49
|
end
|
54
50
|
|
51
|
+
def solr_url(path = '')
|
52
|
+
Solr::Support::UrlHelper.solr_url(path)
|
53
|
+
end
|
54
|
+
|
55
55
|
def instrument(name:, data: {})
|
56
56
|
if defined? ActiveSupport::Notifications
|
57
|
-
|
57
|
+
# Create a copy of data to avoid modifications on the original object by rails
|
58
|
+
# https://github.com/rails/rails/blob/master/activesupport/lib/active_support/notifications.rb#L66-L70
|
59
|
+
ActiveSupport::Notifications.instrument(name, data.dup) do
|
58
60
|
yield if block_given?
|
59
61
|
end
|
60
62
|
else
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: solrb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adriano Luz
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2019-02-07 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: addressable
|
@@ -166,7 +166,6 @@ files:
|
|
166
166
|
- ".gitignore"
|
167
167
|
- ".rspec"
|
168
168
|
- ".rubocop.yml"
|
169
|
-
- ".ruby-version"
|
170
169
|
- Gemfile
|
171
170
|
- Gemfile.lock
|
172
171
|
- LICENSE.txt
|
@@ -175,6 +174,11 @@ files:
|
|
175
174
|
- bin/console
|
176
175
|
- bin/setup
|
177
176
|
- lib/solr.rb
|
177
|
+
- lib/solr/cloud/collections_state_manager.rb
|
178
|
+
- lib/solr/cloud/configuration.rb
|
179
|
+
- lib/solr/cloud/helper_methods.rb
|
180
|
+
- lib/solr/cloud/zookeeper_connection.rb
|
181
|
+
- lib/solr/commands.rb
|
178
182
|
- lib/solr/commit/request.rb
|
179
183
|
- lib/solr/configuration.rb
|
180
184
|
- lib/solr/connection.rb
|
@@ -182,15 +186,22 @@ files:
|
|
182
186
|
- lib/solr/core_configuration/core_config_builder.rb
|
183
187
|
- lib/solr/core_configuration/dynamic_field.rb
|
184
188
|
- lib/solr/core_configuration/field.rb
|
189
|
+
- lib/solr/data_import/request.rb
|
185
190
|
- lib/solr/delete/request.rb
|
186
191
|
- lib/solr/document.rb
|
187
192
|
- lib/solr/document_collection.rb
|
188
193
|
- lib/solr/errors/ambiguous_core_error.rb
|
194
|
+
- lib/solr/errors/could_not_infer_implicit_core_name.rb
|
195
|
+
- lib/solr/errors/no_active_solr_nodes_error.rb
|
196
|
+
- lib/solr/errors/solr_connection_failed_error.rb
|
189
197
|
- lib/solr/errors/solr_query_error.rb
|
190
198
|
- lib/solr/errors/solr_url_not_defined_error.rb
|
199
|
+
- lib/solr/errors/zookeeper_required.rb
|
191
200
|
- lib/solr/grouped_document_collection.rb
|
192
201
|
- lib/solr/indexing/document.rb
|
193
202
|
- lib/solr/indexing/request.rb
|
203
|
+
- lib/solr/query/handler.rb
|
204
|
+
- lib/solr/query/http_request_builder.rb
|
194
205
|
- lib/solr/query/request.rb
|
195
206
|
- lib/solr/query/request/and_filter.rb
|
196
207
|
- lib/solr/query/request/boost_magnitude.rb
|
@@ -214,7 +225,6 @@ files:
|
|
214
225
|
- lib/solr/query/request/geo_filter.rb
|
215
226
|
- lib/solr/query/request/grouping.rb
|
216
227
|
- lib/solr/query/request/or_filter.rb
|
217
|
-
- lib/solr/query/request/runner.rb
|
218
228
|
- lib/solr/query/request/sorting.rb
|
219
229
|
- lib/solr/query/request/sorting/field.rb
|
220
230
|
- lib/solr/query/request/sorting/function.rb
|
@@ -224,6 +234,10 @@ files:
|
|
224
234
|
- lib/solr/query/response/field_facets.rb
|
225
235
|
- lib/solr/query/response/parser.rb
|
226
236
|
- lib/solr/query/response/spellcheck.rb
|
237
|
+
- lib/solr/request/default_node_selection_strategy.rb
|
238
|
+
- lib/solr/request/first_shard_leader_node_selection_strategy.rb
|
239
|
+
- lib/solr/request/http_request.rb
|
240
|
+
- lib/solr/request/runner.rb
|
227
241
|
- lib/solr/response.rb
|
228
242
|
- lib/solr/response/header.rb
|
229
243
|
- lib/solr/response/http_status.rb
|
@@ -258,7 +272,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
258
272
|
version: '0'
|
259
273
|
requirements: []
|
260
274
|
rubyforge_project:
|
261
|
-
rubygems_version: 2.7.
|
275
|
+
rubygems_version: 2.7.8
|
262
276
|
signing_key:
|
263
277
|
specification_version: 4
|
264
278
|
summary: Solr Ruby client with a nice object-oriented API
|
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
2.5.3
|
@@ -1,44 +0,0 @@
|
|
1
|
-
module Solr
|
2
|
-
module Query
|
3
|
-
class Request
|
4
|
-
class Runner
|
5
|
-
PATH = '/select'.freeze
|
6
|
-
|
7
|
-
include Solr::Support::ConnectionHelper
|
8
|
-
|
9
|
-
attr_reader :page, :page_size, :solr_params
|
10
|
-
|
11
|
-
class << self
|
12
|
-
def run(opts)
|
13
|
-
new(opts).run
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def initialize(page:, page_size:, solr_params: {})
|
18
|
-
@page = page
|
19
|
-
@page_size = page_size
|
20
|
-
@solr_params = solr_params
|
21
|
-
end
|
22
|
-
|
23
|
-
def run
|
24
|
-
raw_response = connection(PATH).post_as_json(request_params)
|
25
|
-
response = Solr::Response.from_raw_response(raw_response)
|
26
|
-
response
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def start
|
32
|
-
start_page = @page.to_i - 1
|
33
|
-
start_page = start_page < 1 ? 0 : start_page
|
34
|
-
start_page * page_size
|
35
|
-
end
|
36
|
-
|
37
|
-
def request_params
|
38
|
-
# https://lucene.apache.org/solr/guide/7_1/json-request-api.html#passing-parameters-via-json
|
39
|
-
@request_params ||= { params: solr_params.merge(wt: :json, rows: page_size.to_i, start: start) }
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|