CloudSesame 0.1.5 → 0.1.6
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 +57 -0
- data/cloud_sesame.gemspec +1 -1
- data/lib/cloud_sesame.rb +9 -5
- data/lib/cloud_sesame/domain/base.rb +4 -12
- data/lib/cloud_sesame/query/ast/compound_array.rb +30 -35
- data/lib/cloud_sesame/query/ast/date_value.rb +1 -9
- data/lib/cloud_sesame/query/ast/literal.rb +20 -20
- data/lib/cloud_sesame/query/ast/multi_branch.rb +1 -1
- data/lib/cloud_sesame/query/ast/multi_expression_operator.rb +2 -4
- data/lib/cloud_sesame/query/ast/near.rb +11 -2
- data/lib/cloud_sesame/query/ast/phrase.rb +14 -0
- data/lib/cloud_sesame/query/ast/prefix.rb +1 -2
- data/lib/cloud_sesame/query/ast/range_value.rb +16 -41
- data/lib/cloud_sesame/query/ast/root.rb +3 -13
- data/lib/cloud_sesame/query/ast/single_branch.rb +5 -2
- data/lib/cloud_sesame/query/ast/single_expression_operator.rb +2 -4
- data/lib/cloud_sesame/query/ast/term.rb +14 -0
- data/lib/cloud_sesame/query/ast/value.rb +10 -2
- data/lib/cloud_sesame/query/builder.rb +30 -5
- data/lib/cloud_sesame/query/dsl/boost.rb +20 -0
- data/lib/cloud_sesame/query/dsl/filter_query.rb +11 -20
- data/lib/cloud_sesame/query/dsl/literal.rb +48 -8
- data/lib/cloud_sesame/query/dsl/page.rb +4 -0
- data/lib/cloud_sesame/query/dsl/return.rb +21 -0
- data/lib/cloud_sesame/query/dsl/value.rb +28 -0
- data/lib/cloud_sesame/query/node/request.rb +6 -1
- data/lib/cloud_sesame/query/node/return.rb +21 -0
- data/spec/cloud_sesame/query/ast/multi_branch_spec.rb +1 -1
- data/spec/cloud_sesame/query/ast/multi_expression_operator_spec.rb +0 -4
- data/spec/cloud_sesame/query/dsl/filter_query_spec.rb +6 -56
- data/spec/cloud_sesame/query/node/request_spec.rb +2 -2
- data/spec/cloud_sesame_spec.rb +22 -7
- metadata +8 -3
- data/lib/cloud_sesame/query/dsl/literal_helper.rb +0 -17
- data/lib/cloud_sesame/query/dsl/range.rb +0 -41
@@ -1,21 +1,11 @@
|
|
1
1
|
module CloudSesame
|
2
2
|
module Query
|
3
3
|
module AST
|
4
|
-
class Root <
|
4
|
+
class Root < And
|
5
|
+
self.symbol = :and
|
5
6
|
|
6
7
|
def compile
|
7
|
-
|
8
|
-
join_by_default_operator.compile
|
9
|
-
else
|
10
|
-
compile_children
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
private
|
15
|
-
|
16
|
-
def join_by_default_operator
|
17
|
-
(default = And.new context).children.concat children
|
18
|
-
default
|
8
|
+
children.size > 1 ? super : compile_children
|
19
9
|
end
|
20
10
|
|
21
11
|
end
|
@@ -2,7 +2,6 @@ module CloudSesame
|
|
2
2
|
module Query
|
3
3
|
module AST
|
4
4
|
class SingleBranch
|
5
|
-
|
6
5
|
attr_accessor :child
|
7
6
|
attr_reader :context
|
8
7
|
|
@@ -13,11 +12,15 @@ module CloudSesame
|
|
13
12
|
|
14
13
|
def child=(object)
|
15
14
|
if object.kind_of? Literal
|
16
|
-
(object.options[:excluded] ||= []) << object.options[:included].delete(object.value
|
15
|
+
(object.options[:excluded] ||= []) << object.options[:included].delete(object.value)
|
17
16
|
end
|
18
17
|
@child = object
|
19
18
|
end
|
20
19
|
|
20
|
+
def <<(object)
|
21
|
+
self.child= object
|
22
|
+
end
|
23
|
+
|
21
24
|
end
|
22
25
|
end
|
23
26
|
end
|
@@ -2,20 +2,18 @@ module CloudSesame
|
|
2
2
|
module Query
|
3
3
|
module AST
|
4
4
|
class SingleExpressionOperator < SingleBranch
|
5
|
+
include DSL::Boost
|
5
6
|
|
6
|
-
# Operator Symbol Writer
|
7
7
|
def self.symbol=(symbol)
|
8
8
|
@symbol = symbol
|
9
9
|
end
|
10
10
|
|
11
|
-
# Operator Symbol Getter
|
12
11
|
def self.symbol
|
13
12
|
@symbol
|
14
13
|
end
|
15
14
|
|
16
15
|
def compile
|
17
|
-
|
18
|
-
"(#{ self.class.symbol } #{ child.compile })" if child
|
16
|
+
"(#{ self.class.symbol }#{ compile_boost } #{ child.compile })" if child
|
19
17
|
end
|
20
18
|
|
21
19
|
end
|
@@ -3,14 +3,22 @@ module CloudSesame
|
|
3
3
|
module AST
|
4
4
|
class Value < Leaf
|
5
5
|
|
6
|
-
|
6
|
+
attr_reader :data
|
7
7
|
|
8
8
|
def initialize(data)
|
9
9
|
@data = data
|
10
10
|
end
|
11
11
|
|
12
12
|
def compile
|
13
|
-
format
|
13
|
+
format data
|
14
|
+
end
|
15
|
+
|
16
|
+
def ==(value)
|
17
|
+
data == value || compile == value
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
compile
|
14
22
|
end
|
15
23
|
|
16
24
|
private
|
@@ -1,13 +1,14 @@
|
|
1
1
|
module CloudSesame
|
2
2
|
module Query
|
3
|
-
|
3
|
+
module Builder
|
4
4
|
include DSL::Base
|
5
5
|
include DSL::FilterQuery
|
6
6
|
include DSL::Page
|
7
7
|
include DSL::Query
|
8
8
|
include DSL::Sort
|
9
|
+
include DSL::Return
|
9
10
|
|
10
|
-
attr_reader :
|
11
|
+
attr_reader :result
|
11
12
|
|
12
13
|
def initialize(default_context, searchable)
|
13
14
|
@context = default_context
|
@@ -18,26 +19,50 @@ module CloudSesame
|
|
18
19
|
@request ||= (clear_result; Node::Request.new context.dup)
|
19
20
|
end
|
20
21
|
|
22
|
+
def response
|
23
|
+
@response ||= search
|
24
|
+
end
|
25
|
+
|
21
26
|
def clear_request
|
22
27
|
@request = nil
|
23
28
|
end
|
24
29
|
|
25
30
|
def clear_result
|
26
|
-
@
|
31
|
+
@response = nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def compile
|
35
|
+
request.compile
|
27
36
|
end
|
28
37
|
|
29
38
|
def inspect
|
30
|
-
"
|
39
|
+
"#<#{ self.class }:#{ object_id } #{ compile }>"
|
31
40
|
end
|
32
41
|
|
33
42
|
# ENDING METHODS
|
34
43
|
# =========================================
|
35
44
|
|
45
|
+
def found
|
46
|
+
response.hits.found
|
47
|
+
end
|
48
|
+
|
49
|
+
def results
|
50
|
+
response.hits.hit
|
51
|
+
end
|
52
|
+
|
53
|
+
def each(&block)
|
54
|
+
results.each &block
|
55
|
+
end
|
56
|
+
|
57
|
+
def map(&block)
|
58
|
+
results.map &block
|
59
|
+
end
|
60
|
+
|
36
61
|
def search
|
37
62
|
compiled = request.compile
|
38
63
|
raise Error::MissingQuery.new("Query or FilterQuery can not be empty!") if !compiled[:query] || compiled[:query].empty?
|
39
64
|
clear_request
|
40
|
-
@
|
65
|
+
@response = client.search compiled
|
41
66
|
end
|
42
67
|
|
43
68
|
private
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module CloudSesame
|
2
|
+
module Query
|
3
|
+
module DSL
|
4
|
+
module Boost
|
5
|
+
|
6
|
+
def compile_boost
|
7
|
+
" boost=#{ @boost }" if @boost
|
8
|
+
end
|
9
|
+
|
10
|
+
def boost(value)
|
11
|
+
@boost = value.to_i
|
12
|
+
return self
|
13
|
+
end
|
14
|
+
|
15
|
+
alias_method :weight, :boost
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -2,43 +2,34 @@ module CloudSesame
|
|
2
2
|
module Query
|
3
3
|
module DSL
|
4
4
|
module FilterQuery
|
5
|
-
include Scope
|
6
5
|
include And
|
7
|
-
include Or
|
8
6
|
include Literal
|
9
|
-
include
|
7
|
+
include Or
|
8
|
+
include Scope
|
9
|
+
include Value
|
10
10
|
|
11
|
-
# { fields: { tags: { excluded: [100] } } }
|
12
11
|
def included?(field, value = nil)
|
13
12
|
(field_options = method_scope.context[:fields][field]) && (
|
14
|
-
(value &&
|
15
|
-
(!value &&
|
13
|
+
(value && field_options_is(:included, field_options, value)) ||
|
14
|
+
(!value && field_options_not_empty_in(:included, field_options))
|
16
15
|
)
|
17
16
|
end
|
18
17
|
|
19
18
|
def excluded?(field, value = nil)
|
20
19
|
(field_options = method_scope.context[:fields][field]) && (
|
21
|
-
(value &&
|
22
|
-
(!value &&
|
20
|
+
(value && field_options_is(:excluded, field_options, value)) ||
|
21
|
+
(!value && field_options_not_empty_in(:excluded, field_options))
|
23
22
|
)
|
24
23
|
end
|
25
24
|
|
26
25
|
private
|
27
26
|
|
28
|
-
def
|
29
|
-
field_options[
|
30
|
-
end
|
31
|
-
|
32
|
-
def field_included_is_not_empty?(field_options)
|
33
|
-
field_options[:included] && !field_options[:included].empty?
|
34
|
-
end
|
35
|
-
|
36
|
-
def field_excludes?(field_options, value)
|
37
|
-
field_options[:excluded] && field_options[:excluded].include?(value)
|
27
|
+
def field_options_is(type, field_options, value)
|
28
|
+
(values = field_options[type]) && values.include?(value)
|
38
29
|
end
|
39
30
|
|
40
|
-
def
|
41
|
-
field_options[
|
31
|
+
def field_options_not_empty_in(type, field_options)
|
32
|
+
field_options[type] && !field_options[type].empty?
|
42
33
|
end
|
43
34
|
|
44
35
|
|
@@ -3,12 +3,45 @@ module CloudSesame
|
|
3
3
|
module DSL
|
4
4
|
module Literal
|
5
5
|
|
6
|
-
#
|
7
|
-
#
|
8
|
-
def literal(
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
# LITERAL: creates a single LITERAL node
|
7
|
+
# =======================================
|
8
|
+
def literal(value)
|
9
|
+
field = method_scope.children.field
|
10
|
+
AST::Literal.new field, value, fields[field]
|
11
|
+
end
|
12
|
+
|
13
|
+
alias_method :l, :literal
|
14
|
+
alias_method :field, :literal
|
15
|
+
|
16
|
+
# NEAR: creates a single NEAR node
|
17
|
+
# =======================================
|
18
|
+
def near(value)
|
19
|
+
create_literal_with_operator AST::Near, value
|
20
|
+
end
|
21
|
+
|
22
|
+
alias_method :n, :near
|
23
|
+
alias_method :sloppy, :near
|
24
|
+
|
25
|
+
# PREFIX: creates a single PREFIX node
|
26
|
+
# =======================================
|
27
|
+
def prefix(value)
|
28
|
+
create_literal_with_operator AST::Prefix, value
|
29
|
+
end
|
30
|
+
|
31
|
+
alias_method :p, :prefix
|
32
|
+
alias_method :start_with, :prefix
|
33
|
+
alias_method :begin_with, :prefix
|
34
|
+
|
35
|
+
# PHRASE: creates a single PHRASE node
|
36
|
+
# =======================================
|
37
|
+
def phrase(value)
|
38
|
+
create_literal_with_operator AST::Phrase, value
|
39
|
+
end
|
40
|
+
|
41
|
+
# TERM: creates a single TERM node
|
42
|
+
# =======================================
|
43
|
+
def term(value)
|
44
|
+
create_literal_with_operator AST::Term, value
|
12
45
|
end
|
13
46
|
|
14
47
|
private
|
@@ -17,10 +50,17 @@ module CloudSesame
|
|
17
50
|
method_context[:fields]
|
18
51
|
end
|
19
52
|
|
53
|
+
def create_literal_with_operator(klass, value)
|
54
|
+
field = method_scope.children.field
|
55
|
+
literal = AST::Literal.new field, value, fields[field]
|
56
|
+
(node = klass.new method_context) << literal
|
57
|
+
node
|
58
|
+
end
|
59
|
+
|
20
60
|
def method_missing(field, *values, &block)
|
21
61
|
if fields && (options = fields[field])
|
22
|
-
method_scope.children.
|
23
|
-
method_scope.children.insert_and_return_children
|
62
|
+
method_scope.children.for_field field
|
63
|
+
method_scope.children.insert_and_return_children values
|
24
64
|
else
|
25
65
|
super
|
26
66
|
end
|
@@ -3,6 +3,8 @@ module CloudSesame
|
|
3
3
|
module DSL
|
4
4
|
module Page
|
5
5
|
|
6
|
+
# CLAUSE: PAGE and SIZE
|
7
|
+
# =========================================
|
6
8
|
def page(input = nil)
|
7
9
|
if input
|
8
10
|
request.page.page = input.to_i
|
@@ -21,6 +23,8 @@ module CloudSesame
|
|
21
23
|
end
|
22
24
|
end
|
23
25
|
|
26
|
+
alias_method :limit, :size
|
27
|
+
|
24
28
|
end
|
25
29
|
end
|
26
30
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module CloudSesame
|
2
|
+
module Query
|
3
|
+
module DSL
|
4
|
+
module Return
|
5
|
+
|
6
|
+
def all_fields
|
7
|
+
request.return_field.value = :all_fields
|
8
|
+
end
|
9
|
+
|
10
|
+
def no_fields
|
11
|
+
request.return_field.value = :no_fields
|
12
|
+
end
|
13
|
+
|
14
|
+
def score
|
15
|
+
request.return_field.value = :score
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module CloudSesame
|
2
|
+
module Query
|
3
|
+
module DSL
|
4
|
+
module Value
|
5
|
+
|
6
|
+
# VALUE DSL
|
7
|
+
# =======================================
|
8
|
+
|
9
|
+
# DATE
|
10
|
+
# =======================================
|
11
|
+
def date(date)
|
12
|
+
AST::DateValue.new date
|
13
|
+
end
|
14
|
+
|
15
|
+
alias_method :d, :date
|
16
|
+
|
17
|
+
# RANGE
|
18
|
+
# =======================================
|
19
|
+
def range(range = nil)
|
20
|
+
AST::RangeValue.new range
|
21
|
+
end
|
22
|
+
|
23
|
+
alias_method :r, :range
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -34,6 +34,10 @@ module CloudSesame
|
|
34
34
|
@sort ||= Sort.new(context[:sort, true])
|
35
35
|
end
|
36
36
|
|
37
|
+
def return_field
|
38
|
+
@return ||= Return.new(context[:return, true])
|
39
|
+
end
|
40
|
+
|
37
41
|
# EVALUATION
|
38
42
|
# =========================================
|
39
43
|
|
@@ -44,7 +48,8 @@ module CloudSesame
|
|
44
48
|
query_parser,
|
45
49
|
filter_query,
|
46
50
|
page,
|
47
|
-
sort
|
51
|
+
sort,
|
52
|
+
return_field
|
48
53
|
].each_with_object({}) do |node, compiled|
|
49
54
|
compiled.merge!(node.compile || {})
|
50
55
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module CloudSesame
|
2
|
+
module Query
|
3
|
+
module Node
|
4
|
+
class Return < Abstract
|
5
|
+
|
6
|
+
attr_accessor :value
|
7
|
+
|
8
|
+
def compile
|
9
|
+
{ return: format(value) } if value
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def format(value)
|
15
|
+
value.to_s.gsub(/^_?/, '_')
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|