elasticband 0.1.0 → 0.1.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: af49e433d1512419bc8c9b383a2b0cb61fe968f4
4
- data.tar.gz: d6c0940f96228c7e203969232ed7ed4f3e236157
3
+ metadata.gz: ae34274114e94681aaa9b43e5640f314bf265193
4
+ data.tar.gz: 1406a12e82fada6ad971a853248906aad2166999
5
5
  SHA512:
6
- metadata.gz: d545e4df0a47007b785292f55b29bc6e9a02e7fc3fdf2059c95c9fab1c5fb4b0081d0a241f2373a7f9304f408b7d3eee1b0fdff80bbf9869dddac0906443a43f
7
- data.tar.gz: 0e7665259f56491b1c876934f7ac584b50a46022de13c2c02dca468fe3d0fe076bb919abf4da28f5bf8641dc5aab431cd9aba75993dda15e60111ca7b1e7ea97
6
+ metadata.gz: 61d9b27b7468403e5591395db6000f157881775d905465600e0ff04d5f2cdfa88a8f26a48da3a808d4565e0d56b356212dbb0462e24f88992c1bff213187d98a
7
+ data.tar.gz: b7064257bbc7bae491c156120da453715d29216ff75eadb451c2f7a55823f0c615ad41e90312d9be84940ea8db704fe8847c01b71f231ec73fe5deaed9e29e0c
@@ -18,10 +18,12 @@ module Elasticband
18
18
  # * `on:` Defines which attributes will searched in documents
19
19
  # * `only:` Filter the search results where the condition is `true`
20
20
  # * `except`: Filter the search results where the condition is `false`.
21
+ # * `includes:` Filter the search results with a `Match` query.
21
22
  # * `boost_by:` Boosts the score of a query result based on a attribute of the document.
22
23
  # This score will be multiplied for the `boost_by` attribute over function `ln2p`.
23
24
  # * `boost_where:` Boosts the score of a query result where some condition is `true`.
24
25
  # This score will be multiplied by 1000 (arbitrary, based on gem `searchkick`)
26
+ # * `boost_function:` Boosts using the function passed.
25
27
  #
26
28
  # #### Examples
27
29
  # ```
@@ -40,9 +42,15 @@ module Elasticband
40
42
  # Query.parse('foo', except: { company: { id: 1 } })
41
43
  # => { filtered: { query: ..., filter: { not: { term: { status: :published } } } } }
42
44
  #
45
+ # Query.parse('foo', includes: ['company', on: :description])
46
+ # => { filtered: { query: ..., filter: { query: { match: { description: 'company' } } } } }
47
+ #
43
48
  # Query.parse('foo', boost_by: :contents_count)
44
49
  # => { function_score: { query: ..., field_value_factor: { field: :contents_count, modifier: :ln2p } } }
45
50
  #
51
+ # Query.parse('foo', boost_function: "_score * doc['users_count'].value")
52
+ # => { function_score: { query: ..., script_score: { script: '_score * doc['users_count'].value' } } }
53
+ #
46
54
  # Query.parse('foo', boost_where: { company: { id: 1 } })
47
55
  # => {
48
56
  # function_score: {
@@ -55,8 +63,8 @@ module Elasticband
55
63
  # ```
56
64
  def parse(query_text, options = {})
57
65
  query = parse_on(query_text, options[:on])
58
- query = parse_only_and_except(query, options[:only], options[:except])
59
- query = parse_boost(query, options[:boost_by], options[:boost_where])
66
+ query = parse_query_filters(query, options.slice(:only, :except, :includes))
67
+ query = parse_boost(query, options.slice(:boost_by, :boost_where, :boost_function))
60
68
  query.to_h
61
69
  end
62
70
 
@@ -73,6 +81,8 @@ module Elasticband
73
81
  end
74
82
 
75
83
  def parse_on(query_text, on_options)
84
+ return Query.new if query_text.blank?
85
+
76
86
  if on_options.is_a?(Enumerable)
77
87
  Query::MultiMatch.new(query_text, on_options)
78
88
  else
@@ -80,10 +90,12 @@ module Elasticband
80
90
  end
81
91
  end
82
92
 
83
- def parse_only_and_except(query, only_options, except_options)
84
- return query if only_options.blank? && except_options.blank?
93
+ def parse_query_filters(query, filter_options)
94
+ return query if filter_options.blank?
85
95
 
