elasticquery 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +12 -0
  3. data/README.md +151 -70
  4. data/Rakefile +1 -9
  5. data/elasticquery.gemspec +2 -2
  6. data/lib/elasticquery.rb +1 -0
  7. data/lib/elasticquery/base.rb +6 -48
  8. data/lib/elasticquery/builder.rb +74 -17
  9. data/lib/elasticquery/es.rb +32 -0
  10. data/lib/elasticquery/filters/base.rb +4 -0
  11. data/lib/elasticquery/filters/exists.rb +24 -0
  12. data/lib/elasticquery/filters/not.rb +7 -11
  13. data/lib/elasticquery/filters/range.rb +3 -7
  14. data/lib/elasticquery/filters/term.rb +4 -28
  15. data/lib/elasticquery/filters/terms.rb +23 -0
  16. data/lib/elasticquery/queries/base.rb +16 -0
  17. data/lib/elasticquery/queries/multi_match.rb +34 -0
  18. data/lib/elasticquery/query.rb +25 -36
  19. data/lib/elasticquery/version.rb +1 -1
  20. data/test/base_test.rb +4 -4
  21. data/test/builder_test.rb +24 -8
  22. data/test/es_test.rb +23 -0
  23. data/test/filters/exists_test.rb +30 -0
  24. data/test/filters/not_test.rb +23 -10
  25. data/test/filters/range_test.rb +10 -11
  26. data/test/filters/term_test.rb +6 -7
  27. data/test/filters/terms_test.rb +50 -0
  28. data/test/integration/chainable_call_test.rb +6 -6
  29. data/test/integration/exists_case_test.rb +56 -0
  30. data/test/integration/not_case_test.rb +11 -5
  31. data/test/integration/queries_inheritence_test.rb +12 -4
  32. data/test/integration/range_case_test.rb +4 -2
  33. data/test/integration/search_case_test.rb +20 -11
  34. data/test/integration/term_case_test.rb +4 -2
  35. data/test/integration/terms_case_test.rb +49 -0
  36. data/test/queries/multi_match_test.rb +49 -0
  37. data/test/query_test.rb +40 -40
  38. metadata +26 -27
  39. data/lib/elasticquery/filters/search.rb +0 -54
  40. data/test/filters/search_test.rb +0 -62
@@ -1,4 +1,4 @@
1
1
  module Elasticquery
2
2
  # Current gem version
3
- VERSION = "0.1.2"
3
+ VERSION = "0.1.3".freeze
4
4
  end
@@ -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.filters
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.filters.first.call
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 test_filters_as_array
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.filters.count
50
+ assert_equal 2, query.rules.count
51
51
  end
52
52
 
53
53
  def test_should_execute_code_in_instance_context
@@ -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 test_defined_instances_return_sel
26
- assert_equal self, term
29
+ def test_have_multi_match
30
+ assert_respond_to self, :multi_match
27
31
  end
28
32
 
29
- def test_push_hash_term_to_query
30
- term a: 1
31
- search b: 2
32
- term c: 3
33
- assert_equal 3, query.size
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
@@ -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
@@ -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 = {query: {filtered: {filter: {and: [{term: {a: 1, b: 2}}]}}}}
24
- filter_class.expect :to_hash, expected
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 = {query: {filtered: {filter: {and: [{range: {a: {lte: 1}}}]}}}}
41
- filter_class.expect :to_hash, expected
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
 
@@ -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({query: {filtered: {filter: {and: [{range: {year: {lte: 1, gte: 0}}}]}}}}, filter.to_hash)
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({query: {filtered: {filter: {and: [{range: {year: {lte: 1}}}]}}}}, filter.to_hash)
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({query: {filtered: {filter: {and: [{range: {year: {_cache: true, lte: 1}}}]}}}}, filter.to_hash)
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({query: {filtered: {filter: {and: [{range: {year: {lte: 1, gte: 0, execution: "fielddata"}}}]}}}}, filter.to_hash)
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({query: {filtered: {filter: {and: [{range: {year: { _cache: true, lte: 1}}}]}}}}, filter.to_hash)
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
@@ -1,7 +1,7 @@
1
1
  require "test_helper"
2
2
  require "elasticquery/filters/term"
3
3
 
4
- class TestTermfilter < MiniTest::Test
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({query: {filtered: {filter: {and: [{term: {a: 1, _cache: true}}]}}}}, filter.to_hash)
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({query: {filtered: {filter: {and: [{term: {a: 1}}]}}}}, filter.to_hash)
38
+ assert_equal({term: {a: 1}}, filter.to_hash)
39
39
  end
40
40
 
41
- def test_to_hash_is_empty_if_invalid
42
- filter = Elasticquery::Filters::Term.new
43
- refute filter.valid?
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
- term.not id: params[:id]
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
- term published: true
14
- range.not :age, lte: params[:year]
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
- term.not
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