CloudSesame 0.8.3 → 0.9.0

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.
data/lib/cloud_sesame.rb CHANGED
@@ -37,6 +37,7 @@ require 'cloud_sesame/query/dsl/range_helper'
37
37
  require 'cloud_sesame/query/dsl/response_methods'
38
38
  require 'cloud_sesame/query/dsl/return_methods'
39
39
  require 'cloud_sesame/query/dsl/sort_methods'
40
+ require 'cloud_sesame/query/dsl/k_gram_phrase_methods'
40
41
 
41
42
  # Query Query Domain Objects
42
43
  # ===============================================
@@ -10,6 +10,10 @@ module CloudSesame
10
10
  new value.to_s if value
11
11
  end
12
12
 
13
+ def to_ary
14
+ compile.split(' ')
15
+ end
16
+
13
17
  private
14
18
 
15
19
  def recompile(value)
@@ -11,6 +11,7 @@ module CloudSesame
11
11
  include DSL::ReturnMethods
12
12
  include DSL::ScopeAccessors
13
13
  include DSL::SortMethods
14
+ include DSL::KGramPhraseMethods
14
15
 
15
16
  # ClassSpecific construct class callback
16
17
  #
@@ -9,6 +9,7 @@ module CloudSesame
9
9
  include DSL::RangeHelper
10
10
  include DSL::ScopeAccessors
11
11
  include DSL::BindCaller
12
+ include DSL::KGramPhraseMethods
12
13
 
13
14
  after_construct { |_, field_accessor| include field_accessor }
14
15
 
@@ -0,0 +1,50 @@
1
+ module CloudSesame
2
+ module Query
3
+ module DSL
4
+ module KGramPhraseMethods
5
+ DELIMITER = / |-/.freeze
6
+ MULTIPLIER = 5
7
+
8
+ def k_gram_phrase(field, value, options = {})
9
+ if value && !value.empty?
10
+ words = value.split(DELIMITER).compact
11
+
12
+ or!(options) do
13
+ literal field, phrase(value, boost: MULTIPLIER * words.size)
14
+
15
+ each_k_gram_combination(words, options[:min]) do |combination, original|
16
+ remaining_terms = (original - combination).join(' ')
17
+ unique_phrase = combination.join(' ')
18
+ k = MULTIPLIER * combination.size
19
+
20
+ and!(boost: k + 2) do
21
+ literal field, phrase(unique_phrase)
22
+ literal field, term(remaining_terms)
23
+ end
24
+
25
+ literal field, phrase(unique_phrase, boost: k)
26
+ end
27
+
28
+ literal field, term(value)
29
+ end
30
+ end
31
+
32
+ _return != _scope ? _return : self
33
+ end
34
+
35
+ private
36
+
37
+ def each_k_gram_combination(array, min)
38
+ min ||= 4
39
+ size = array.size
40
+ m = [size - min, 1].max
41
+ n = size - 1
42
+ while n > m
43
+ array.each_cons(n) { |con| yield(con, array) }
44
+ n -= 1
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -9,7 +9,7 @@ module CloudSesame
9
9
  end
10
10
 
11
11
  def self.query
12
- @query
12
+ @query ||= Query
13
13
  end
14
14
 
15
15
  # CHILDREN
@@ -94,10 +94,10 @@ module CloudSesame
94
94
  context 'when given no type' do
95
95
  let(:initial_value) { 10..20 }
96
96
 
97
- it 'should not parse the start and end value' do
98
- expect(type).to_not receive(:parse)
99
- subject
100
- end
97
+ # it 'should not parse the start and end value' do
98
+ # expect(type).to_not receive(:parse)
99
+ # subject
100
+ # end
101
101
  it 'should keep the original start and end value' do
102
102
  expect(subject.begin).to be_kind_of(Numeric)
103
103
  expect(subject.end).to be_kind_of(Numeric)
@@ -143,13 +143,13 @@ module CloudSesame
143
143
  subject.parse(parse_type)
144
144
  end
145
145
  end
146
- context 'given type is nil' do
147
- let(:parse_type) { nil }
148
- it 'should not try to parse the begin and end value' do
149
- expect(parse_type).to_not receive(:parse)
150
- subject.parse(parse_type)
151
- end
152
- end
146
+ # context 'given type is nil' do
147
+ # let(:parse_type) { nil }
148
+ # it 'should not try to parse the begin and end value' do
149
+ # expect(parse_type).to_not receive(:parse)
150
+ # subject.parse(parse_type)
151
+ # end
152
+ # end
153
153
  end
154
154
 
155
155
  describe '#begin' do