86
- filter = parse_filters(only_options) + parse_filters(except_options).map { |f| Filter::Not.new(f) }
96
+ filter = parse_filters(filter_options[:only])
97
+ filter += parse_filters(filter_options[:except]).map { |f| Filter::Not.new(f) }
98
+ filter += parse_includes_filter(filter_options[:includes])
87
99
  filter = join_filters(filter)
88
100
 
89
101
  Query::Filtered.new(filter, query)
@@ -93,6 +105,12 @@ module Elasticband
93
105
  filters.count > 1 ? Filter::And.new(filters) : filters.first
94
106
  end
95
107
 
108
+ def parse_includes_filter(includes_options)
109
+ return [] if includes_options.blank?
110
+
111
+ [Filter::Query.new(parse(*includes_options))]
112
+ end
113
+
96
114
  def parse_filters(options)
97
115
  return [] if options.blank?
98
116
 
@@ -107,19 +125,21 @@ module Elasticband
107
125
  end
108
126
  end
109
127
 
110
- def parse_boost(query, boost_by_options, boost_where_options)
111
- return query if boost_by_options.blank? && boost_where_options.blank?
128
+ def parse_boost(query, boost_options)
129
+ return query if boost_options.blank?
112
130
 
113
- function = parse_boost_function(boost_by_options, boost_where_options)
131
+ function = parse_boost_function(boost_options)
114
132
  Query::FunctionScore.new(query, function)
115
133
  end
116
134
 
117
- def parse_boost_function(boost_by_options, boost_where_options)
118
- if boost_by_options.present?
119
- ScoreFunction::FieldValueFactor.new(boost_by_options, modifier: :ln2p)
120
- else
121
- filter = join_filters(parse_filters(boost_where_options))
135
+ def parse_boost_function(boost_options)
136
+ if boost_options[:boost_by].present?
137
+ ScoreFunction::FieldValueFactor.new(boost_options[:boost_by], modifier: :ln2p)
138
+ elsif boost_options[:boost_where].present?
139
+ filter = join_filters(parse_filters(boost_options[:boost_where]))
122
140
  ScoreFunction::Filtered.new(filter, ScoreFunction::BoostFactor.new(1_000))
141
+ else
142
+ ScoreFunction::ScriptScore.new(boost_options[:boost_function])
123
143
  end
124
144
  end
125
145
  end
@@ -1,3 +1,3 @@
1
1
  module Elasticband
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
data/spec/query_spec.rb CHANGED
@@ -8,6 +8,12 @@ RSpec.describe Elasticband::Query do
8
8
  end
9
9
 
10
10
  describe '.parse' do
11
+ context 'with no query' do
12
+ subject { described_class.parse('') }
13
+
14
+ it { is_expected.to eq(match_all: {}) }
15
+ end
16
+
11
17
  context 'with only the query text' do
12
18
  subject { described_class.parse('foo') }
13
19
 
@@ -175,6 +181,27 @@ RSpec.describe Elasticband::Query do
175
181
  end
176
182
  end
177
183
 
184
+ context 'with `:includes` option' do
185
+ let(:options) { { includes: ['bar', on: :description] } }
186
+
187
+ it 'returns a filtered query with query filter' do
188
+ is_expected.to eq(
189
+ filtered: {
190
+ query: { match: { _all: 'foo' } },
191
+ filter: {
192
+ query: { match: { description: 'bar' } }
193
+ }
194
+ }
195
+ )
196
+ end
197
+
198
+ it 'calls `.parse` for the includes option' do
199
+ allow(described_class).to receive(:parse).with('foo', options).and_call_original
200
+ expect(described_class).to receive(:parse).with('bar', on: :description).and_call_original
201
+ subject
202
+ end
203
+ end
204
+
178
205
  context 'with `:boost_by` option' do
179
206
  let(:options) { { boost_by: :contents_count } }
180
207
 
@@ -191,6 +218,21 @@ RSpec.describe Elasticband::Query do
191
218
  end
192
219
  end
193
220
 
221
+ context 'with `:boost_function` option' do
222
+ let(:options) { { boost_function: "_score * doc['users_count'].value" } }
223
+
224
+ it 'returns a function score query with a `script_score` function' do
225
+ is_expected.to eq(
226
+ function_score: {
227
+ query: { match: { _all: 'foo' } },
228
+ script_score: {
229
+ script: "_score * doc['users_count'].value"
230
+ }
231
+ }
232
+ )
233
+ end
234
+ end
235
+
194
236
  context 'with `:boost_where` option' do
195
237
  context 'with a regular attribute' do
196
238
  let(:options) { { boost_where: { status: :published } } }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elasticband
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Glauber Campinho