CloudSesame 0.2.2 → 0.2.3
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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +110 -44
- data/cloud_sesame.gemspec +3 -3
- data/lib/cloud_sesame/domain/base.rb +1 -1
- data/lib/cloud_sesame/query/ast/literal.rb +3 -3
- data/lib/cloud_sesame/query/ast/multi_expression_operator.rb +1 -1
- data/lib/cloud_sesame/query/ast/range_value.rb +9 -9
- data/lib/cloud_sesame/query/dsl/field_array_methods.rb +18 -13
- data/lib/cloud_sesame/query/dsl/field_methods.rb +2 -6
- data/lib/cloud_sesame/query/dsl/operator_methods.rb +3 -3
- data/lib/cloud_sesame/query/dsl/range_methods.rb +25 -0
- data/lib/cloud_sesame/query/dsl/return_methods.rb +13 -6
- data/lib/cloud_sesame/query/{builder.rb → methods.rb} +1 -2
- data/lib/cloud_sesame/query/node/fuzziness.rb +3 -4
- data/lib/cloud_sesame/query/node/query.rb +6 -3
- data/lib/cloud_sesame/query/node/return.rb +5 -7
- data/lib/cloud_sesame.rb +2 -3
- data/spec/cloud_sesame/query/{builder_spec.rb → methods_spec.rb} +1 -1
- data/spec/cloud_sesame_spec.rb +30 -21
- metadata +7 -8
- data/lib/cloud_sesame/query/dsl/value_methods.rb +0 -25
- data/lib/cloud_sesame/query/fuzziness.rb +0 -58
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cad47f21e63d0bbeb0258dbb151d48e0ec5641fa
|
4
|
+
data.tar.gz: 84db3ca4528fcf0d12f4f434774cc79d8a6c878c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3ad6883b3f6132987d65ddfb8134a082e2b605317a7a1ade5f8e7b5512e63e5137668d45985e5e15b2bcfbd84527ee348d8d6d8b9e813ac24f42f4cf684127f7
|
7
|
+
data.tar.gz: b792c52ccc362256a202fbdf9c151bebd4a21ce8128e9d2efe8d66710e30690c55ef8564aa912848bdad131b8ba8847158e80d2e93672cb4d20ae0d6dbc7d1d5
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
#CloudSesame
|
2
|
-
|
2
|
+
Powerful and Flexible CloudSearch Query DSL
|
3
3
|
|
4
|
-
#
|
4
|
+
#Installation
|
5
5
|
* In terminal type:
|
6
6
|
```
|
7
7
|
gem install CloudSesame
|
8
8
|
```
|
9
|
-
* Or add this line to the application in Gemfile
|
9
|
+
* Or add this line to the application in `Gemfile`:
|
10
10
|
```
|
11
|
-
gem 'CloudSesame
|
11
|
+
gem 'CloudSesame'
|
12
12
|
```
|
13
13
|
|
14
|
-
#
|
14
|
+
#AWS Credentials
|
15
15
|
*Create a initializer file, example: `config/initializers/cloud_sesame.rb`
|
16
16
|
```
|
17
17
|
require 'cloud_sesame'
|
@@ -21,68 +21,122 @@ CloudSesame::Domain::Client.configure do |config|
|
|
21
21
|
config.secret_key = ENV['AWS_SECRET_ACCESS_KEY']
|
22
22
|
end
|
23
23
|
```
|
24
|
-
|
24
|
+
|
25
|
+
#Model Setup
|
25
26
|
##1. Mix CloudSesame into any class or model
|
27
|
+
- `include CloudSesame` in a model or class
|
28
|
+
- call `define_cloudsearch` and pass in a block to define the cloudsearch
|
29
|
+
|
30
|
+
#####define_cloudsearch(&block)
|
31
|
+
Includes all Model/Class specific cloudsearch configurations
|
32
|
+
#####config.endpoint=(string)
|
33
|
+
Set AWS CloudSearch instance search endpoint
|
34
|
+
#####config.region=(string)
|
35
|
+
Set AWS CloudSearch isntance region
|
36
|
+
#####default_size(integer = 10)
|
37
|
+
Set default search size
|
38
|
+
#####define_sloppiness(integer)
|
39
|
+
Setup sloppy query, it is turned off by default
|
40
|
+
#####define_fuzziness(&block)
|
41
|
+
Setup fuzziness, it is turned off by default.
|
42
|
+
the block can set 3 values
|
43
|
+
- **max_fuzziness(integer = 3)**
|
44
|
+
maxinmum fuzziness per word
|
45
|
+
- **min_char_size(integer = 6)**
|
46
|
+
minimum word length to trigger fuzziness
|
47
|
+
- **fuzzy_percent(float = 0.17)**
|
48
|
+
percent used to calculate the fuzziness based on the word length, fuzziness whill choose between the calculated result and maximum fizziness, whichever is smaller.
|
49
|
+
[(word.size * fuzzy_percent).round, max_fuzziness].min
|
50
|
+
|
51
|
+
#####field(symbol, options = {})
|
52
|
+
calling field and pass in a field_name will create an literal method, which can be called to create a literal expression
|
53
|
+
|
54
|
+
**field examples with query options**
|
55
|
+
```
|
56
|
+
field :name, query: true
|
57
|
+
# COMPILED: query_options[:fields] = ["name"]
|
58
|
+
|
59
|
+
field :tags, query: { weight: 2 }
|
60
|
+
# COMPILED: query_options[:fields] = ["name", "tags^2"]
|
61
|
+
```
|
62
|
+
**field example with facet**
|
63
|
+
```
|
64
|
+
# To enable facet
|
65
|
+
field :currency, facet: true
|
66
|
+
|
67
|
+
# To enable facet with buckets
|
68
|
+
field :discount, facet: {
|
69
|
+
buckets: %w([10,100] [25,100] [50,100] [70,100]),
|
70
|
+
method: 'interval'
|
71
|
+
}
|
72
|
+
|
73
|
+
# To enable facet with max size
|
74
|
+
field :manufacturer, facet: { size: 50 }
|
75
|
+
|
76
|
+
# To enable facet with sorting
|
77
|
+
field :category, facet: { sort: 'bucket', size: 10_000 }
|
78
|
+
|
79
|
+
```
|
80
|
+
|
81
|
+
#####scope(symbol, proc, &block)
|
82
|
+
ActiveRecord styled scope method. Scope allows you to specify commonly-used queries which can be referenced as method calls on cloudsearch or inside of operator block
|
83
|
+
|
84
|
+
|
85
|
+
|
86
|
+
**complete example**
|
26
87
|
```
|
27
88
|
class Product < ActiveRecord::Base
|
28
89
|
include CloudSesame
|
29
90
|
|
30
|
-
# call `define_cloudsearch` to setup your CloudSearch config, default size (optional), fields, and scopes (optional)
|
31
91
|
define_cloudsearch do
|
32
92
|
|
33
|
-
# REQUIRED: class specific config
|
34
93
|
config.endpoint = ENV['AWS_PRODUCT_SEARCH_ENDPOINT']
|
35
94
|
config.region = ENV['AWS_PRODUCT_SEARCH_REGION']
|
36
95
|
|
37
|
-
# default query size is 10
|
38
96
|
default_size <integer>
|
39
97
|
|
40
|
-
|
41
|
-
define_sloppiness 3
|
98
|
+
define_sloppiness <integer>
|
42
99
|
|
43
|
-
# turn on fuzzy search
|
44
100
|
define_fuzziness {
|
45
|
-
max_fuzziness <integer>
|
46
|
-
min_char_size <integer>
|
47
|
-
fuzzy_percent <float>
|
101
|
+
max_fuzziness <integer>
|
102
|
+
min_char_size <integer>
|
103
|
+
fuzzy_percent <float>
|
48
104
|
}
|
49
105
|
|
50
|
-
|
51
|
-
field :
|
52
|
-
field :description, query: true # => query_options[:fields] = ["description"]
|
106
|
+
field :product_name, query: { weight: <integer> }
|
107
|
+
field :description, query: true
|
53
108
|
|
54
|
-
field :currency, facet: true
|
55
|
-
field :discount, facet: {
|
109
|
+
field :currency, facet: true
|
110
|
+
field :discount, facet: {
|
56
111
|
buckets: %w([10,100] [25,100] [50,100] [70,100]),
|
57
112
|
method: 'interval'
|
58
113
|
}
|
59
|
-
field :manufacturer, facet: { size:
|
60
|
-
field :category, facet: {
|
61
|
-
sort: 'bucket', size:
|
114
|
+
field :manufacturer, facet: { size: <integer> }
|
115
|
+
field :category, facet: {
|
116
|
+
sort: 'bucket', size: <integer>
|
62
117
|
}
|
63
118
|
|
64
119
|
field :created_at
|
65
120
|
|
66
|
-
# scope examples
|
67
|
-
|
68
|
-
# INPUT: "puma",
|
69
|
-
# OUPUT: query="shoes", filter_query="(and manufacturer:'puma')"
|
70
121
|
scope :shoes_by_brand, ->(brand = nil) { query("shoes").and { manufacturer brand } if brand }
|
71
|
-
|
72
|
-
# INPUT: 1
|
73
|
-
# OUPUT: filter_query="(and created_at:{'2016-01-17T00:00:00Z',})"
|
122
|
+
|
74
123
|
scope :created_in, ->(days = nil) { and { created_at r.gt(Date.today - days) } if days }
|
75
124
|
|
76
125
|
end
|
77
126
|
end
|
78
127
|
```
|
79
|
-
|
128
|
+
|
129
|
+
#####load_definition_from(Class/Model)
|
130
|
+
every cloud
|
80
131
|
```
|
81
|
-
# Inheriting Definitions from another class
|
82
132
|
class ExclusiveProduct < Product
|
83
|
-
|
84
|
-
# load previous define cloudsearch definition
|
133
|
+
# load any define cloudsearch definition from class/model
|
85
134
|
load_definition_from Product
|
135
|
+
end
|
136
|
+
```
|
137
|
+
|
138
|
+
```
|
139
|
+
|
86
140
|
|
87
141
|
# call define_cloudsearch again to override config
|
88
142
|
# or map field to a different name
|
@@ -186,7 +240,10 @@ Product.cloudsearch.or { and!.not { ...} }
|
|
186
240
|
```
|
187
241
|
|
188
242
|
###Field Methods
|
189
|
-
|
243
|
+
#####field_name(*values)
|
244
|
+
- calling the field_name with multiple values will generate multiple field expression
|
245
|
+
- fields can be chained together
|
246
|
+
|
190
247
|
```
|
191
248
|
Product.cloudsearch.name("shoes")
|
192
249
|
# OUTPUT: "name:'shoes'"
|
@@ -200,7 +257,10 @@ Product.cloudsearch.name("shoes").price(100)
|
|
200
257
|
Product.cloudsearch.and { name "shoes"; price 25..100 }
|
201
258
|
# OUTPUT: "(and name:'shoes' price:[25,100])"
|
202
259
|
```
|
203
|
-
|
260
|
+
|
261
|
+
#####field_name.field_array_method(*values)
|
262
|
+
- #not, #prefix (#start_with, #begin_with), #near can be called after the field_name
|
263
|
+
- #not can be chained with another operator after, example: `name.not.prefix`
|
204
264
|
```
|
205
265
|
Product.cloudsearch.and { name.not "shoes"; ... }
|
206
266
|
# OUTPUT: "(and (not name:'shoes') ...)"
|
@@ -242,11 +302,17 @@ r.gt(Date.today) => "{'2016-01-18T00:00:00Z',}"
|
|
242
302
|
```
|
243
303
|
|
244
304
|
###Search Related Methods
|
245
|
-
* #search
|
246
|
-
* #found
|
247
|
-
* #results
|
248
|
-
* #each
|
249
|
-
* #map
|
250
|
-
|
251
|
-
|
252
|
-
* #
|
305
|
+
* #search => send off the request, save and returns the response and clear the request
|
306
|
+
* #found => returns the hits found from the response
|
307
|
+
* #results => returns the hits.hit from the response
|
308
|
+
* #each => Calls the given block once for each result, passing that result as a parameter. Returns the results itself.
|
309
|
+
* #map => Creates a new array containing the results returned by the block.
|
310
|
+
* #request => returns the cloudsearch ast tree
|
311
|
+
* #response => returns the last response
|
312
|
+
* #clear_request => resets the request
|
313
|
+
* #clear_reponse => resets the response
|
314
|
+
*
|
315
|
+
###MISC Methods
|
316
|
+
* #compile => compiles the current query and return the compiled hash
|
317
|
+
*
|
318
|
+
|
data/cloud_sesame.gemspec
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'CloudSesame'
|
3
|
-
s.version = '0.2.
|
3
|
+
s.version = '0.2.3'
|
4
4
|
s.date = '2016-01-14'
|
5
|
-
s.summary = "AWS CloudSearch Query
|
6
|
-
s.description = "AWS CloudSearch Query
|
5
|
+
s.summary = "AWS CloudSearch Query DSL"
|
6
|
+
s.description = "AWS CloudSearch Query DSL"
|
7
7
|
s.authors = ['Scott Chu', 'Emily Fan', 'Greg Ward', 'David McHoull',
|
8
8
|
'Alishan Ladhani', 'Justine Jones', 'Gillian Chesnais', 'Jeff Li']
|
9
9
|
s.email = 'dev@retailcommon.com'
|
@@ -6,9 +6,9 @@ module CloudSesame
|
|
6
6
|
attr_accessor :field
|
7
7
|
attr_reader :options, :value
|
8
8
|
|
9
|
-
def initialize(field = nil, value = nil, options = {})
|
9
|
+
def initialize(field = nil, value = nil, options = {}, &block)
|
10
10
|
@field = field
|
11
|
-
@value =
|
11
|
+
@value = valufy value
|
12
12
|
@options = options || {}
|
13
13
|
(@options[:included] ||= []) << @value
|
14
14
|
end
|
@@ -33,7 +33,7 @@ module CloudSesame
|
|
33
33
|
|
34
34
|
private
|
35
35
|
|
36
|
-
def
|
36
|
+
def valufy(value)
|
37
37
|
return value if value.kind_of? Value
|
38
38
|
return RangeValue.new value if value.kind_of? Range
|
39
39
|
return DateValue.new(value) if value.kind_of?(Date) || value.kind_of?(Time)
|
@@ -11,29 +11,29 @@ module CloudSesame
|
|
11
11
|
"#{ lb }#{ data[1].to_s },#{ data[2].to_s }#{ ub }"
|
12
12
|
end
|
13
13
|
|
14
|
-
def gt(value)
|
15
|
-
data[0], data[1] = false,
|
14
|
+
def gt(value = nil)
|
15
|
+
data[0], data[1] = false, valufy(value) if value
|
16
16
|
return self
|
17
17
|
end
|
18
18
|
|
19
|
-
def gte(value)
|
20
|
-
data[0], data[1] = true,
|
19
|
+
def gte(value = nil)
|
20
|
+
data[0], data[1] = true, valufy(value) if value
|
21
21
|
return self
|
22
22
|
end
|
23
23
|
|
24
|
-
def lt(value)
|
25
|
-
data[2], data[3] =
|
24
|
+
def lt(value = nil)
|
25
|
+
data[2], data[3] = valufy(value), false if value
|
26
26
|
return self
|
27
27
|
end
|
28
28
|
|
29
|
-
def lte(value)
|
30
|
-
data[2], data[3] =
|
29
|
+
def lte(value = nil)
|
30
|
+
data[2], data[3] = valufy(value), true if value
|
31
31
|
return self
|
32
32
|
end
|
33
33
|
|
34
34
|
private
|
35
35
|
|
36
|
-
def
|
36
|
+
def valufy(value)
|
37
37
|
return value if value.kind_of? Value
|
38
38
|
return DateValue.new(value) if value.kind_of?(Date) || value.kind_of?(Time)
|
39
39
|
Value.new value
|
@@ -1,37 +1,42 @@
|
|
1
|
+
# =========================================================
|
2
|
+
# field array methods enables field array to chain
|
3
|
+
# operators after calling the field expression
|
4
|
+
# accessor
|
5
|
+
# =========================================================
|
1
6
|
module CloudSesame
|
2
7
|
module Query
|
3
8
|
module DSL
|
4
9
|
module FieldArrayMethods
|
5
10
|
|
6
|
-
# NEAR
|
7
|
-
# =======================================
|
8
|
-
def near(*values)
|
9
|
-
parents[0] = { klass: AST::Near, options: extract_options(values) }
|
10
|
-
insert_and_return_children values
|
11
|
-
end
|
12
|
-
|
13
|
-
alias_method :sloppy, :near
|
14
|
-
|
15
11
|
# NOT
|
16
12
|
# =======================================
|
17
13
|
def not(*values)
|
18
14
|
parents[1] = { klass: AST::Not, options: extract_options(values) }
|
19
|
-
|
15
|
+
insert values
|
20
16
|
end
|
21
17
|
|
22
18
|
alias_method :is_not, :not
|
23
19
|
|
20
|
+
# NEAR
|
21
|
+
# =======================================
|
22
|
+
def near(*values)
|
23
|
+
parents[0] = { klass: AST::Near, options: extract_options(values) }
|
24
|
+
insert values
|
25
|
+
end
|
26
|
+
|
27
|
+
alias_method :sloppy, :near
|
28
|
+
|
24
29
|
# PREFIX
|
25
30
|
# =======================================
|
26
31
|
def prefix(*values)
|
27
32
|
parents[0] = { klass: AST::Prefix, options: extract_options(values) }
|
28
|
-
|
33
|
+
insert values
|
29
34
|
end
|
30
35
|
|
31
36
|
alias_method :start_with, :prefix
|
32
37
|
alias_method :begin_with, :prefix
|
33
38
|
|
34
|
-
def
|
39
|
+
def insert(values = [])
|
35
40
|
values.each do |value|
|
36
41
|
child = ensure_not_raw_value value
|
37
42
|
parents.compact.each do |parent|
|
@@ -53,7 +58,7 @@ module CloudSesame
|
|
53
58
|
|
54
59
|
def ensure_not_raw_value(value)
|
55
60
|
if value.kind_of?(AST::SingleExpressionOperator) || value.is_a?(AST::Literal)
|
56
|
-
value.
|
61
|
+
value.is_for field, field_options
|
57
62
|
value
|
58
63
|
else
|
59
64
|
AST::Literal.new field, value, field_options
|
@@ -5,15 +5,11 @@ module CloudSesame
|
|
5
5
|
|
6
6
|
private
|
7
7
|
|
8
|
-
def fields
|
9
|
-
dsl_context[:fields]
|
10
|
-
end
|
11
|
-
|
12
8
|
def method_missing(field, *values, &block)
|
13
|
-
if fields
|
9
|
+
if (fields = dsl_context[:fields]) && fields[field]
|
14
10
|
dsl_scope.children.field = field
|
15
11
|
dsl_scope.children.dsl_return = dsl_return
|
16
|
-
dsl_scope.children.
|
12
|
+
dsl_scope.children.insert values
|
17
13
|
else
|
18
14
|
super
|
19
15
|
end
|
@@ -39,11 +39,11 @@ module CloudSesame
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def create_literal(klass, options, value)
|
42
|
-
(
|
43
|
-
return
|
42
|
+
(node = klass.new dsl_context, options) << fieldless_literal(value)
|
43
|
+
return node
|
44
44
|
end
|
45
45
|
|
46
|
-
def
|
46
|
+
def fieldless_literal(value)
|
47
47
|
AST::Literal.new nil, value
|
48
48
|
end
|
49
49
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module CloudSesame
|
2
|
+
module Query
|
3
|
+
module DSL
|
4
|
+
module RangeMethods
|
5
|
+
|
6
|
+
def gt(input)
|
7
|
+
AST::RangeValue.new.gt(input)
|
8
|
+
end
|
9
|
+
|
10
|
+
def gte(input)
|
11
|
+
AST::RangeValue.new.gte(input)
|
12
|
+
end
|
13
|
+
|
14
|
+
def lt(input)
|
15
|
+
AST::RangeValue.new.lt(input)
|
16
|
+
end
|
17
|
+
|
18
|
+
def lte(input)
|
19
|
+
AST::RangeValue.new.lte(input)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -3,16 +3,23 @@ module CloudSesame
|
|
3
3
|
module DSL
|
4
4
|
module ReturnMethods
|
5
5
|
|
6
|
-
def
|
7
|
-
|
6
|
+
def return_fields(*fields)
|
7
|
+
unless fields.empty?
|
8
|
+
request.return_field.fields = fields
|
9
|
+
return self
|
10
|
+
else
|
11
|
+
request.return_field.fields
|
12
|
+
end
|
8
13
|
end
|
9
14
|
|
10
|
-
def
|
11
|
-
request.return_field.
|
15
|
+
def return_no_fields
|
16
|
+
request.return_field.fields = ['_no_fields']
|
17
|
+
return self
|
12
18
|
end
|
13
19
|
|
14
|
-
def
|
15
|
-
request.return_field.
|
20
|
+
def include_score
|
21
|
+
request.return_field.fields << '_score'
|
22
|
+
return self
|
16
23
|
end
|
17
24
|
|
18
25
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module CloudSesame
|
2
2
|
module Query
|
3
|
-
module
|
3
|
+
module Methods
|
4
4
|
include DSL::Base
|
5
5
|
include DSL::PageMethods
|
6
6
|
include DSL::QueryMethods
|
@@ -12,7 +12,6 @@ module CloudSesame
|
|
12
12
|
include DSL::FieldMethods
|
13
13
|
include DSL::FilterQueryMethods
|
14
14
|
include DSL::ScopeMethods
|
15
|
-
include DSL::ValueMethods
|
16
15
|
|
17
16
|
attr_reader :result
|
18
17
|
|
@@ -26,8 +26,7 @@ module CloudSesame
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def parse(string)
|
29
|
-
|
30
|
-
join_by_and result
|
29
|
+
join_by_and each_with(string) { |word| fuzziness word }
|
31
30
|
end
|
32
31
|
|
33
32
|
private
|
@@ -46,8 +45,8 @@ module CloudSesame
|
|
46
45
|
end
|
47
46
|
end
|
48
47
|
|
49
|
-
def join_by_and(
|
50
|
-
(args = args.
|
48
|
+
def join_by_and(args = [])
|
49
|
+
(args = args.compact).size > 1 ? "(#{ args.join('+') })" : args[0]
|
51
50
|
end
|
52
51
|
|
53
52
|
def excluding_term?(word)
|
@@ -10,7 +10,10 @@ module CloudSesame
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def compile
|
13
|
-
|
13
|
+
compiled = [query]
|
14
|
+
compiled << fuzziness if context[:fuzziness]
|
15
|
+
compiled << sloppiness if context[:sloppiness]
|
16
|
+
{ query: join_by_or(compiled) }
|
14
17
|
end
|
15
18
|
|
16
19
|
private
|
@@ -23,8 +26,8 @@ module CloudSesame
|
|
23
26
|
context[:sloppiness] && query && query.include?(' ') ? "\"#{ query }\"~#{ context[:sloppiness] }" : nil
|
24
27
|
end
|
25
28
|
|
26
|
-
def join_by_or(
|
27
|
-
(args = args.
|
29
|
+
def join_by_or(args = [])
|
30
|
+
(args = args.compact).size > 1 ? "(#{ args.join('|') })" : args[0]
|
28
31
|
end
|
29
32
|
|
30
33
|
end
|
@@ -3,16 +3,14 @@ module CloudSesame
|
|
3
3
|
module Node
|
4
4
|
class Return < Abstract
|
5
5
|
|
6
|
-
attr_accessor :
|
6
|
+
attr_accessor :fields
|
7
7
|
|
8
|
-
def
|
9
|
-
|
8
|
+
def fields
|
9
|
+
@fields ||= []
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
def format(value)
|
15
|
-
value.to_s.gsub(/^_?/, '_')
|
12
|
+
def compile
|
13
|
+
{ return: fields.join(',') } unless fields.empty?
|
16
14
|
end
|
17
15
|
|
18
16
|
end
|
data/lib/cloud_sesame.rb
CHANGED
@@ -28,9 +28,8 @@ require 'cloud_sesame/query/dsl/field_methods'
|
|
28
28
|
require 'cloud_sesame/query/dsl/field_array_methods'
|
29
29
|
require 'cloud_sesame/query/dsl/filter_query_methods'
|
30
30
|
require 'cloud_sesame/query/dsl/operator_methods'
|
31
|
+
require 'cloud_sesame/query/dsl/range_methods'
|
31
32
|
require 'cloud_sesame/query/dsl/scope_methods'
|
32
|
-
require 'cloud_sesame/query/dsl/value_methods'
|
33
|
-
|
34
33
|
|
35
34
|
# Query Query Filter Query AST Tree
|
36
35
|
# ===============================================
|
@@ -69,7 +68,7 @@ require 'cloud_sesame/query/node/return'
|
|
69
68
|
|
70
69
|
# Query Builder Interface
|
71
70
|
# ===============================================
|
72
|
-
require 'cloud_sesame/query/
|
71
|
+
require 'cloud_sesame/query/methods'
|
73
72
|
|
74
73
|
# Domain Objects
|
75
74
|
# ===============================================
|
data/spec/cloud_sesame_spec.rb
CHANGED
@@ -66,26 +66,35 @@ describe CloudSesame do
|
|
66
66
|
# end
|
67
67
|
|
68
68
|
# # Example Query
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
|
74
|
-
#
|
75
|
-
#
|
76
|
-
#
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
80
|
-
#
|
81
|
-
#
|
82
|
-
#
|
83
|
-
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
|
88
|
-
|
89
|
-
#
|
69
|
+
# require 'benchmark'
|
70
|
+
# Benchmark.bm do |x|
|
71
|
+
# x.report do
|
72
|
+
# 1.times do |i|
|
73
|
+
# query = Product.cloudsearch.query("black jacket").sort(price: :ast).page(1).size(1000).or {
|
74
|
+
# or! {
|
75
|
+
# tags("men", "women")
|
76
|
+
# }
|
77
|
+
# tags.not start_with("automotive"), "home"
|
78
|
+
# and! {
|
79
|
+
# price gt(100).lt(500)
|
80
|
+
# created_at gt(Date.today - 7)
|
81
|
+
# currency "CAD", "USD"
|
82
|
+
# }
|
83
|
+
|
84
|
+
# }.or {
|
85
|
+
# and! {
|
86
|
+
# tags "outdoor"
|
87
|
+
# price gt(200).lt(1000)
|
88
|
+
# created_at gt(Date.today - 7)
|
89
|
+
# currency "CAD", "USD"
|
90
|
+
# }
|
91
|
+
# }
|
92
|
+
|
93
|
+
# query.compile
|
94
|
+
# end
|
95
|
+
# end
|
96
|
+
# end
|
97
|
+
|
98
|
+
|
90
99
|
|
91
100
|
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.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott Chu
|
@@ -87,7 +87,7 @@ dependencies:
|
|
87
87
|
- - '>='
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
|
-
description: AWS CloudSearch Query
|
90
|
+
description: AWS CloudSearch Query DSL
|
91
91
|
email: dev@retailcommon.com
|
92
92
|
executables: []
|
93
93
|
extensions: []
|
@@ -124,7 +124,6 @@ files:
|
|
124
124
|
- lib/cloud_sesame/query/ast/single_expression_operator.rb
|
125
125
|
- lib/cloud_sesame/query/ast/term.rb
|
126
126
|
- lib/cloud_sesame/query/ast/value.rb
|
127
|
-
- lib/cloud_sesame/query/builder.rb
|
128
127
|
- lib/cloud_sesame/query/dsl/base.rb
|
129
128
|
- lib/cloud_sesame/query/dsl/block_chaining_methods.rb
|
130
129
|
- lib/cloud_sesame/query/dsl/block_methods.rb
|
@@ -134,14 +133,14 @@ files:
|
|
134
133
|
- lib/cloud_sesame/query/dsl/operator_methods.rb
|
135
134
|
- lib/cloud_sesame/query/dsl/page_methods.rb
|
136
135
|
- lib/cloud_sesame/query/dsl/query_methods.rb
|
136
|
+
- lib/cloud_sesame/query/dsl/range_methods.rb
|
137
137
|
- lib/cloud_sesame/query/dsl/return_methods.rb
|
138
138
|
- lib/cloud_sesame/query/dsl/scope_methods.rb
|
139
139
|
- lib/cloud_sesame/query/dsl/sort_methods.rb
|
140
|
-
- lib/cloud_sesame/query/dsl/value_methods.rb
|
141
140
|
- lib/cloud_sesame/query/error/invalid_syntax.rb
|
142
141
|
- lib/cloud_sesame/query/error/missing_operator_symbol.rb
|
143
142
|
- lib/cloud_sesame/query/error/missing_query.rb
|
144
|
-
- lib/cloud_sesame/query/
|
143
|
+
- lib/cloud_sesame/query/methods.rb
|
145
144
|
- lib/cloud_sesame/query/node/abstract.rb
|
146
145
|
- lib/cloud_sesame/query/node/facet.rb
|
147
146
|
- lib/cloud_sesame/query/node/filter_query.rb
|
@@ -157,13 +156,13 @@ files:
|
|
157
156
|
- spec/abstract_object_spec.rb
|
158
157
|
- spec/cloud_sesame/domain/base_spec.rb
|
159
158
|
- spec/cloud_sesame/domain/context_spec.rb
|
160
|
-
- spec/cloud_sesame/query/builder_spec.rb
|
161
159
|
- spec/cloud_sesame/query/dsl/base_spec.rb
|
162
160
|
- spec/cloud_sesame/query/dsl/block_chaining_methods_spec.rb
|
163
161
|
- spec/cloud_sesame/query/dsl/block_methods_spec.rb
|
164
162
|
- spec/cloud_sesame/query/dsl/field_array_methods_spec.rb
|
165
163
|
- spec/cloud_sesame/query/dsl/field_methods_spec.rb
|
166
164
|
- spec/cloud_sesame/query/dsl_spec.rb
|
165
|
+
- spec/cloud_sesame/query/methods_spec.rb
|
167
166
|
- spec/cloud_sesame/query/node/abstract_spec.rb
|
168
167
|
- spec/cloud_sesame/query/node/facet_spec.rb
|
169
168
|
- spec/cloud_sesame/query/node/filter_query_spec.rb
|
@@ -198,18 +197,18 @@ rubyforge_project:
|
|
198
197
|
rubygems_version: 2.4.8
|
199
198
|
signing_key:
|
200
199
|
specification_version: 4
|
201
|
-
summary: AWS CloudSearch Query
|
200
|
+
summary: AWS CloudSearch Query DSL
|
202
201
|
test_files:
|
203
202
|
- spec/abstract_object_spec.rb
|
204
203
|
- spec/cloud_sesame/domain/base_spec.rb
|
205
204
|
- spec/cloud_sesame/domain/context_spec.rb
|
206
|
-
- spec/cloud_sesame/query/builder_spec.rb
|
207
205
|
- spec/cloud_sesame/query/dsl/base_spec.rb
|
208
206
|
- spec/cloud_sesame/query/dsl/block_chaining_methods_spec.rb
|
209
207
|
- spec/cloud_sesame/query/dsl/block_methods_spec.rb
|
210
208
|
- spec/cloud_sesame/query/dsl/field_array_methods_spec.rb
|
211
209
|
- spec/cloud_sesame/query/dsl/field_methods_spec.rb
|
212
210
|
- spec/cloud_sesame/query/dsl_spec.rb
|
211
|
+
- spec/cloud_sesame/query/methods_spec.rb
|
213
212
|
- spec/cloud_sesame/query/node/abstract_spec.rb
|
214
213
|
- spec/cloud_sesame/query/node/facet_spec.rb
|
215
214
|
- spec/cloud_sesame/query/node/filter_query_spec.rb
|
@@ -1,25 +0,0 @@
|
|
1
|
-
module CloudSesame
|
2
|
-
module Query
|
3
|
-
module DSL
|
4
|
-
module ValueMethods
|
5
|
-
|
6
|
-
# DATE
|
7
|
-
# =======================================
|
8
|
-
def date(date)
|
9
|
-
AST::DateValue.new date
|
10
|
-
end
|
11
|
-
|
12
|
-
alias_method :d, :date
|
13
|
-
|
14
|
-
# RANGE
|
15
|
-
# =======================================
|
16
|
-
def range(range = nil)
|
17
|
-
AST::RangeValue.new range
|
18
|
-
end
|
19
|
-
|
20
|
-
alias_method :r, :range
|
21
|
-
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,58 +0,0 @@
|
|
1
|
-
module CloudSesame
|
2
|
-
module Query
|
3
|
-
class Fuzziness
|
4
|
-
|
5
|
-
def initialize(&block)
|
6
|
-
|
7
|
-
# default fuzziness
|
8
|
-
@max_fuzziness = 3
|
9
|
-
@min_char_size = 6
|
10
|
-
@fuzzy_percent = 0.17
|
11
|
-
|
12
|
-
instance_eval &block if block_given?
|
13
|
-
end
|
14
|
-
|
15
|
-
def max_fuzziness(int)
|
16
|
-
@max_fuzziness = int.to_i
|
17
|
-
end
|
18
|
-
|
19
|
-
def min_char_size(int)
|
20
|
-
@min_char_size = int.to_i
|
21
|
-
end
|
22
|
-
|
23
|
-
def fuzzy_percent(float)
|
24
|
-
@fuzzy_percent = float.to_f
|
25
|
-
end
|
26
|
-
|
27
|
-
def parse(string)
|
28
|
-
result = each_with(string) { |word| fuzziness word }
|
29
|
-
join_by_and result
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def each_with(string, &block)
|
35
|
-
string.split(' ').map &block
|
36
|
-
end
|
37
|
-
|
38
|
-
def fuzziness(word)
|
39
|
-
if word.length >= @min_char_size && !excluding_term?(word)
|
40
|
-
fuzziness = (word.length * @fuzzy_percent).round
|
41
|
-
fuzziness = [fuzziness, @max_fuzziness].min
|
42
|
-
"#{word}~#{fuzziness}"
|
43
|
-
else
|
44
|
-
word
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def join_by_and(*args)
|
49
|
-
(args = args.flatten.compact).size > 1 ? "(#{ args.join('+') })" : args[0]
|
50
|
-
end
|
51
|
-
|
52
|
-
def excluding_term?(word)
|
53
|
-
!!word.match(/^\-/)
|
54
|
-
end
|
55
|
-
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|