solrb 0.1.8 → 0.1.9
Sign up to get free protection for your applications and to get access to all the features.
- 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
|