elasticquery 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.md +12 -0
- data/README.md +151 -70
- data/Rakefile +1 -9
- data/elasticquery.gemspec +2 -2
- data/lib/elasticquery.rb +1 -0
- data/lib/elasticquery/base.rb +6 -48
- data/lib/elasticquery/builder.rb +74 -17
- data/lib/elasticquery/es.rb +32 -0
- data/lib/elasticquery/filters/base.rb +4 -0
- data/lib/elasticquery/filters/exists.rb +24 -0
- data/lib/elasticquery/filters/not.rb +7 -11
- data/lib/elasticquery/filters/range.rb +3 -7
- data/lib/elasticquery/filters/term.rb +4 -28
- data/lib/elasticquery/filters/terms.rb +23 -0
- data/lib/elasticquery/queries/base.rb +16 -0
- data/lib/elasticquery/queries/multi_match.rb +34 -0
- data/lib/elasticquery/query.rb +25 -36
- data/lib/elasticquery/version.rb +1 -1
- data/test/base_test.rb +4 -4
- data/test/builder_test.rb +24 -8
- data/test/es_test.rb +23 -0
- data/test/filters/exists_test.rb +30 -0
- data/test/filters/not_test.rb +23 -10
- data/test/filters/range_test.rb +10 -11
- data/test/filters/term_test.rb +6 -7
- data/test/filters/terms_test.rb +50 -0
- data/test/integration/chainable_call_test.rb +6 -6
- data/test/integration/exists_case_test.rb +56 -0
- data/test/integration/not_case_test.rb +11 -5
- data/test/integration/queries_inheritence_test.rb +12 -4
- data/test/integration/range_case_test.rb +4 -2
- data/test/integration/search_case_test.rb +20 -11
- data/test/integration/term_case_test.rb +4 -2
- data/test/integration/terms_case_test.rb +49 -0
- data/test/queries/multi_match_test.rb +49 -0
- data/test/query_test.rb +40 -40
- metadata +26 -27
- data/lib/elasticquery/filters/search.rb +0 -54
- data/test/filters/search_test.rb +0 -62
data/lib/elasticquery/version.rb
CHANGED
data/test/base_test.rb
CHANGED
@@ -21,7 +21,7 @@ class TestBase < MiniTest::Test
|
|
21
21
|
|
22
22
|
def test_filters_is_empty_by_default
|
23
23
|
query = Elasticquery::Base.new
|
24
|
-
assert_empty query.
|
24
|
+
assert_empty query.rules
|
25
25
|
end
|
26
26
|
|
27
27
|
def test_extract_params
|
@@ -34,20 +34,20 @@ class TestBase < MiniTest::Test
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def test_filters_proc
|
37
|
-
assert_equal 2, @query.
|
37
|
+
assert_equal 2, @query.rules.first.call
|
38
38
|
end
|
39
39
|
|
40
40
|
def test_should_have_term_rule_included
|
41
41
|
assert_respond_to @query, :term
|
42
42
|
end
|
43
43
|
|
44
|
-
def
|
44
|
+
def test_rules_as_array
|
45
45
|
klass = Class.new(Elasticquery::Base)
|
46
46
|
klass.filtered { 1 + 1 }
|
47
47
|
klass.filtered { 2 + 2 }
|
48
48
|
|
49
49
|
query = klass.new
|
50
|
-
assert_equal 2, query.
|
50
|
+
assert_equal 2, query.rules.count
|
51
51
|
end
|
52
52
|
|
53
53
|
def test_should_execute_code_in_instance_context
|
data/test/builder_test.rb
CHANGED
@@ -18,24 +18,40 @@ class TestAllBaseQueries < MiniTest::Test
|
|
18
18
|
assert_respond_to self, :term
|
19
19
|
end
|
20
20
|
|
21
|
+
def test_have_terms
|
22
|
+
assert_respond_to self, :terms
|
23
|
+
end
|
24
|
+
|
21
25
|
def test_have_search
|
22
26
|
assert_respond_to self, :search
|
23
27
|
end
|
24
28
|
|
25
|
-
def
|
26
|
-
|
29
|
+
def test_have_multi_match
|
30
|
+
assert_respond_to self, :multi_match
|
27
31
|
end
|
28
32
|
|
29
|
-
def
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
33
|
+
def test_have_range
|
34
|
+
assert_respond_to self, :range
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_have_range
|
38
|
+
assert_respond_to self, :exists
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_have_range
|
42
|
+
assert_respond_to self, :with
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_defined_instances_return_self
|
46
|
+
@query.expect :push_filter, true, [Elasticquery::Filters::Term]
|
47
|
+
|
48
|
+
assert_equal self, filters { term(a: 1) }
|
49
|
+
assert @query.verify
|
34
50
|
end
|
35
51
|
|
36
52
|
private
|
37
53
|
|
38
54
|
def clear_query
|
39
|
-
@query =
|
55
|
+
@query = MiniTest::Mock.new
|
40
56
|
end
|
41
57
|
end
|
data/test/es_test.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'elasticsearch/model'
|
3
|
+
require 'elasticquery/es'
|
4
|
+
|
5
|
+
class Searchable
|
6
|
+
include Elasticsearch::Model
|
7
|
+
end
|
8
|
+
|
9
|
+
class NotSearchable
|
10
|
+
end
|
11
|
+
|
12
|
+
class TestEs < MiniTest::Test
|
13
|
+
def setup
|
14
|
+
Searchable.extend Elasticquery::Es
|
15
|
+
@model = Searchable
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_raise_error_for_not_searchable_class
|
19
|
+
assert_raises Elasticquery::EsNotSupported do
|
20
|
+
NotSearchable.extend Elasticquery::Es
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "elasticquery/filters/exists"
|
3
|
+
|
4
|
+
class TestExistsFilter < MiniTest::Test
|
5
|
+
|
6
|
+
def test_valid_filter_has_present_field_name
|
7
|
+
filter = Elasticquery::Filters::Exists.new "user"
|
8
|
+
assert filter.valid?
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_invalid_filter_has_blank_field_name
|
12
|
+
filter = Elasticquery::Filters::Exists.new ""
|
13
|
+
refute filter.valid?
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_invalid_filter_has_no_field
|
17
|
+
filter = Elasticquery::Filters::Exists.new
|
18
|
+
refute filter.valid?
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_to_hash_returns_elastic_rule
|
22
|
+
filter = Elasticquery::Filters::Exists.new "user"
|
23
|
+
assert_equal filter.to_hash, {exists: {field: "user"}}
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_to_not_hash_returns_missing
|
27
|
+
filter = Elasticquery::Filters::Exists.new "user"
|
28
|
+
assert_equal filter.to_not_hash, {missing: {field: "user"}}
|
29
|
+
end
|
30
|
+
end
|
data/test/filters/not_test.rb
CHANGED
@@ -17,37 +17,50 @@ class NotFilter < MiniTest::Test
|
|
17
17
|
assert_instance_of Proc, @filter.to_hash
|
18
18
|
end
|
19
19
|
|
20
|
+
def test_valid_return_proc
|
21
|
+
assert_instance_of Proc, @filter.valid?
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_valid_proxy_to_previous_filter
|
25
|
+
filter_class = MiniTest::Mock.new
|
26
|
+
filter_class.expect :valid?, true
|
27
|
+
previous_filter = MiniTest::Mock.new
|
28
|
+
previous_filter.expect :dup_with, filter_class, [{a: 1}]
|
29
|
+
|
30
|
+
@filters = [previous_filter, "current-not-filter"]
|
31
|
+
assert instance_exec &@filter.valid?
|
32
|
+
|
33
|
+
assert filter_class.verify
|
34
|
+
assert previous_filter.verify
|
35
|
+
end
|
36
|
+
|
20
37
|
def test_to_hash_change_last_term_filter_value
|
21
38
|
filter_class = MiniTest::Mock.new
|
22
39
|
filter_class.expect :valid?, true
|
23
|
-
expected = {
|
24
|
-
filter_class.expect :
|
40
|
+
expected = {not: {filter: {term: {a: 1, b: 2}}}}
|
41
|
+
filter_class.expect :to_not_hash, expected
|
25
42
|
previous_filter = MiniTest::Mock.new
|
26
43
|
previous_filter.expect :dup_with, filter_class, [{a: 1}]
|
27
44
|
|
28
|
-
@filters = [previous_filter]
|
45
|
+
@filters = [previous_filter, "current-not-filter"]
|
29
46
|
result = instance_exec &@filter.to_hash
|
30
|
-
expected = {query: {filtered: {filter: {and: [{not: {filter: {term: {a: 1, b: 2}}}}]}}}}
|
31
47
|
assert_equal result, expected
|
32
48
|
|
33
|
-
assert filter_class.verify
|
34
49
|
assert previous_filter.verify
|
35
50
|
end
|
36
51
|
|
37
52
|
def test_to_hash_change_last_range_filter_value
|
38
53
|
filter_class = MiniTest::Mock.new
|
39
54
|
filter_class.expect :valid?, true
|
40
|
-
expected = {
|
41
|
-
filter_class.expect :
|
55
|
+
expected = {not: {filter: {range: {a: {lte: 1}}}}}
|
56
|
+
filter_class.expect :to_not_hash, expected
|
42
57
|
previous_filter = MiniTest::Mock.new
|
43
58
|
previous_filter.expect :dup_with, filter_class, [{a: 1}]
|
44
59
|
|
45
|
-
@filters = [previous_filter]
|
60
|
+
@filters = [previous_filter, "current-not-filter"]
|
46
61
|
result = instance_exec &@filter.to_hash
|
47
|
-
expected = {query: {filtered: {filter: {and: [{not: {filter: {range: {a: {lte: 1}}}}}]}}}}
|
48
62
|
assert_equal result, expected
|
49
63
|
|
50
|
-
assert filter_class.verify
|
51
64
|
assert previous_filter.verify
|
52
65
|
end
|
53
66
|
|
data/test/filters/range_test.rb
CHANGED
@@ -29,33 +29,27 @@ class RangeFilter < MiniTest::Test
|
|
29
29
|
|
30
30
|
def test_to_hash_should_return_query
|
31
31
|
filter = Elasticquery::Filters::Range.new :year, lte: 1, gte: 0
|
32
|
-
assert_equal({
|
32
|
+
assert_equal({range: {year: {lte: 1, gte: 0}}}, filter.to_hash)
|
33
33
|
end
|
34
34
|
|
35
35
|
def test_to_hash_with_one_param
|
36
36
|
filter = Elasticquery::Filters::Range.new :year, lte: 1
|
37
|
-
assert_equal({
|
37
|
+
assert_equal({range: {year: {lte: 1}}}, filter.to_hash)
|
38
38
|
end
|
39
39
|
|
40
40
|
def test_to_hash_support_cache_option
|
41
41
|
filter = Elasticquery::Filters::Range.new :year, lte: 1, _cache: true
|
42
|
-
assert_equal({
|
42
|
+
assert_equal({range: {year: {_cache: true, lte: 1}}}, filter.to_hash)
|
43
43
|
end
|
44
44
|
|
45
45
|
def test_to_hash_support_execution_option
|
46
46
|
filter = Elasticquery::Filters::Range.new :year, lte: 1, gte: 0, execution: "fielddata"
|
47
|
-
assert_equal({
|
47
|
+
assert_equal({range: {year: {lte: 1, gte: 0, execution: "fielddata"}}}, filter.to_hash)
|
48
48
|
end
|
49
49
|
|
50
50
|
def test_to_hash_skip_unnesessary_options
|
51
51
|
filter = Elasticquery::Filters::Range.new :year, lte: 1, _cache: true, extra: false
|
52
|
-
assert_equal({
|
53
|
-
end
|
54
|
-
|
55
|
-
def test_to_hash_is_empty_if_invalid
|
56
|
-
filter = Elasticquery::Filters::Range.new "year"
|
57
|
-
refute filter.valid?
|
58
|
-
assert_equal filter.to_hash, {}
|
52
|
+
assert_equal({range: {year: { _cache: true, lte: 1}}}, filter.to_hash)
|
59
53
|
end
|
60
54
|
|
61
55
|
def test_dup_with_return_new_range_filter
|
@@ -63,4 +57,9 @@ class RangeFilter < MiniTest::Test
|
|
63
57
|
new_filter = filter.dup_with "month", gte: 12
|
64
58
|
assert_kind_of Elasticquery::Filters::Range, new_filter
|
65
59
|
end
|
60
|
+
|
61
|
+
def test_not_hash_to_returns_terms_not
|
62
|
+
filter = Elasticquery::Filters::Range.new :year, lte: 1
|
63
|
+
assert_equal({not: {filter: {range: {year: {lte: 1}}}}}, filter.to_not_hash)
|
64
|
+
end
|
66
65
|
end
|
data/test/filters/term_test.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require "test_helper"
|
2
2
|
require "elasticquery/filters/term"
|
3
3
|
|
4
|
-
class
|
4
|
+
class TestTermFilter < MiniTest::Test
|
5
5
|
|
6
6
|
def test_valid_filter_should_have_one_key
|
7
7
|
filter = Elasticquery::Filters::Term.new a: 1
|
@@ -30,18 +30,17 @@ class TestTermfilter < MiniTest::Test
|
|
30
30
|
|
31
31
|
def test_to_hash_should_pass__cache_options
|
32
32
|
filter = Elasticquery::Filters::Term.new a: 1, _cache: true
|
33
|
-
assert_equal({
|
33
|
+
assert_equal({term: {a: 1, _cache: true}}, filter.to_hash)
|
34
34
|
end
|
35
35
|
|
36
36
|
def test_to_hash_should_return_es_query
|
37
37
|
filter = Elasticquery::Filters::Term.new a: 1
|
38
|
-
assert_equal({
|
38
|
+
assert_equal({term: {a: 1}}, filter.to_hash)
|
39
39
|
end
|
40
40
|
|
41
|
-
def
|
42
|
-
filter = Elasticquery::Filters::Term.new
|
43
|
-
|
44
|
-
assert_equal filter.to_hash, {}
|
41
|
+
def test_not_to_hash_should_return_terms_not_query
|
42
|
+
filter = Elasticquery::Filters::Term.new a: 1
|
43
|
+
assert_equal({not: {filter: {term: {a: 1}}}}, filter.to_not_hash)
|
45
44
|
end
|
46
45
|
|
47
46
|
def test_dup_with_return_new_term_filter
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "elasticquery/filters/terms"
|
3
|
+
|
4
|
+
class TestTermsFilter < MiniTest::Test
|
5
|
+
|
6
|
+
def test_valid_filter_should_have_one_key
|
7
|
+
filter = Elasticquery::Filters::Terms.new a: 1
|
8
|
+
assert filter.valid?
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_invalid_filter_should_have_no_keys
|
12
|
+
filter = Elasticquery::Filters::Terms.new
|
13
|
+
refute filter.valid?
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_valid_filter_should_have_2_and_more_keys
|
17
|
+
filter = Elasticquery::Filters::Terms.new a: 1, b: 2
|
18
|
+
assert filter.valid?
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_valid_filter_could_have_cache_option
|
22
|
+
filter = Elasticquery::Filters::Terms.new a: 1, _cache: false
|
23
|
+
assert filter.valid?
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_invalid_with_all_blank_values
|
27
|
+
filter = Elasticquery::Filters::Terms.new a: "", b: nil
|
28
|
+
refute filter.valid?
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_valid_filter_could_have_execution_option
|
32
|
+
filter = Elasticquery::Filters::Terms.new a: [1,2], b: 2, execution: "or"
|
33
|
+
assert filter.valid?
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_to_hash_should_pass_all_valid_conditions
|
37
|
+
filter = Elasticquery::Filters::Terms.new a: 42, b: "42"
|
38
|
+
assert_equal({terms: {a: 42, b: "42"}}, filter.to_hash)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_to_not_hash_should_returns_terms_not_condition
|
42
|
+
filter = Elasticquery::Filters::Terms.new a: 42, b: "42"
|
43
|
+
assert_equal({not: {filter: {terms: {a: 42, b: "42"}}}}, filter.to_not_hash)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_to_hash_should_skip_blank_values
|
47
|
+
filter = Elasticquery::Filters::Terms.new a: 42, b: "", execution: "bool"
|
48
|
+
assert_equal({terms: {a: 42, execution: "bool"}}, filter.to_hash)
|
49
|
+
end
|
50
|
+
end
|
@@ -8,23 +8,23 @@ class TestChainableCalls < MiniTest::Test
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def test_sign_call_return_itself
|
11
|
-
assert_kind_of Elasticquery::Base, @query.term(a: 1)
|
11
|
+
assert_kind_of Elasticquery::Base, @query.filters.term(a: 1)
|
12
12
|
end
|
13
13
|
|
14
14
|
def test_apply_query
|
15
|
-
query = @query.term(a: 1).term(b: 3)
|
15
|
+
query = @query.filters.term(a: 1).term(b: 3)
|
16
16
|
assert_equal query.build, query: {filtered: {filter: {and: [{term: {a: 1}}, {term: {b: 3}}]}}}
|
17
17
|
end
|
18
18
|
|
19
19
|
def test_with_not_filter
|
20
|
-
query = @query.search("hi").term.not(a: 1, _cache: true)
|
21
|
-
assert_equal query.build, {query: {filtered: {query: {multi_match: {fields: "_all", operator: "and", type: "best_fields", query: "hi"}}, filter: {and: [{not: {filter: {term: {a: 1, _cache: true}}}}]}}}}
|
20
|
+
query = @query.queries.search("hi").filters.term.not(a: 1, _cache: true)
|
21
|
+
assert_equal query.build, {query: {filtered: {query: {bool: {must: [{multi_match: {fields: "_all", operator: "and", type: "best_fields", query: "hi"}}]}}, filter: {and: [{not: {filter: {term: {a: 1, _cache: true}}}}]}}}}
|
22
22
|
end
|
23
23
|
|
24
24
|
def test_apply_kinds_of_query
|
25
|
-
query = @query.term(a: 1).search("hello", operator: "or").build
|
25
|
+
query = @query.filters.term(a: 1).queries.search("hello", operator: "or").build
|
26
26
|
terms = query[:query][:filtered][:filter][:and]
|
27
|
-
search = query[:query][:filtered][:query][:multi_match]
|
27
|
+
search = query[:query][:filtered][:query][:bool][:must][0][:multi_match]
|
28
28
|
assert_equal terms, [{term: {a: 1}}]
|
29
29
|
assert_equal search, {fields: "_all", operator: "or", type: "best_fields", query: "hello"}
|
30
30
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "elasticquery"
|
3
|
+
|
4
|
+
class TestExistsCase < MiniTest::Test
|
5
|
+
class UserQuery < Elasticquery::Base
|
6
|
+
filtered do |params|
|
7
|
+
queries do
|
8
|
+
search params[:query]
|
9
|
+
end
|
10
|
+
filters do
|
11
|
+
exists params[:required]
|
12
|
+
with.not params[:missing]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class SimpleUserQuery < Elasticquery::Base
|
18
|
+
filtered do |params|
|
19
|
+
filters do
|
20
|
+
without params[:missing]
|
21
|
+
missing params[:another_missing]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_simple_setup
|
27
|
+
params = {query: "Mark", required: "name"}
|
28
|
+
actual = UserQuery.new(params).build
|
29
|
+
|
30
|
+
expected_queries = [{multi_match: {fields: "_all", operator: "and", type: "best_fields", query: "Mark"}}]
|
31
|
+
expected_filters = [{exists: {field: "name"}}]
|
32
|
+
assert_equal expected_queries, actual[:query][:filtered][:query][:bool][:must]
|
33
|
+
assert_equal expected_filters, actual[:query][:filtered][:filter][:and]
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_exists_not_use_missing
|
37
|
+
params = {query: "Mark", missing: "deleted_at"}
|
38
|
+
actual = UserQuery.new(params).build
|
39
|
+
expected_filters = [{missing: {field: "deleted_at"}}]
|
40
|
+
assert_equal expected_filters, actual[:query][:filtered][:filter][:and]
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_without_support
|
44
|
+
params = {missing: "deleted_at"}
|
45
|
+
actual = SimpleUserQuery.new(params).build
|
46
|
+
expected_filters = [{missing: {field: "deleted_at"}}]
|
47
|
+
assert_equal expected_filters, actual[:query][:filtered][:filter][:and]
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_missing_support
|
51
|
+
params = {another_missing: "deleted_at"}
|
52
|
+
actual = SimpleUserQuery.new(params).build
|
53
|
+
expected_filters = [{missing: {field: "deleted_at"}}]
|
54
|
+
assert_equal expected_filters, actual[:query][:filtered][:filter][:and]
|
55
|
+
end
|
56
|
+
end
|
@@ -4,20 +4,26 @@ require "elasticquery"
|
|
4
4
|
class TestNotCase < MiniTest::Test
|
5
5
|
class PostQuery < Elasticquery::Base
|
6
6
|
filtered do |param|
|
7
|
-
|
7
|
+
filters do
|
8
|
+
term.not id: params[:id]
|
9
|
+
end
|
8
10
|
end
|
9
11
|
end
|
10
12
|
|
11
13
|
class PostRangeQuery < Elasticquery::Base
|
12
14
|
filtered do |param|
|
13
|
-
|
14
|
-
|
15
|
+
filters do
|
16
|
+
term published: true
|
17
|
+
range.not :age, lte: params[:year], _cache: false
|
18
|
+
end
|
15
19
|
end
|
16
20
|
end
|
17
21
|
|
18
22
|
class InvalidQuery < Elasticquery::Base
|
19
23
|
filtered do |param|
|
20
|
-
|
24
|
+
filters do
|
25
|
+
term.not
|
26
|
+
end
|
21
27
|
end
|
22
28
|
end
|
23
29
|
|
@@ -36,7 +42,7 @@ class TestNotCase < MiniTest::Test
|
|
36
42
|
def test_range_case
|
37
43
|
params = {year: 2015}
|
38
44
|
actual = PostRangeQuery.new(params).build
|
39
|
-
expected = [{term: {published: true}}, {not: {filter: {range: {age: {lte: 2015}}}}}]
|
45
|
+
expected = [{term: {published: true}}, {not: {filter: {range: {age: {lte: 2015, _cache: false}}}}}]
|
40
46
|
assert_equal expected, actual[:query][:filtered][:filter][:and]
|
41
47
|
end
|
42
48
|
end
|