daedal 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.rspec +3 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +82 -0
- data/Guardfile +4 -0
- data/LICENSE +20 -0
- data/README.md +4 -0
- data/daedal.gemspec +14 -0
- data/lib/daedal.rb +8 -0
- data/lib/daedal/attributes.rb +94 -0
- data/lib/daedal/filters.rb +7 -0
- data/lib/daedal/filters/base_filter.rb +17 -0
- data/lib/daedal/filters/term_filter.rb +18 -0
- data/lib/daedal/queries.rb +13 -0
- data/lib/daedal/queries/base_query.rb +13 -0
- data/lib/daedal/queries/bool_query.rb +48 -0
- data/lib/daedal/queries/constant_score_query.rb +35 -0
- data/lib/daedal/queries/dis_max_query.rb +37 -0
- data/lib/daedal/queries/filtered_query.rb +20 -0
- data/lib/daedal/queries/match_all_query.rb +12 -0
- data/lib/daedal/queries/match_query.rb +33 -0
- data/lib/daedal/queries/multi_match_query.rb +43 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/unit/daedal/filters/term_filter_spec.rb +55 -0
- data/spec/unit/daedal/queries/bool_query_spec.rb +214 -0
- data/spec/unit/daedal/queries/constant_score_query_spec.rb +72 -0
- data/spec/unit/daedal/queries/dis_max_query_spec.rb +151 -0
- data/spec/unit/daedal/queries/filtered_query_spec.rb +60 -0
- data/spec/unit/daedal/queries/match_all_query_spec.rb +19 -0
- data/spec/unit/daedal/queries/match_query_spec.rb +245 -0
- data/spec/unit/daedal/queries/multi_match_query_spec.rb +253 -0
- metadata +74 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'daedal/queries/match_all_query'
|
2
|
+
require 'daedal/filters/base_filter'
|
3
|
+
require 'daedal/queries/base_query'
|
4
|
+
require 'daedal/attributes'
|
5
|
+
|
6
|
+
module Daedal
|
7
|
+
module Queries
|
8
|
+
"""Class for the basic match query"""
|
9
|
+
class FilteredQuery < BaseQuery
|
10
|
+
|
11
|
+
# required attributes
|
12
|
+
attribute :query, Attributes::Query, default: Daedal::Queries::MatchAllQuery.new
|
13
|
+
attribute :filter, Attributes::Filter, default: Daedal::Filters::BaseFilter.new
|
14
|
+
|
15
|
+
def to_hash
|
16
|
+
{filtered: {query: query.to_hash, filter: filter.to_hash}}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'daedal/queries/base_query'
|
2
|
+
require 'daedal/attributes'
|
3
|
+
|
4
|
+
module Daedal
|
5
|
+
module Queries
|
6
|
+
|
7
|
+
"""Class for the basic match query"""
|
8
|
+
class MatchQuery < BaseQuery
|
9
|
+
|
10
|
+
# required attributes
|
11
|
+
attribute :field, Symbol
|
12
|
+
attribute :query, Symbol
|
13
|
+
|
14
|
+
# non required attributes
|
15
|
+
attribute :operator, Attributes::Operator, required: false
|
16
|
+
attribute :minimum_should_match, Integer, required: false
|
17
|
+
attribute :cutoff_frequency, Float, required: false
|
18
|
+
attribute :type, Attributes::MatchType, required: false
|
19
|
+
attribute :analyzer, Symbol, required: false
|
20
|
+
attribute :boost, Integer, required: false
|
21
|
+
attribute :fuzziness, Float, required: false
|
22
|
+
|
23
|
+
def to_hash
|
24
|
+
|
25
|
+
result = {match: {field => {query: query}}}
|
26
|
+
options = {minimum_should_match: minimum_should_match, cutoff_frequency: cutoff_frequency, type: type, analyzer: analyzer, boost: boost, fuzziness: fuzziness, operator: operator}
|
27
|
+
result[:match][field].merge! options.select {|k,v| !v.nil?}
|
28
|
+
|
29
|
+
result
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'daedal/queries/base_query'
|
2
|
+
require 'daedal/attributes'
|
3
|
+
|
4
|
+
module Daedal
|
5
|
+
module Queries
|
6
|
+
|
7
|
+
"""Class for the multi_match query"""
|
8
|
+
class MultiMatchQuery < BaseQuery
|
9
|
+
|
10
|
+
# required attributes
|
11
|
+
attribute :query, Symbol
|
12
|
+
attribute :fields, Array[Symbol]
|
13
|
+
|
14
|
+
# non required attributes
|
15
|
+
attribute :use_dis_max, Boolean, default: true
|
16
|
+
attribute :tie_breaker, Float, default: 0.0
|
17
|
+
attribute :operator, Attributes::Operator, required: false
|
18
|
+
attribute :minimum_should_match, Integer, required: false
|
19
|
+
attribute :cutoff_frequency, Float, required: false
|
20
|
+
attribute :type, Attributes::MatchType, required: false
|
21
|
+
attribute :analyzer, Symbol, required: false
|
22
|
+
attribute :boost, Integer, required: false
|
23
|
+
attribute :fuzziness, Float, required: false
|
24
|
+
|
25
|
+
def initialize(options={})
|
26
|
+
super options
|
27
|
+
|
28
|
+
if fields.empty?
|
29
|
+
raise "Must give at least one field to match on"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_hash
|
34
|
+
result = {multi_match: {query: query, fields: fields}}
|
35
|
+
options = {minimum_should_match: minimum_should_match, cutoff_frequency: cutoff_frequency, type: type, analyzer: analyzer, boost: boost, fuzziness: fuzziness, operator: operator}
|
36
|
+
|
37
|
+
result[:multi_match].merge!(options.select { |k,v| !v.nil? })
|
38
|
+
|
39
|
+
result
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'require_all'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
def append_load_path(*paths)
|
5
|
+
full_path = File.join([File.dirname(__FILE__), ".."] << paths)
|
6
|
+
$: << File.expand_path(full_path)
|
7
|
+
end
|
8
|
+
|
9
|
+
append_load_path('')
|
10
|
+
append_load_path('lib')
|
11
|
+
|
12
|
+
RSpec.configure do |config|
|
13
|
+
config.expect_with :rspec do |c|
|
14
|
+
c.syntax = :expect
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'daedal/filters'
|
3
|
+
|
4
|
+
describe Daedal::Filters::TermFilter do
|
5
|
+
|
6
|
+
subject do
|
7
|
+
Daedal::Filters::TermFilter
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:field) do
|
11
|
+
:foo
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:term) do
|
15
|
+
:bar
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:hash_filter) do
|
19
|
+
{term: {field => term}}
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'without a field or a term specified' do
|
23
|
+
it 'will raise an error' do
|
24
|
+
expect {subject.new}.to raise_error
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'without a field specified' do
|
29
|
+
it 'will raise an error' do
|
30
|
+
expect {subject.new(term: term)}.to raise_error
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'without a term specified' do
|
35
|
+
it 'will raise an error' do
|
36
|
+
expect {subject.new(field: field)}.to raise_error
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'with a field and a term specified' do
|
41
|
+
let(:filter) do
|
42
|
+
subject.new(field: field, term: term)
|
43
|
+
end
|
44
|
+
it 'will populate the field and term attributes appropriately' do
|
45
|
+
expect(filter.field).to eq field
|
46
|
+
expect(filter.term).to eq term
|
47
|
+
end
|
48
|
+
it 'will have the correct hash representation' do
|
49
|
+
expect(filter.to_hash).to eq hash_filter
|
50
|
+
end
|
51
|
+
it 'will have the correct json representation' do
|
52
|
+
expect(filter.to_json).to eq hash_filter.to_json
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,214 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'daedal/queries'
|
3
|
+
|
4
|
+
describe Daedal::Queries::BoolQuery do
|
5
|
+
|
6
|
+
subject do
|
7
|
+
Daedal::Queries::BoolQuery
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:match_query) do
|
11
|
+
Daedal::Queries::MatchQuery
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:hash_query) do
|
15
|
+
{bool: {should: [], must: [], must_not: []}}
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'with no initial queries specified' do
|
19
|
+
let(:query) do
|
20
|
+
subject.new
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'will give an empty bool query' do
|
24
|
+
expect(query.should).to eq Array.new
|
25
|
+
expect(query.must).to eq Array.new
|
26
|
+
expect(query.must_not).to eq Array.new
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'will have the correct hash representation' do
|
30
|
+
expect(query.to_hash).to eq hash_query
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'will have the correct json representation' do
|
34
|
+
expect(query.to_json).to eq hash_query.to_json
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'with a minimum should match specified' do
|
38
|
+
before do
|
39
|
+
hash_query[:bool][:minimum_should_match] = 2
|
40
|
+
end
|
41
|
+
let(:query_with_min) do
|
42
|
+
subject.new(minimum_should_match: 2)
|
43
|
+
end
|
44
|
+
it 'will set the minimum_should_match parameter' do
|
45
|
+
expect(query_with_min.minimum_should_match).to eq 2
|
46
|
+
end
|
47
|
+
it 'will have the correct hash representation' do
|
48
|
+
expect(query_with_min.to_hash).to eq hash_query
|
49
|
+
end
|
50
|
+
it 'will have the correct json representation' do
|
51
|
+
expect(query_with_min.to_json).to eq hash_query.to_json
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'with a boost specified' do
|
56
|
+
before do
|
57
|
+
hash_query[:bool][:boost] = 2
|
58
|
+
end
|
59
|
+
let(:query_with_boost) do
|
60
|
+
subject.new(boost: 2)
|
61
|
+
end
|
62
|
+
it 'will set the boost parameter' do
|
63
|
+
expect(query_with_boost.boost).to eq 2
|
64
|
+
end
|
65
|
+
it 'will have the correct hash representation' do
|
66
|
+
expect(query_with_boost.to_hash).to eq hash_query
|
67
|
+
end
|
68
|
+
it 'will have the correct json representation' do
|
69
|
+
expect(query_with_boost.to_json).to eq hash_query.to_json
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'with initial arrays of queries specified' do
|
75
|
+
|
76
|
+
let(:should) do
|
77
|
+
[match_query.new(field: :a, query: :b), match_query.new(field: :c, query: :d)]
|
78
|
+
end
|
79
|
+
let(:must) do
|
80
|
+
[match_query.new(field: :e, query: :f), match_query.new(field: :g, query: :h)]
|
81
|
+
end
|
82
|
+
let(:must_not) do
|
83
|
+
[match_query.new(field: :i, query: :j), match_query.new(field: :k, query: :l)]
|
84
|
+
end
|
85
|
+
|
86
|
+
let(:query) do
|
87
|
+
subject.new(should: should, must: must, must_not: must_not)
|
88
|
+
end
|
89
|
+
|
90
|
+
before do
|
91
|
+
hash_query[:bool][:should] = should.map {|q| q.to_hash}
|
92
|
+
hash_query[:bool][:must] = must.map {|q| q.to_hash}
|
93
|
+
hash_query[:bool][:must_not] = must_not.map {|q| q.to_hash}
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'will create a bool query with the appropriate initial arrays of queries' do
|
97
|
+
expect(query.should).to eq should
|
98
|
+
expect(query.must).to eq must
|
99
|
+
expect(query.must_not).to eq must_not
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'will have the correct hash representation' do
|
103
|
+
expect(query.to_hash).to eq hash_query
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'will have the correct json representation' do
|
107
|
+
expect(query.to_json).to eq hash_query.to_json
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'with an initial array of non queries specified' do
|
112
|
+
it 'will raise an error' do
|
113
|
+
expect {subject.new(should: [:foo])}.to raise_error
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'with a query (not in an array) specified' do
|
118
|
+
let(:mq) do
|
119
|
+
match_query.new(field: :a, query: :b)
|
120
|
+
end
|
121
|
+
|
122
|
+
let(:query) do
|
123
|
+
subject.new(should: mq)
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'will convert the input into an array of the single query' do
|
127
|
+
expect(query.should).to eq([mq])
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context 'when adding more queries' do
|
132
|
+
let(:query) do
|
133
|
+
subject.new
|
134
|
+
end
|
135
|
+
let(:mq) do
|
136
|
+
match_query.new(field: :a, query: :b)
|
137
|
+
end
|
138
|
+
|
139
|
+
context 'with the #add_should_query method' do
|
140
|
+
before do
|
141
|
+
query.add_should_query mq
|
142
|
+
end
|
143
|
+
it 'will add a should query' do
|
144
|
+
expect(query.should).to eq [mq]
|
145
|
+
end
|
146
|
+
|
147
|
+
context 'twice' do
|
148
|
+
before do
|
149
|
+
query.add_should_query mq
|
150
|
+
end
|
151
|
+
it 'will append the second query' do
|
152
|
+
expect(query.should).to eq [mq, mq]
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context 'with a non-valid query' do
|
157
|
+
it 'will raise an error' do
|
158
|
+
expect{query.add_should_query :foo}.to raise_error
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context 'with the #add_must_query method' do
|
164
|
+
before do
|
165
|
+
query.add_must_query mq
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'will add a should query' do
|
169
|
+
expect(query.must).to eq [mq]
|
170
|
+
end
|
171
|
+
|
172
|
+
context 'twice' do
|
173
|
+
before do
|
174
|
+
query.add_must_query mq
|
175
|
+
end
|
176
|
+
it 'will append the second query' do
|
177
|
+
expect(query.must).to eq [mq, mq]
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
context 'with a non-valid query' do
|
182
|
+
it 'will raise an error' do
|
183
|
+
expect {query.add_must_query :foo}.to raise_error
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
context 'with the #add_must_not_query method' do
|
190
|
+
before do
|
191
|
+
query.add_must_not_query mq
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'will add a must_not query' do
|
195
|
+
expect(query.must_not).to eq [mq]
|
196
|
+
end
|
197
|
+
|
198
|
+
context 'twice' do
|
199
|
+
before do
|
200
|
+
query.add_must_not_query mq
|
201
|
+
end
|
202
|
+
it 'will append the second query' do
|
203
|
+
expect(query.must_not).to eq [mq, mq]
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
context 'with a non-valid query' do
|
208
|
+
it 'will raise an error' do
|
209
|
+
expect {query.add_must_not_query :foo}.to raise_error
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'daedal/queries'
|
3
|
+
require 'daedal/filters'
|
4
|
+
|
5
|
+
describe Daedal::Queries::ConstantScoreQuery do
|
6
|
+
|
7
|
+
subject do
|
8
|
+
Daedal::Queries::ConstantScoreQuery
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:match_query) do
|
12
|
+
Daedal::Queries::MatchQuery.new(field: :foo, query: :bar)
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:term_filter) do
|
16
|
+
Daedal::Filters::TermFilter.new(field: :foo, term: :bar)
|
17
|
+
end
|
18
|
+
|
19
|
+
let(:hash_query) do
|
20
|
+
{constant_score: { boost: 5.0, query: match_query.to_hash}}
|
21
|
+
end
|
22
|
+
|
23
|
+
let(:hash_filter) do
|
24
|
+
{constant_score: { boost: 5.0, filter: term_filter.to_hash}}
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'without a query or a filter specified' do
|
28
|
+
it 'will raise an error' do
|
29
|
+
expect{subject.new(boost: 5)}.to raise_error
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'without a boost specified' do
|
34
|
+
it 'will raise an error' do
|
35
|
+
expect{subject.new(query: match_query)}.to raise_error
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'with a query and a boost specified' do
|
40
|
+
let(:query) do
|
41
|
+
subject.new(query: match_query, boost: 5)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'will create a constant score query with the correct query and boost' do
|
45
|
+
expect(query.query).to eq match_query
|
46
|
+
expect(query.boost).to eq 5.0
|
47
|
+
end
|
48
|
+
it 'will have the correct hash representation' do
|
49
|
+
expect(query.to_hash).to eq hash_query
|
50
|
+
end
|
51
|
+
it 'will have the correct json representation' do
|
52
|
+
expect(query.to_json).to eq hash_query.to_json
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'with a filter and a boost specified' do
|
57
|
+
let(:query) do
|
58
|
+
subject.new(filter: term_filter, boost: 5)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'will create a constant score query with the correct filter and boost' do
|
62
|
+
expect(query.filter).to eq term_filter
|
63
|
+
expect(query.boost).to eq 5.0
|
64
|
+
end
|
65
|
+
it 'will have the correct hash representation' do
|
66
|
+
expect(query.to_hash).to eq hash_filter
|
67
|
+
end
|
68
|
+
it 'will have the correct json representation' do
|
69
|
+
expect(query.to_json).to eq hash_filter.to_json
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|