solrb 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.circleci/config.yml +69 -0
- data/.circleci/run-with-local-config.sh +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.rubocop.yml +30 -0
- data/.ruby-version +1 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +83 -0
- data/LICENSE.txt +21 -0
- data/README.md +259 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/solr/commit/request.rb +15 -0
- data/lib/solr/configuration.rb +66 -0
- data/lib/solr/connection.rb +33 -0
- data/lib/solr/core_configuration/core_config.rb +44 -0
- data/lib/solr/core_configuration/core_config_builder.rb +51 -0
- data/lib/solr/core_configuration/dynamic_field.rb +17 -0
- data/lib/solr/core_configuration/field.rb +20 -0
- data/lib/solr/delete/request.rb +34 -0
- data/lib/solr/document.rb +26 -0
- data/lib/solr/document_collection.rb +55 -0
- data/lib/solr/errors/ambiguous_core_error.rb +9 -0
- data/lib/solr/errors/solr_query_error.rb +4 -0
- data/lib/solr/errors/solr_url_not_defined_error.rb +16 -0
- data/lib/solr/grouped_document_collection.rb +38 -0
- data/lib/solr/indexing/document.rb +25 -0
- data/lib/solr/indexing/request.rb +22 -0
- data/lib/solr/query/request/boost_magnitude.rb +9 -0
- data/lib/solr/query/request/boosting/dictionary_boost_function.rb +36 -0
- data/lib/solr/query/request/boosting/exists_boost_function.rb +27 -0
- data/lib/solr/query/request/boosting/field_value_less_than_boost_function.rb +25 -0
- data/lib/solr/query/request/boosting/field_value_match_boost_function.rb +24 -0
- data/lib/solr/query/request/boosting/geodist_function.rb +37 -0
- data/lib/solr/query/request/boosting/ln_function_boost.rb +28 -0
- data/lib/solr/query/request/boosting/numeric_field_value_match_boost_function.rb +13 -0
- data/lib/solr/query/request/boosting/phrase_proximity_boost.rb +27 -0
- data/lib/solr/query/request/boosting/ranking_field_boost_function.rb +20 -0
- data/lib/solr/query/request/boosting/recent_field_value_boost_function.rb +26 -0
- data/lib/solr/query/request/boosting/scale_function_boost.rb +28 -0
- data/lib/solr/query/request/boosting/textual_field_value_match_boost_function.rb +13 -0
- data/lib/solr/query/request/boosting.rb +46 -0
- data/lib/solr/query/request/edismax_adapter.rb +163 -0
- data/lib/solr/query/request/facet.rb +68 -0
- data/lib/solr/query/request/field_with_boost.rb +18 -0
- data/lib/solr/query/request/filter.rb +73 -0
- data/lib/solr/query/request/geo_filter.rb +26 -0
- data/lib/solr/query/request/grouping.rb +37 -0
- data/lib/solr/query/request/or_filter.rb +16 -0
- data/lib/solr/query/request/runner.rb +46 -0
- data/lib/solr/query/request/sorting/field.rb +16 -0
- data/lib/solr/query/request/sorting.rb +34 -0
- data/lib/solr/query/request/spellcheck.rb +74 -0
- data/lib/solr/query/request.rb +49 -0
- data/lib/solr/query/response/facet_value.rb +16 -0
- data/lib/solr/query/response/field_facets.rb +25 -0
- data/lib/solr/query/response/parser.rb +154 -0
- data/lib/solr/query/response/spellcheck.rb +42 -0
- data/lib/solr/query/response.rb +48 -0
- data/lib/solr/response/header.rb +25 -0
- data/lib/solr/response/http_status.rb +27 -0
- data/lib/solr/response/parser.rb +47 -0
- data/lib/solr/response/solr_error.rb +31 -0
- data/lib/solr/response.rb +52 -0
- data/lib/solr/support/connection_helper.rb +12 -0
- data/lib/solr/support/hash_extensions.rb +29 -0
- data/lib/solr/support/schema_helper.rb +11 -0
- data/lib/solr/support/string_extensions.rb +12 -0
- data/lib/solr/support/url_helper.rb +12 -0
- data/lib/solr/support.rb +5 -0
- data/lib/solr/testing.rb +19 -0
- data/lib/solr/version.rb +3 -0
- data/lib/solr.rb +65 -0
- data/solrb.gemspec +36 -0
- metadata +261 -0
@@ -0,0 +1,44 @@
|
|
1
|
+
module Solr
|
2
|
+
module CoreConfiguration
|
3
|
+
class CoreConfig
|
4
|
+
attr_reader :name, :fields
|
5
|
+
|
6
|
+
def initialize(name:, fields:, default:)
|
7
|
+
@name = name
|
8
|
+
@fields = fields
|
9
|
+
@default = default
|
10
|
+
end
|
11
|
+
|
12
|
+
def field_by_name(field_name)
|
13
|
+
fields[field_name.to_sym]
|
14
|
+
end
|
15
|
+
|
16
|
+
def default?
|
17
|
+
@default
|
18
|
+
end
|
19
|
+
|
20
|
+
def url
|
21
|
+
@url ||= File.join(Solr.configuration.url || ENV['SOLR_URL'], name.to_s).chomp('/')
|
22
|
+
end
|
23
|
+
|
24
|
+
def uri
|
25
|
+
@uri ||= Addressable::URI.parse(url)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class EnvUrlCoreConfig < CoreConfig
|
30
|
+
attr_reader :name, :fields
|
31
|
+
|
32
|
+
def initialize(name: nil, fields: {})
|
33
|
+
@name = name
|
34
|
+
@fields = fields
|
35
|
+
@default = false
|
36
|
+
end
|
37
|
+
|
38
|
+
def url
|
39
|
+
raise ArgumentError, "Solr's URL can't be nil" if ENV['SOLR_URL'].nil?
|
40
|
+
ENV['SOLR_URL']
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Solr
|
2
|
+
module CoreConfiguration
|
3
|
+
class CoreConfigBuilder
|
4
|
+
attr_reader :name, :dynamic_fields, :fields_params, :default
|
5
|
+
|
6
|
+
def initialize(name: nil, default:)
|
7
|
+
@name = name
|
8
|
+
@default = default
|
9
|
+
@dynamic_fields = {}
|
10
|
+
@fields_params = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def dynamic_field(field_name, solr_name:)
|
14
|
+
dynamic_fields[field_name] = Solr::CoreConfiguration::DynamicField.new(name: field_name, solr_name: solr_name)
|
15
|
+
end
|
16
|
+
|
17
|
+
def field(field_name, params = {})
|
18
|
+
fields_params[field_name] = params
|
19
|
+
end
|
20
|
+
|
21
|
+
def build
|
22
|
+
Solr::CoreConfiguration::CoreConfig.new(
|
23
|
+
name: name,
|
24
|
+
fields: build_fields,
|
25
|
+
default: default
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_dynamic_field(field_name, dynamic_field_name)
|
30
|
+
dynamic_field = dynamic_fields[dynamic_field_name]
|
31
|
+
|
32
|
+
if dynamic_field_name && !dynamic_field
|
33
|
+
raise "Field '#{field_name}' is mapped to an undefined dynamic field '#{dynamic_field_name}'"
|
34
|
+
end
|
35
|
+
|
36
|
+
dynamic_field
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def build_fields
|
42
|
+
fields_params.each_with_object({}) do |(name, params), fields|
|
43
|
+
fields[name] =
|
44
|
+
Solr::CoreConfiguration::Field.new(name: name,
|
45
|
+
solr_name: params[:solr_name],
|
46
|
+
dynamic_field: get_dynamic_field(name, params[:dynamic_field]))
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Solr
|
2
|
+
module CoreConfiguration
|
3
|
+
class DynamicField
|
4
|
+
attr_reader :name, :solr_name
|
5
|
+
|
6
|
+
def initialize(name:, solr_name:)
|
7
|
+
@name = name
|
8
|
+
@solr_name = solr_name
|
9
|
+
freeze
|
10
|
+
end
|
11
|
+
|
12
|
+
def build(name)
|
13
|
+
solr_name.gsub('*', name.to_s)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Solr
|
2
|
+
module CoreConfiguration
|
3
|
+
class Field
|
4
|
+
attr_reader :name, :dynamic_field, :solr_name
|
5
|
+
|
6
|
+
def initialize(name:, dynamic_field: nil, solr_name: nil)
|
7
|
+
@name = name
|
8
|
+
@dynamic_field = dynamic_field
|
9
|
+
@solr_name = solr_name
|
10
|
+
freeze
|
11
|
+
end
|
12
|
+
|
13
|
+
def solr_field_name
|
14
|
+
return solr_name.to_s if solr_name
|
15
|
+
return dynamic_field.build(name) if dynamic_field
|
16
|
+
name.to_s
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Solr
|
2
|
+
module Delete
|
3
|
+
class Request
|
4
|
+
include Solr::Support::ConnectionHelper
|
5
|
+
using Solr::Support::HashExtensions
|
6
|
+
|
7
|
+
PATH = '/update'.freeze
|
8
|
+
|
9
|
+
attr_reader :delete_command
|
10
|
+
|
11
|
+
def initialize(options = {})
|
12
|
+
options = validate_delete_options!(options)
|
13
|
+
@delete_command = { delete: options }
|
14
|
+
end
|
15
|
+
|
16
|
+
def run(commit: false)
|
17
|
+
# need to think how to move out commit data from the connection, it doesn't belong there
|
18
|
+
raw_response = connection(PATH, commit: commit).post_as_json(delete_command)
|
19
|
+
Solr::Response.from_raw_response(raw_response)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def validate_delete_options!(options)
|
25
|
+
options = options.deep_symbolize_keys
|
26
|
+
id, query = options.values_at(:id, :query)
|
27
|
+
error_message = 'options must contain either id or query, but not both'
|
28
|
+
raise ArgumentError, error_message if id.nil? && query.nil?
|
29
|
+
raise ArgumentError, error_message if id && query
|
30
|
+
options
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Solr
|
2
|
+
class Document
|
3
|
+
class GroupInformation
|
4
|
+
attr_reader :key, :value
|
5
|
+
def initialize(key:, value:)
|
6
|
+
@key = key
|
7
|
+
@value = value
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.empty
|
11
|
+
new(key: nil, value: nil)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :id, :model_name, :score, :debug_info, :group
|
16
|
+
|
17
|
+
# TODO: model_name is specific for machinio
|
18
|
+
def initialize(id:, model_name: nil, score: nil, debug_info: nil, group: GroupInformation.empty)
|
19
|
+
@id = id
|
20
|
+
@model_name = model_name
|
21
|
+
@score = score
|
22
|
+
@debug_info = debug_info
|
23
|
+
@group = group
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Solr
|
2
|
+
class DocumentCollection
|
3
|
+
include Enumerable
|
4
|
+
attr_reader :documents, :total_count
|
5
|
+
|
6
|
+
def self.from_ids(ids, model_name:)
|
7
|
+
documents = ids.map { |id| Solr::Document.new(id: id, model_name: model_name) }
|
8
|
+
new(documents: documents, total_count: documents.count)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.empty
|
12
|
+
new(documents: [], total_count: 0)
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(documents:, total_count:)
|
16
|
+
@documents = documents
|
17
|
+
@total_count = total_count
|
18
|
+
end
|
19
|
+
|
20
|
+
def each(&b)
|
21
|
+
return enum_for(:each) unless block_given?
|
22
|
+
documents.each(&b)
|
23
|
+
end
|
24
|
+
|
25
|
+
def first(n)
|
26
|
+
new_documents = documents.first(n)
|
27
|
+
self.class.new(documents: new_documents, total_count: new_documents.count)
|
28
|
+
end
|
29
|
+
|
30
|
+
def slice(range)
|
31
|
+
new_documents = documents[range]
|
32
|
+
if new_documents
|
33
|
+
self.class.new(documents: new_documents, total_count: new_documents.count)
|
34
|
+
else
|
35
|
+
self.class.empty
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def +(other)
|
40
|
+
self.class.new(
|
41
|
+
documents: documents + other.documents,
|
42
|
+
total_count: total_count + other.total_count
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
def unshift(document)
|
47
|
+
@documents.unshift(document)
|
48
|
+
@total_count += 1
|
49
|
+
end
|
50
|
+
|
51
|
+
def find(id)
|
52
|
+
documents.find { |doc| doc.id == id }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Errors
|
2
|
+
class SolrUrlNotDefinedError < StandardError
|
3
|
+
SOLR_URL_NOT_DEFINED_MESSAGE = '
|
4
|
+
Solrb gem requires you to set the URL of your Solr instance
|
5
|
+
either through SOLR_URL environmental variable or explicitly inside the configure block:
|
6
|
+
|
7
|
+
Solr.configure do |config|
|
8
|
+
config.url = "http://localhost:8983/solr/core"
|
9
|
+
end
|
10
|
+
'.freeze
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
super(SOLR_URL_NOT_DEFINED_MESSAGE)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Solr
|
2
|
+
class GroupedDocumentCollection < DocumentCollection
|
3
|
+
attr_reader :group_counts
|
4
|
+
|
5
|
+
def self.empty
|
6
|
+
new(documents: [], total_count: 0, group_counts: {})
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(documents:, total_count:, group_counts:)
|
10
|
+
super(documents: documents, total_count: total_count)
|
11
|
+
@group_counts = group_counts
|
12
|
+
end
|
13
|
+
|
14
|
+
def first(n)
|
15
|
+
new_documents = documents.first(n)
|
16
|
+
self.class.new(documents: new_documents,
|
17
|
+
total_count: new_documents.count, group_counts: group_counts)
|
18
|
+
end
|
19
|
+
|
20
|
+
def slice(range)
|
21
|
+
new_documents = documents[range]
|
22
|
+
if new_documents
|
23
|
+
self.class.new(documents: new_documents, total_count: new_documents.count, group_counts: group_counts)
|
24
|
+
else
|
25
|
+
self.class.empty
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def +(other)
|
30
|
+
other_group_counts = other.is_a?(Solr::GroupedDocumentCollection) ? other.group_counts : {}
|
31
|
+
self.class.new(
|
32
|
+
documents: documents + other.documents,
|
33
|
+
total_count: total_count + other.total_count,
|
34
|
+
group_counts: group_counts.merge(other_group_counts)
|
35
|
+
)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Solr
|
2
|
+
module Indexing
|
3
|
+
class Document
|
4
|
+
include Solr::Support::SchemaHelper
|
5
|
+
attr_reader :fields
|
6
|
+
|
7
|
+
def initialize(fields = {})
|
8
|
+
@fields = fields
|
9
|
+
end
|
10
|
+
|
11
|
+
def add_field(name, value)
|
12
|
+
@fields[name] = value
|
13
|
+
end
|
14
|
+
|
15
|
+
# TODO: refactor & optimize this
|
16
|
+
def to_json(_json_context)
|
17
|
+
solr_fields = fields.map do |k, v|
|
18
|
+
solr_field_name = solarize_field(k)
|
19
|
+
[solr_field_name, v]
|
20
|
+
end.to_h
|
21
|
+
JSON.generate(solr_fields)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Solr
|
2
|
+
module Indexing
|
3
|
+
class Request
|
4
|
+
include Solr::Support::ConnectionHelper
|
5
|
+
|
6
|
+
# TODO: potentially make handlers configurable and have them handle the path
|
7
|
+
PATH = '/update'.freeze
|
8
|
+
|
9
|
+
attr_reader :documents
|
10
|
+
|
11
|
+
def initialize(documents = [])
|
12
|
+
@documents = documents
|
13
|
+
end
|
14
|
+
|
15
|
+
def run(commit: false)
|
16
|
+
# need to think how to move out commit data from the connection, it doesn't belong there
|
17
|
+
raw_response = connection(PATH, commit: commit).post_as_json(documents)
|
18
|
+
Solr::Response.from_raw_response(raw_response)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Solr
|
2
|
+
module Query
|
3
|
+
class Request
|
4
|
+
class Boosting
|
5
|
+
class DictionaryBoostFunction
|
6
|
+
include Solr::Support::SchemaHelper
|
7
|
+
using Solr::Support::StringExtensions
|
8
|
+
attr_reader :field, :dictionary
|
9
|
+
|
10
|
+
def initialize(field:, dictionary:)
|
11
|
+
raise 'dictionary must be a non-empty Hash' if Hash(dictionary).empty?
|
12
|
+
@field = field
|
13
|
+
@dictionary = dictionary
|
14
|
+
end
|
15
|
+
|
16
|
+
# example: given a hash (dictionary)
|
17
|
+
# {3025 => 2.0, 3024 => 1.5, 3023 => 1.2}
|
18
|
+
# and a field of category_id
|
19
|
+
# the resulting boosting function will be:
|
20
|
+
# if(eq(category_id_it, 3025), 2.0, if(eq(category_id_it, 3024), 1.5, if(eq(category_id_it, 3023), 1.2, 1)))
|
21
|
+
# note that I added spaces for readability, real Solr query functions must always be w/out spaces
|
22
|
+
def to_solr_s
|
23
|
+
sf = solarize_field(field)
|
24
|
+
dictionary.to_a.reverse.reduce(1) do |acc, (field_value, boost)|
|
25
|
+
if field_value.is_a?(String) || field_value.is_a?(Symbol)
|
26
|
+
"if(termfreq(#{sf},\"#{field_value.to_s.solr_escape}\"),#{boost},#{acc})"
|
27
|
+
else
|
28
|
+
"if(eq(#{sf},#{field_value}),#{boost},#{acc})"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Solr
|
2
|
+
module Query
|
3
|
+
class Request
|
4
|
+
class Boosting
|
5
|
+
class ExistsBoostFunction
|
6
|
+
include Solr::Support::SchemaHelper
|
7
|
+
|
8
|
+
attr_reader :field, :boost_magnitude
|
9
|
+
|
10
|
+
def initialize(field:, boost_magnitude:)
|
11
|
+
@field = field
|
12
|
+
@boost_magnitude = boost_magnitude
|
13
|
+
freeze
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_solr_s
|
17
|
+
"if(exists(#{solr_field}),#{boost_magnitude},1)"
|
18
|
+
end
|
19
|
+
|
20
|
+
def solr_field
|
21
|
+
solarize_field(field)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Solr
|
2
|
+
module Query
|
3
|
+
class Request
|
4
|
+
class Boosting
|
5
|
+
class FieldValueLessThanBoostFunction
|
6
|
+
include Solr::Support::SchemaHelper
|
7
|
+
|
8
|
+
attr_reader :field, :max, :boost_magnitude
|
9
|
+
|
10
|
+
def initialize(field:, max:, boost_magnitude:)
|
11
|
+
@field = field
|
12
|
+
@max = max
|
13
|
+
@boost_magnitude = boost_magnitude
|
14
|
+
freeze
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_solr_s
|
18
|
+
solr_field = solarize_field(field)
|
19
|
+
"if(sub(#{max},max(#{solr_field},#{max})),1,#{boost_magnitude})"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Solr
|
2
|
+
module Query
|
3
|
+
class Request
|
4
|
+
class Boosting
|
5
|
+
class FieldValueMatchBoostFunction
|
6
|
+
include Solr::Support::SchemaHelper
|
7
|
+
|
8
|
+
attr_reader :field, :value, :boost_magnitude
|
9
|
+
|
10
|
+
def initialize(field:, value:, boost_magnitude:)
|
11
|
+
@field = field
|
12
|
+
@value = value
|
13
|
+
@boost_magnitude = boost_magnitude
|
14
|
+
freeze
|
15
|
+
end
|
16
|
+
|
17
|
+
def solr_field
|
18
|
+
solarize_field(field)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# Spatial search:
|
2
|
+
# https://cwiki.apache.org/confluence/display/solr/Spatial+Search
|
3
|
+
|
4
|
+
module Solr
|
5
|
+
module Query
|
6
|
+
class Request
|
7
|
+
class Boosting
|
8
|
+
class GeodistFunction
|
9
|
+
include Solr::Support::SchemaHelper
|
10
|
+
|
11
|
+
attr_reader :field, :latitude, :longitude
|
12
|
+
|
13
|
+
def initialize(field:, latitude:, longitude:)
|
14
|
+
@field = field
|
15
|
+
@latitude = latitude
|
16
|
+
@longitude = longitude
|
17
|
+
freeze
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_solr_s
|
21
|
+
# this constants are magical, but they influence the slope of geo proximity decay function
|
22
|
+
'recip(geodist(),3,17000,3000)'
|
23
|
+
end
|
24
|
+
|
25
|
+
# TODO: Check this dead code and the initialize arguments
|
26
|
+
def latlng
|
27
|
+
"#{latitude},#{longitude}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def sfield
|
31
|
+
solarize_field(field)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Solr
|
2
|
+
module Query
|
3
|
+
class Request
|
4
|
+
class Boosting
|
5
|
+
class LnFunctionBoost
|
6
|
+
include Solr::Support::SchemaHelper
|
7
|
+
|
8
|
+
attr_reader :field, :min, :boost_magnitude
|
9
|
+
|
10
|
+
def initialize(field:, min: 0.69, boost_magnitude: 1)
|
11
|
+
@field = field
|
12
|
+
@min = min
|
13
|
+
@boost_magnitude = boost_magnitude
|
14
|
+
freeze
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_solr_s
|
18
|
+
"mul(if(gt(#{solr_field},1),ln(#{solr_field}),#{min}),#{boost_magnitude})"
|
19
|
+
end
|
20
|
+
|
21
|
+
def solr_field
|
22
|
+
solarize_field(field)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Solr
|
2
|
+
module Query
|
3
|
+
class Request
|
4
|
+
class Boosting
|
5
|
+
class NumericFieldValueMatchBoostFunction < FieldValueMatchBoostFunction
|
6
|
+
def to_solr_s
|
7
|
+
"if(sub(def(#{solr_field},-1),#{value}),1,#{boost_magnitude})"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Solr
|
2
|
+
module Query
|
3
|
+
class Request
|
4
|
+
class Boosting
|
5
|
+
# https://wiki.apache.org/solr/ExtendedDisMax#pf_.28Phrase_Fields.29
|
6
|
+
# solr in action chapter 16.3.5
|
7
|
+
# we only need to do the phrase proximity boosting if we have a phrase, i.e. more than 1 word
|
8
|
+
class PhraseProximityBoost
|
9
|
+
include Solr::Support::SchemaHelper
|
10
|
+
|
11
|
+
attr_reader :field, :boost_magnitude
|
12
|
+
|
13
|
+
def initialize(field:, boost_magnitude:)
|
14
|
+
@field = field
|
15
|
+
@boost_magnitude = boost_magnitude
|
16
|
+
freeze
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_solr_s
|
20
|
+
solr_field = solarize_field(field)
|
21
|
+
"#{solr_field}^#{boost_magnitude}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Solr
|
2
|
+
module Query
|
3
|
+
class Request
|
4
|
+
class Boosting
|
5
|
+
class RankingFieldBoostFunction
|
6
|
+
include Solr::Support::SchemaHelper
|
7
|
+
attr_reader :field
|
8
|
+
|
9
|
+
def initialize(field:)
|
10
|
+
@field = field
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_solr_s
|
14
|
+
solarize_field(field).to_s
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Solr
|
2
|
+
module Query
|
3
|
+
class Request
|
4
|
+
class Boosting
|
5
|
+
class RecentFieldValueBoostFunction
|
6
|
+
include Solr::Support::SchemaHelper
|
7
|
+
|
8
|
+
attr_reader :field, :boost_magnitude, :max_age_days
|
9
|
+
|
10
|
+
def initialize(field:, boost_magnitude:, max_age_days:)
|
11
|
+
@field = field
|
12
|
+
@boost_magnitude = boost_magnitude
|
13
|
+
@max_age_days = max_age_days
|
14
|
+
freeze
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_solr_s
|
18
|
+
solr_field = solarize_field(field)
|
19
|
+
recip_max_age_days_ms = 1.0 / (max_age_days * 24 * 3600 * 1000)
|
20
|
+
"mul(#{boost_magnitude},recip(ms(NOW,#{solr_field}),#{recip_max_age_days_ms},0.5,0.1))"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Solr
|
2
|
+
module Query
|
3
|
+
class Request
|
4
|
+
class Boosting
|
5
|
+
class ScaleFunctionBoost
|
6
|
+
include Solr::Support::SchemaHelper
|
7
|
+
|
8
|
+
attr_reader :field, :min, :max
|
9
|
+
|
10
|
+
def initialize(field:, min:, max:)
|
11
|
+
@field = field
|
12
|
+
@min = min
|
13
|
+
@max = max
|
14
|
+
freeze
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_solr_s
|
18
|
+
"scale(#{solr_field},#{min},#{max})"
|
19
|
+
end
|
20
|
+
|
21
|
+
def solr_field
|
22
|
+
solarize_field(field)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|