CloudSesame 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|