elasticquery 0.1.2 → 0.1.3
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/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
|