@@ -0,0 +1,99 @@
1
+ module CloudSesame
2
+ module Query
3
+ module DSL
4
+ describe KGramPhraseMethods do
5
+
6
+ class Product
7
+ include CloudSesame
8
+ define_cloudsearch do
9
+ field :name, query: { weight: 2 }, type: :string
10
+ field :description, query: { weight: 0.4 }, type: :string
11
+ end
12
+ end
13
+
14
+ subject(:cloudsearch) { Product.cloudsearch.builder }
15
+ let(:root) { cloudsearch.request.filter_query.root }
16
+
17
+ describe '#k_gram_phrase' do
18
+ let(:phrase) { 'listerine mouth wash' }
19
+
20
+ it 'inserts an OR node at its scope level' do
21
+ expect { cloudsearch.k_gram_phrase(:name, phrase) }.to change { root.children }.by([AST::Or])
22
+ end
23
+
24
+ describe 'in the OR node' do
25
+ let(:or_node) { root.children.first }
26
+
27
+ it 'builds a phrase node with original term' do
28
+ cloudsearch.k_gram_phrase(:name, phrase)
29
+
30
+ phrase_node = or_node.children.first
31
+ expect(phrase_node).to be_kind_of AST::Phrase
32
+ expect(phrase_node.child.value).to eq(phrase)
33
+ end
34
+
35
+ it 'builds a term node with original term' do
36
+ cloudsearch.k_gram_phrase(:name, phrase)
37
+
38
+ term_node = or_node.children.last
39
+ expect(term_node).to be_kind_of AST::Term
40
+ expect(term_node.child.value).to eq(phrase)
41
+ end
42
+
43
+ it 'builds bunch of phrase nodes with k grams' do
44
+ cloudsearch.k_gram_phrase(:name, phrase)
45
+ k_nodes = or_node.children[1..-1]
46
+
47
+ expect(k_nodes[0]).to be_kind_of AST::And
48
+
49
+ expect(k_nodes[1]).to be_kind_of AST::Phrase
50
+ expect(k_nodes[1].options[:boost]).to eq(10)
51
+ expect(k_nodes[1].child.value).to eq('listerine mouth')
52
+
53
+ expect(k_nodes[2]).to be_kind_of AST::And
54
+
55
+ expect(k_nodes[3]).to be_kind_of AST::Phrase
56
+ expect(k_nodes[3].options[:boost]).to eq(10)
57
+ expect(k_nodes[3].child.value).to eq('mouth wash')
58
+ end
59
+
60
+ it 'builds the correct first And node' do
61
+ cloudsearch.k_gram_phrase(:name, phrase)
62
+ and_node = or_node.children[1..-1][0]
63
+
64
+ expect(and_node.options[:boost]).to eq(12)
65
+
66
+ expect(and_node.children.first).to be_kind_of AST::Phrase
67
+ expect(and_node.children.first.child.value).to eq('listerine mouth')
68
+
69
+ expect(and_node.children.last).to be_kind_of AST::Term
70
+ expect(and_node.children.last.child.value).to eq('wash')
71
+ end
72
+
73
+ it 'builds the correct second And node' do
74
+ cloudsearch.k_gram_phrase(:name, phrase)
75
+ and_node = or_node.children[1..-1][2]
76
+
77
+ expect(and_node.options[:boost]).to eq(12)
78
+
79
+ expect(and_node.children.first).to be_kind_of AST::Phrase
80
+ expect(and_node.children.first.child.value).to eq('mouth wash')
81
+
82
+ expect(and_node.children.last).to be_kind_of AST::Term
83
+ expect(and_node.children.last.child.value).to eq('listerine')
84
+ end
85
+ end
86
+
87
+ context 'when phrase is empty' do
88
+ let(:phrase) { nil }
89
+
90
+ it 'does not build anything' do
91
+ expect { cloudsearch.k_gram_phrase(:name, phrase) }.to_not change { root.children }
92
+ end
93
+ end
94
+ end
95
+
96
+ end
97
+ end
98
+ end
99
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: CloudSesame
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.3
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Chu
@@ -16,7 +16,7 @@ authors:
16
16
  autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
- date: 2016-08-25 00:00:00.000000000 Z
19
+ date: 2016-09-07 00:00:00.000000000 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: aws-sdk
@@ -188,6 +188,7 @@ files:
188
188
  - lib/cloud_sesame/query/dsl/bind_caller.rb
189
189
  - lib/cloud_sesame/query/dsl/block_styled_operators.rb
190
190
  - lib/cloud_sesame/query/dsl/inspect_method.rb
191
+ - lib/cloud_sesame/query/dsl/k_gram_phrase_methods.rb
191
192
  - lib/cloud_sesame/query/dsl/literal_chaining_methods.rb
192
193
  - lib/cloud_sesame/query/dsl/literal_methods.rb
193
194
  - lib/cloud_sesame/query/dsl/operators.rb
@@ -246,6 +247,7 @@ files:
246
247
  - spec/cloud_sesame/query/domain/block_spec.rb
247
248
  - spec/cloud_sesame/query/dsl/applied_filter_query_spec.rb
248
249
  - spec/cloud_sesame/query/dsl/block_styled_operators_spec.rb
250
+ - spec/cloud_sesame/query/dsl/k_gram_phrase_methods_spec.rb
249
251
  - spec/cloud_sesame/query/dsl/literal_chaining_methods_spec.rb
250
252
  - spec/cloud_sesame/query/dsl/literal_methods_spec.rb
251
253
  - spec/cloud_sesame/query/node/abstract_spec.rb
@@ -318,6 +320,7 @@ test_files:
318
320
  - spec/cloud_sesame/query/domain/block_spec.rb
319
321
  - spec/cloud_sesame/query/dsl/applied_filter_query_spec.rb
320
322
  - spec/cloud_sesame/query/dsl/block_styled_operators_spec.rb
323
+ - spec/cloud_sesame/query/dsl/k_gram_phrase_methods_spec.rb
321
324
  - spec/cloud_sesame/query/dsl/literal_chaining_methods_spec.rb
322
325
  - spec/cloud_sesame/query/dsl/literal_methods_spec.rb
323
326
  - spec/cloud_sesame/query/node/abstract_spec.rb