CloudSesame 0.1.3 → 0.1.4
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/cloud_sesame.gemspec +2 -2
- data/lib/cloud_sesame.rb +34 -11
- data/lib/cloud_sesame/domain/base.rb +30 -22
- data/lib/cloud_sesame/domain/context.rb +4 -0
- data/lib/cloud_sesame/query/ast/and.rb +1 -1
- data/lib/cloud_sesame/query/ast/compound_array.rb +20 -11
- data/lib/cloud_sesame/query/ast/literal.rb +25 -1
- data/lib/cloud_sesame/query/ast/{operator.rb → multi_expression_operator.rb} +1 -1
- data/lib/cloud_sesame/query/ast/near.rb +15 -0
- data/lib/cloud_sesame/query/ast/not.rb +2 -6
- data/lib/cloud_sesame/query/ast/or.rb +1 -1
- data/lib/cloud_sesame/query/ast/prefix.rb +15 -0
- data/lib/cloud_sesame/query/ast/single_expression_operator.rb +24 -0
- data/lib/cloud_sesame/query/builder.rb +15 -42
- data/lib/cloud_sesame/query/dsl/filter_query.rb +1 -0
- data/lib/cloud_sesame/query/dsl/literal.rb +1 -10
- data/lib/cloud_sesame/query/dsl/literal_helper.rb +17 -0
- data/lib/cloud_sesame/query/dsl/page.rb +27 -0
- data/lib/cloud_sesame/query/dsl/query.rb +18 -0
- data/lib/cloud_sesame/query/dsl/scope.rb +1 -1
- data/lib/cloud_sesame/query/dsl/sort.rb +20 -0
- data/spec/cloud_sesame/domain/base_spec.rb +1 -1
- data/spec/cloud_sesame/query/ast/{operator_spec.rb → multi_expression_operator_spec.rb} +4 -4
- data/spec/cloud_sesame_spec.rb +57 -52
- metadata +12 -7
- data/lib/cloud_sesame/query/ast/prefix_literal.rb +0 -17
- data/lib/cloud_sesame/query/dsl.rb +0 -62
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f00925c20af3319d8ce8f88dc5dff6387d8d68b6
|
4
|
+
data.tar.gz: f175cc69bb9a53b6a7e3c783c67d482d0361d64b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1eed85f4d9436110b17c7e0b842713daaaf5278014fd20f5a8c2e00931392bfb0d5e66b3ee0f796bb4df36f31753497f43353f1b93826247dbb4b0a2c03ff2f6
|
7
|
+
data.tar.gz: 6d4a8daea2e4edfbecbf33c325022295040a0b73ca8e8c9c11e451a23d1e2b49d728319d542a76fac93a73d1ba7a8872f3b0ce77502611519effc572fcbfd304
|
data/Gemfile.lock
CHANGED
data/cloud_sesame.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'CloudSesame'
|
3
|
-
s.version = '0.1.
|
4
|
-
s.date = '2016-01-
|
3
|
+
s.version = '0.1.4'
|
4
|
+
s.date = '2016-01-14'
|
5
5
|
s.summary = "AWS CloudSearch Query Interface"
|
6
6
|
s.description = "AWS CloudSearch Query Interface"
|
7
7
|
s.authors = ['Scott Chu', 'Emily Fan', 'Greg Ward', 'David McHoull',
|
data/lib/cloud_sesame.rb
CHANGED
@@ -8,35 +8,44 @@ require 'forwardable'
|
|
8
8
|
require 'abstract_object'
|
9
9
|
require 'cloud_sesame/config/credential'
|
10
10
|
|
11
|
+
# Custom Errors
|
12
|
+
# ===============================================
|
11
13
|
require 'cloud_sesame/query/error/missing_operator_symbol'
|
12
14
|
require 'cloud_sesame/query/error/missing_query'
|
13
15
|
|
14
|
-
|
16
|
+
# Query DSL Methods
|
17
|
+
# ===============================================
|
15
18
|
require 'cloud_sesame/query/dsl/base'
|
19
|
+
require 'cloud_sesame/query/dsl/query'
|
20
|
+
require 'cloud_sesame/query/dsl/page'
|
21
|
+
require 'cloud_sesame/query/dsl/sort'
|
16
22
|
require 'cloud_sesame/query/dsl/and'
|
17
23
|
require 'cloud_sesame/query/dsl/or'
|
18
24
|
require 'cloud_sesame/query/dsl/range'
|
19
25
|
require 'cloud_sesame/query/dsl/literal'
|
26
|
+
require 'cloud_sesame/query/dsl/literal_helper'
|
20
27
|
require 'cloud_sesame/query/dsl/scope'
|
21
28
|
require 'cloud_sesame/query/dsl/filter_query'
|
22
29
|
|
23
|
-
|
24
|
-
|
25
|
-
require 'cloud_sesame/query/builder'
|
26
|
-
|
30
|
+
# Query Query Filter Query AST Tree
|
31
|
+
# ===============================================
|
27
32
|
require 'cloud_sesame/query/ast/multi_branch'
|
28
33
|
require 'cloud_sesame/query/ast/single_branch'
|
29
|
-
require 'cloud_sesame/query/ast/leaf'
|
30
34
|
require 'cloud_sesame/query/ast/root'
|
31
|
-
require 'cloud_sesame/query/ast/
|
35
|
+
require 'cloud_sesame/query/ast/leaf'
|
36
|
+
require 'cloud_sesame/query/ast/multi_expression_operator'
|
32
37
|
require 'cloud_sesame/query/ast/and'
|
33
38
|
require 'cloud_sesame/query/ast/or'
|
39
|
+
require 'cloud_sesame/query/ast/single_expression_operator'
|
34
40
|
require 'cloud_sesame/query/ast/not'
|
35
|
-
require 'cloud_sesame/query/ast/
|
41
|
+
require 'cloud_sesame/query/ast/near'
|
42
|
+
require 'cloud_sesame/query/ast/prefix'
|
36
43
|
require 'cloud_sesame/query/ast/compound_array'
|
37
|
-
require 'cloud_sesame/query/ast/
|
44
|
+
require 'cloud_sesame/query/ast/literal'
|
38
45
|
require 'cloud_sesame/query/ast/value'
|
39
46
|
|
47
|
+
# Query Request Nodes
|
48
|
+
# ===============================================
|
40
49
|
require 'cloud_sesame/query/node/abstract'
|
41
50
|
require 'cloud_sesame/query/node/request'
|
42
51
|
require 'cloud_sesame/query/node/query'
|
@@ -48,12 +57,17 @@ require 'cloud_sesame/query/node/facet'
|
|
48
57
|
require 'cloud_sesame/query/node/page'
|
49
58
|
require 'cloud_sesame/query/node/sort'
|
50
59
|
|
60
|
+
# Query Builder Interface
|
61
|
+
# ===============================================
|
62
|
+
require 'cloud_sesame/query/builder'
|
63
|
+
|
64
|
+
# Domain Objects
|
65
|
+
# ===============================================
|
51
66
|
require 'cloud_sesame/domain/base'
|
52
67
|
require 'cloud_sesame/domain/client'
|
53
68
|
require 'cloud_sesame/domain/config'
|
54
69
|
require 'cloud_sesame/domain/context'
|
55
70
|
|
56
|
-
|
57
71
|
# Public Interface
|
58
72
|
# ===============================================
|
59
73
|
module CloudSesame
|
@@ -69,7 +83,16 @@ module CloudSesame
|
|
69
83
|
end
|
70
84
|
|
71
85
|
def define_cloudsearch(&block)
|
72
|
-
|
86
|
+
if block_given?
|
87
|
+
cloudsearch.definition = block
|
88
|
+
cloudsearch.instance_eval &block
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def load_definition_from(klass)
|
93
|
+
if klass.respond_to?(:cloudsearch) && klass.cloudsearch.definition
|
94
|
+
cloudsearch.instance_eval &klass.cloudsearch.definition
|
95
|
+
end
|
73
96
|
end
|
74
97
|
|
75
98
|
end
|
@@ -2,18 +2,19 @@ module CloudSesame
|
|
2
2
|
module Domain
|
3
3
|
class Base
|
4
4
|
extend Forwardable
|
5
|
+
include Query::DSL::Scope
|
5
6
|
|
6
|
-
|
7
|
+
attr_accessor :definition
|
8
|
+
attr_reader :searchable
|
7
9
|
|
8
10
|
def_delegator :client, :config
|
9
11
|
|
10
|
-
def_delegators :builder, :query, :
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:included?, :excluded?
|
12
|
+
def_delegators :builder, :query, :page, :size, :sort,
|
13
|
+
:and, :or, :included?, :excluded?,
|
14
|
+
:method_context, :method_return, :method_scope
|
14
15
|
|
15
|
-
def initialize(
|
16
|
-
@
|
16
|
+
def initialize(searchable)
|
17
|
+
@searchable = searchable
|
17
18
|
end
|
18
19
|
|
19
20
|
def client
|
@@ -21,7 +22,7 @@ module CloudSesame
|
|
21
22
|
end
|
22
23
|
|
23
24
|
def builder
|
24
|
-
@builder ||= CloudSesame::Query::Builder.new context,
|
25
|
+
@builder ||= CloudSesame::Query::Builder.new context, searchable
|
25
26
|
end
|
26
27
|
|
27
28
|
# DEFAULT CONTEXT METHODS
|
@@ -36,22 +37,14 @@ module CloudSesame
|
|
36
37
|
end
|
37
38
|
|
38
39
|
def field(name, options = {})
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
define_query_options(name, options[:query]) if options[:query]
|
44
|
-
|
45
|
-
# define facet options
|
46
|
-
define_facet_options(name, options[:facet]) if options[:facet]
|
40
|
+
field_name = options[:as] || name
|
41
|
+
define_query_options(field_name, options.delete(:query)) if options[:query]
|
42
|
+
define_facet_options(field_name, options.delete(:facet)) if options[:facet]
|
43
|
+
define_filter_query_field(name, options)
|
47
44
|
end
|
48
45
|
|
49
|
-
def
|
50
|
-
|
51
|
-
end
|
52
|
-
|
53
|
-
def define_facet_options(name, facet_options)
|
54
|
-
context[:facet, true][name.to_sym] = format_options(facet_options)
|
46
|
+
def default_scope(proc, &block)
|
47
|
+
scope :default, proc, &block
|
55
48
|
end
|
56
49
|
|
57
50
|
def scope(name, proc = nil, &block)
|
@@ -65,6 +58,21 @@ module CloudSesame
|
|
65
58
|
options.is_a?(Hash) ? options : {}
|
66
59
|
end
|
67
60
|
|
61
|
+
def define_filter_query_field(name, options)
|
62
|
+
if (as = options[:as]) && (existing_options = context[:filter_query, true][:fields, true].delete(as))
|
63
|
+
options.merge!(existing_options)
|
64
|
+
end
|
65
|
+
context[:filter_query, true][:fields, true][name.to_sym] = options
|
66
|
+
end
|
67
|
+
|
68
|
+
def define_query_options(name, options)
|
69
|
+
context[:query_options, true][:fields, true][name.to_sym] = format_options(options)
|
70
|
+
end
|
71
|
+
|
72
|
+
def define_facet_options(name, options)
|
73
|
+
context[:facet, true][name.to_sym] = format_options(options)
|
74
|
+
end
|
75
|
+
|
68
76
|
end
|
69
77
|
end
|
70
78
|
end
|
@@ -9,7 +9,6 @@ module CloudSesame
|
|
9
9
|
|
10
10
|
def field=(field)
|
11
11
|
self.parent = nil
|
12
|
-
self.literal = AST::Literal
|
13
12
|
@field = field
|
14
13
|
end
|
15
14
|
|
@@ -20,21 +19,30 @@ module CloudSesame
|
|
20
19
|
|
21
20
|
# SINGLE BRANCH OPERATOR
|
22
21
|
# =======================================
|
22
|
+
|
23
|
+
# NOT
|
24
|
+
# =======================================
|
23
25
|
def not(*values)
|
24
26
|
self.parent = AST::Not
|
25
|
-
|
26
|
-
insert_children(values)
|
27
|
-
return self
|
27
|
+
insert_and_return_children(values)
|
28
28
|
end
|
29
29
|
|
30
30
|
alias_method :is_not, :not
|
31
31
|
|
32
|
+
# NEAR
|
33
|
+
# =======================================
|
34
|
+
def near(*values)
|
35
|
+
self.parent = AST::Near
|
36
|
+
insert_and_return_children(values)
|
37
|
+
end
|
38
|
+
|
39
|
+
alias_method :sloppy, :near
|
40
|
+
|
32
41
|
# PREFIX LITERAL
|
33
42
|
# =======================================
|
34
43
|
def prefix(*values)
|
35
|
-
self.
|
36
|
-
|
37
|
-
return self
|
44
|
+
self.parent = AST::Prefix
|
45
|
+
insert_and_return_children(values)
|
38
46
|
end
|
39
47
|
|
40
48
|
alias_method :start_with, :prefix
|
@@ -44,21 +52,22 @@ module CloudSesame
|
|
44
52
|
# =======================================
|
45
53
|
# def range
|
46
54
|
# self.literal = AST::PrefixLiteral
|
47
|
-
#
|
55
|
+
# insert_and_return_children(values)
|
48
56
|
# return self
|
49
57
|
# end
|
50
58
|
|
51
59
|
# alias_method :start_with, :prefix
|
52
60
|
|
53
|
-
def
|
61
|
+
def insert_and_return_children(values = [])
|
54
62
|
values.each do |value|
|
55
63
|
if parent
|
56
64
|
self << (node = parent.new scope.context)
|
57
|
-
node.child =
|
65
|
+
node.child = AST::Literal.new(field, value, options)
|
58
66
|
else
|
59
|
-
self <<
|
67
|
+
self << AST::Literal.new(field, value, options)
|
60
68
|
end
|
61
69
|
end
|
70
|
+
return self
|
62
71
|
end
|
63
72
|
|
64
73
|
private
|
@@ -13,12 +13,36 @@ module CloudSesame
|
|
13
13
|
(options[:included] ||= []) << value
|
14
14
|
end
|
15
15
|
|
16
|
+
def detailed
|
17
|
+
options[:detailed] = true
|
18
|
+
return self
|
19
|
+
end
|
20
|
+
|
16
21
|
def value=(value)
|
17
22
|
@value = Value.new(value)
|
18
23
|
end
|
19
24
|
|
20
25
|
def compile
|
21
|
-
|
26
|
+
options[:detailed] ? long_format : short_format
|
27
|
+
end
|
28
|
+
|
29
|
+
def as_field
|
30
|
+
options[:as] || field
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def short_format
|
36
|
+
"#{ as_field }:#{ value.compile }"
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def long_format
|
41
|
+
"field=#{ escape as_field } #{ value.compile }"
|
42
|
+
end
|
43
|
+
|
44
|
+
def escape(data = "")
|
45
|
+
"'#{ data.to_s.gsub(/\'/) { "\\'" } }'"
|
22
46
|
end
|
23
47
|
|
24
48
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module CloudSesame
|
2
|
+
module Query
|
3
|
+
module AST
|
4
|
+
class SingleExpressionOperator < SingleBranch
|
5
|
+
|
6
|
+
# Operator Symbol Writer
|
7
|
+
def self.symbol=(symbol)
|
8
|
+
@symbol = symbol
|
9
|
+
end
|
10
|
+
|
11
|
+
# Operator Symbol Getter
|
12
|
+
def self.symbol
|
13
|
+
@symbol
|
14
|
+
end
|
15
|
+
|
16
|
+
def compile
|
17
|
+
raise Error::MissingOperatorSymbol if self.class.symbol.nil?
|
18
|
+
"(#{ self.class.symbol } #{ child.compile })" if child
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -3,57 +3,31 @@ module CloudSesame
|
|
3
3
|
class Builder
|
4
4
|
include DSL::Base
|
5
5
|
include DSL::FilterQuery
|
6
|
+
include DSL::Page
|
7
|
+
include DSL::Query
|
8
|
+
include DSL::Sort
|
6
9
|
|
7
|
-
|
10
|
+
attr_reader :context, :searchable, :result
|
8
11
|
|
9
|
-
def initialize(default_context,
|
12
|
+
def initialize(default_context, searchable)
|
10
13
|
@context = default_context
|
11
|
-
@
|
14
|
+
@searchable = searchable
|
12
15
|
end
|
13
16
|
|
14
17
|
def request
|
15
|
-
@request ||= Node::Request.new context.dup
|
18
|
+
@request ||= (clear_result; Node::Request.new context.dup)
|
16
19
|
end
|
17
20
|
|
18
|
-
def
|
21
|
+
def clear_request
|
19
22
|
@request = nil
|
20
23
|
end
|
21
24
|
|
22
|
-
def
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
# CHAINABLE METHODS
|
27
|
-
# =========================================
|
28
|
-
|
29
|
-
def query(string)
|
30
|
-
request.query.query = string
|
31
|
-
return self
|
32
|
-
end
|
33
|
-
|
34
|
-
def terms(*terms)
|
35
|
-
request.query.terms.concat terms
|
36
|
-
return self
|
25
|
+
def clear_result
|
26
|
+
@result = nil
|
37
27
|
end
|
38
28
|
|
39
|
-
def
|
40
|
-
|
41
|
-
return self
|
42
|
-
end
|
43
|
-
|
44
|
-
def page(value)
|
45
|
-
request.page.page = value.to_i
|
46
|
-
return self
|
47
|
-
end
|
48
|
-
|
49
|
-
def size(value)
|
50
|
-
request.page.size = value.to_i
|
51
|
-
return self
|
52
|
-
end
|
53
|
-
|
54
|
-
def sort(hash = {})
|
55
|
-
hash.each { |key, value| request.sort[key] = value }
|
56
|
-
return self
|
29
|
+
def inspect
|
30
|
+
"#<CloudSesame::Query::Builder:#{ object_id } #{ request.compile }>"
|
57
31
|
end
|
58
32
|
|
59
33
|
# ENDING METHODS
|
@@ -61,10 +35,9 @@ module CloudSesame
|
|
61
35
|
|
62
36
|
def search
|
63
37
|
compiled = request.compile
|
64
|
-
raise Error::MissingQuery.new("Query can not be empty!")
|
65
|
-
|
66
|
-
|
67
|
-
result
|
38
|
+
raise Error::MissingQuery.new("Query or FilterQuery can not be empty!") if !compiled[:query] || compiled[:query].empty?
|
39
|
+
clear_request
|
40
|
+
@result = searchable.cloudsearch.client.search compiled
|
68
41
|
end
|
69
42
|
|
70
43
|
private
|
@@ -11,14 +11,6 @@ module CloudSesame
|
|
11
11
|
node
|
12
12
|
end
|
13
13
|
|
14
|
-
def date(date_object)
|
15
|
-
strip date_object.strftime('%FT%TZ')
|
16
|
-
end
|
17
|
-
|
18
|
-
def strip(string)
|
19
|
-
string.gsub(/ /, '')
|
20
|
-
end
|
21
|
-
|
22
14
|
private
|
23
15
|
|
24
16
|
def fields
|
@@ -28,8 +20,7 @@ module CloudSesame
|
|
28
20
|
def method_missing(field, *values, &block)
|
29
21
|
if fields && (options = fields[field])
|
30
22
|
method_scope.children.field = field
|
31
|
-
method_scope.children.
|
32
|
-
method_scope.children
|
23
|
+
method_scope.children.insert_and_return_children(values)
|
33
24
|
else
|
34
25
|
super
|
35
26
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module CloudSesame
|
2
|
+
module Query
|
3
|
+
module DSL
|
4
|
+
module Page
|
5
|
+
|
6
|
+
def page(input = nil)
|
7
|
+
if input
|
8
|
+
request.page.page = input.to_i
|
9
|
+
return self
|
10
|
+
else
|
11
|
+
request.page.page
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def size(input)
|
16
|
+
if input
|
17
|
+
request.page.size = input.to_i
|
18
|
+
return self
|
19
|
+
else
|
20
|
+
request.page.size
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module CloudSesame
|
2
|
+
module Query
|
3
|
+
module DSL
|
4
|
+
module Sort
|
5
|
+
|
6
|
+
def sort(input = nil)
|
7
|
+
if input.is_a? Hash
|
8
|
+
input.each { |key, value| request.sort[key] = value }
|
9
|
+
return self
|
10
|
+
elsif input
|
11
|
+
request.sort[input]
|
12
|
+
else
|
13
|
+
request.sort.sorting_attributes
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -3,14 +3,14 @@ require "spec_helper"
|
|
3
3
|
module CloudSesame
|
4
4
|
module Query
|
5
5
|
module AST
|
6
|
-
describe
|
6
|
+
describe MultiExpressionOperator do
|
7
7
|
let(:proc) { Proc.new {} }
|
8
|
-
let(:operator) {
|
9
|
-
before {
|
8
|
+
let(:operator) { MultiExpressionOperator.new({}, &proc )}
|
9
|
+
before { MultiExpressionOperator.symbol = :symbol }
|
10
10
|
|
11
11
|
describe '#compile' do
|
12
12
|
it 'should raise an error if operator symbol has not being set' do
|
13
|
-
|
13
|
+
MultiExpressionOperator.symbol = nil
|
14
14
|
expect{ operator.compile }.to raise_error(Error::MissingOperatorSymbol)
|
15
15
|
end
|
16
16
|
|
data/spec/cloud_sesame_spec.rb
CHANGED
@@ -1,58 +1,63 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe CloudSesame
|
3
|
+
describe CloudSesame do
|
4
|
+
|
5
|
+
# # AWS initializer
|
6
|
+
# require 'yaml'
|
7
|
+
# YAML.load_file('aws.yml').each do |key, value|
|
8
|
+
# ENV["AWS_#{ key }"] = value
|
9
|
+
# end
|
10
|
+
|
11
|
+
# # Domain Initializer /config/initializers/cloudsearch.rb
|
12
|
+
# CloudSesame::Domain::Client.configure do |config|
|
13
|
+
# config.access_key = ENV['AWS_ACCESS_KEY_ID']
|
14
|
+
# config.secret_key = ENV['AWS_SECRET_ACCESS_KEY']
|
15
|
+
# end
|
16
|
+
|
17
|
+
# # Usage Example
|
18
|
+
# class Product
|
19
|
+
# include CloudSesame
|
20
|
+
|
21
|
+
# define_cloudsearch do
|
22
|
+
# # Product CloudSesame Config
|
23
|
+
# config.endpoint = ENV['AWS_ENDPOINT']
|
24
|
+
# config.region = ENV['AWS_REGION']
|
25
|
+
|
26
|
+
# default_size 100
|
27
|
+
# field :searchable_text, query: { weight: 2 }
|
28
|
+
# field :description, query: true
|
29
|
+
# field :tags
|
30
|
+
|
31
|
+
# field :affiliate_advertiser_ext_id, facet: { size: 50 }
|
32
|
+
# field :currency, facet: true
|
33
|
+
# field :discount_percentage, facet: { buckets: %w([10,100] [25,100] [50,100] [70,100]), method: 'interval' }
|
34
|
+
# field :manufacturer_name, facet: { size: 50 }
|
35
|
+
# field :price, facet: { buckets: %w([0,25] [25,50] [50,100] [100,200] [200,}), method: 'interval' }
|
36
|
+
# field :category_string, facet: { sort: 'bucket', size: 10_000 }
|
37
|
+
# field :created_at
|
38
|
+
|
39
|
+
# scope :men_tag, -> { tags "men" }
|
40
|
+
# scope :and_mens, -> { and! { tags "men"} }
|
41
|
+
|
42
|
+
# end
|
43
|
+
|
44
|
+
# end
|
45
|
+
|
46
|
+
# class NewProduct < Product
|
47
|
+
# load_definition_from Product
|
48
|
+
|
49
|
+
# define_cloudsearch do
|
50
|
+
# field :searchable_text, query: { weight: 4 }
|
51
|
+
# end
|
52
|
+
# end
|
53
|
+
|
54
|
+
# # Example Query
|
55
|
+
# # result = Product.cloudsearch.query("shoes")
|
56
|
+
# # .page(3)
|
57
|
+
# # .or {
|
58
|
+
# # tags.not.near "men", "women"
|
59
|
+
# # }
|
4
60
|
|
5
|
-
# AWS initializer
|
6
|
-
require 'yaml'
|
7
|
-
YAML.load_file('aws.yml').each do |key, value|
|
8
|
-
ENV["AWS_#{ key }"] = value
|
9
|
-
end
|
10
|
-
|
11
|
-
# Domain Initializer /config/initializers/cloudsearch.rb
|
12
|
-
CloudSesame::Domain::Client.configure do |config|
|
13
|
-
config.access_key = ENV['AWS_ACCESS_KEY_ID']
|
14
|
-
config.secret_key = ENV['AWS_SECRET_ACCESS_KEY']
|
15
|
-
end
|
16
|
-
|
17
|
-
# Usage Example
|
18
|
-
class Product
|
19
|
-
include CloudSesame
|
20
|
-
|
21
|
-
define_cloudsearch do
|
22
|
-
|
23
|
-
# Product CloudSesame Config
|
24
|
-
config.endpoint = ENV['AWS_ENDPOINT']
|
25
|
-
config.region = ENV['AWS_REGION']
|
26
|
-
|
27
|
-
default_size 100
|
28
|
-
|
29
|
-
field :searchable_text, query: { weight: 2 }
|
30
|
-
field :description, query: true
|
31
|
-
field :tags
|
32
|
-
|
33
|
-
field :affiliate_advertiser_ext_id, facet: { size: 50 }
|
34
|
-
field :currency, facet: true
|
35
|
-
field :discount_percentage, facet: { buckets: %w([10,100] [25,100] [50,100] [70,100]), method: 'interval' }
|
36
|
-
field :manufacturer_name, facet: { size: 50 }
|
37
|
-
field :price, facet: { buckets: %w([0,25] [25,50] [50,100] [100,200] [200,}), method: 'interval' }
|
38
|
-
field :category_string, facet: { sort: 'bucket', size: 10_000 }
|
39
|
-
field :created_at
|
40
|
-
|
41
|
-
scope :men_tag, -> { tags "men" }
|
42
|
-
scope :and_mens, -> { and! { tags "men"} }
|
43
|
-
|
44
|
-
end
|
45
|
-
|
46
|
-
end
|
47
|
-
|
48
|
-
result = Product.cloudsearch.query("shoes")
|
49
|
-
.page(3)
|
50
|
-
.or {
|
51
|
-
tags.not.start_with 'home', 'outdoor'
|
52
|
-
price.start_with(100)
|
53
|
-
}
|
54
|
-
|
55
|
-
# result.included?(price: 100)
|
56
61
|
# binding.pry
|
57
62
|
|
58
63
|
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.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott Chu
|
@@ -15,7 +15,7 @@ authors:
|
|
15
15
|
autorequire:
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
|
-
date: 2016-01-
|
18
|
+
date: 2016-01-14 00:00:00.000000000 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: aws-sdk
|
@@ -111,22 +111,27 @@ files:
|
|
111
111
|
- lib/cloud_sesame/query/ast/leaf.rb
|
112
112
|
- lib/cloud_sesame/query/ast/literal.rb
|
113
113
|
- lib/cloud_sesame/query/ast/multi_branch.rb
|
114
|
+
- lib/cloud_sesame/query/ast/multi_expression_operator.rb
|
115
|
+
- lib/cloud_sesame/query/ast/near.rb
|
114
116
|
- lib/cloud_sesame/query/ast/not.rb
|
115
|
-
- lib/cloud_sesame/query/ast/operator.rb
|
116
117
|
- lib/cloud_sesame/query/ast/or.rb
|
117
|
-
- lib/cloud_sesame/query/ast/
|
118
|
+
- lib/cloud_sesame/query/ast/prefix.rb
|
118
119
|
- lib/cloud_sesame/query/ast/root.rb
|
119
120
|
- lib/cloud_sesame/query/ast/single_branch.rb
|
121
|
+
- lib/cloud_sesame/query/ast/single_expression_operator.rb
|
120
122
|
- lib/cloud_sesame/query/ast/value.rb
|
121
123
|
- lib/cloud_sesame/query/builder.rb
|
122
|
-
- lib/cloud_sesame/query/dsl.rb
|
123
124
|
- lib/cloud_sesame/query/dsl/and.rb
|
124
125
|
- lib/cloud_sesame/query/dsl/base.rb
|
125
126
|
- lib/cloud_sesame/query/dsl/filter_query.rb
|
126
127
|
- lib/cloud_sesame/query/dsl/literal.rb
|
128
|
+
- lib/cloud_sesame/query/dsl/literal_helper.rb
|
127
129
|
- lib/cloud_sesame/query/dsl/or.rb
|
130
|
+
- lib/cloud_sesame/query/dsl/page.rb
|
131
|
+
- lib/cloud_sesame/query/dsl/query.rb
|
128
132
|
- lib/cloud_sesame/query/dsl/range.rb
|
129
133
|
- lib/cloud_sesame/query/dsl/scope.rb
|
134
|
+
- lib/cloud_sesame/query/dsl/sort.rb
|
130
135
|
- lib/cloud_sesame/query/error/missing_operator_symbol.rb
|
131
136
|
- lib/cloud_sesame/query/error/missing_query.rb
|
132
137
|
- lib/cloud_sesame/query/node/abstract.rb
|
@@ -145,7 +150,7 @@ files:
|
|
145
150
|
- spec/cloud_sesame/query/ast/and_spec.rb
|
146
151
|
- spec/cloud_sesame/query/ast/literal_spec.rb
|
147
152
|
- spec/cloud_sesame/query/ast/multi_branch_spec.rb
|
148
|
-
- spec/cloud_sesame/query/ast/
|
153
|
+
- spec/cloud_sesame/query/ast/multi_expression_operator_spec.rb
|
149
154
|
- spec/cloud_sesame/query/ast/or_spec.rb
|
150
155
|
- spec/cloud_sesame/query/ast/root_spec.rb
|
151
156
|
- spec/cloud_sesame/query/ast/value_spec.rb
|
@@ -196,7 +201,7 @@ test_files:
|
|
196
201
|
- spec/cloud_sesame/query/ast/and_spec.rb
|
197
202
|
- spec/cloud_sesame/query/ast/literal_spec.rb
|
198
203
|
- spec/cloud_sesame/query/ast/multi_branch_spec.rb
|
199
|
-
- spec/cloud_sesame/query/ast/
|
204
|
+
- spec/cloud_sesame/query/ast/multi_expression_operator_spec.rb
|
200
205
|
- spec/cloud_sesame/query/ast/or_spec.rb
|
201
206
|
- spec/cloud_sesame/query/ast/root_spec.rb
|
202
207
|
- spec/cloud_sesame/query/ast/value_spec.rb
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module CloudSesame
|
2
|
-
module Query
|
3
|
-
module AST
|
4
|
-
class PrefixLiteral < Literal
|
5
|
-
|
6
|
-
def compile
|
7
|
-
"(prefix field=#{ escape(field) } #{ value.compile })"
|
8
|
-
end
|
9
|
-
|
10
|
-
def escape(data = "")
|
11
|
-
"'#{ data.to_s.gsub(/\'/) { "\\'" } }'"
|
12
|
-
end
|
13
|
-
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,62 +0,0 @@
|
|
1
|
-
# module CloudSesame
|
2
|
-
# module Query
|
3
|
-
# module DSL
|
4
|
-
|
5
|
-
# # CLAUSE: AND
|
6
|
-
# # =========================================
|
7
|
-
# def and(&block)
|
8
|
-
# filter_query.children << AST::And.new(context, &block)
|
9
|
-
# return filter_query
|
10
|
-
# end
|
11
|
-
|
12
|
-
# alias_method :all, :and
|
13
|
-
# alias_method :and!, :and
|
14
|
-
# alias_method :+, :and
|
15
|
-
|
16
|
-
# # CLAUSE: OR
|
17
|
-
# # =========================================
|
18
|
-
# def or(&block)
|
19
|
-
# filter_query.children << AST::Or.new(context, &block)
|
20
|
-
# return filter_query
|
21
|
-
# end
|
22
|
-
|
23
|
-
# alias_method :any, :or
|
24
|
-
# alias_method :or!, :or
|
25
|
-
|
26
|
-
# # CLAUSE: LITERAL
|
27
|
-
# # =========================================
|
28
|
-
# def literal(field, value, options = {})
|
29
|
-
# node = AST::Literal.new(field, value, options)
|
30
|
-
# filter_query.children << node
|
31
|
-
# node
|
32
|
-
# end
|
33
|
-
|
34
|
-
# def prefix(literals)
|
35
|
-
# literals.each { |literal| literal.options[:prefix] = true }
|
36
|
-
# return filter_query
|
37
|
-
# end
|
38
|
-
|
39
|
-
# private
|
40
|
-
|
41
|
-
# def filter_query
|
42
|
-
# self
|
43
|
-
# end
|
44
|
-
|
45
|
-
# def scopes
|
46
|
-
# filter_query.context[:scopes]
|
47
|
-
# end
|
48
|
-
|
49
|
-
# def method_missing(field, *values, &block)
|
50
|
-
# if context[:fields] && (options = context[:fields][field])
|
51
|
-
# values.map { |value| literal(field, value, options) }
|
52
|
-
# elsif scope && (callback = scope[field])
|
53
|
-
# filter_query.instance_exec *values, &callback
|
54
|
-
# return filter_query
|
55
|
-
# else
|
56
|
-
# super
|
57
|
-
# end
|
58
|
-
# end
|
59
|
-
|
60
|
-
# end
|
61
|
-
# end
|
62
|
-
# end
|