CloudSesame 0.1.5 → 0.1.6
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 +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
|