load_balanced_tire 0.1
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.
- data/.gitignore +14 -0
- data/.travis.yml +29 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE +20 -0
- data/README.markdown +760 -0
- data/Rakefile +78 -0
- data/examples/rails-application-template.rb +249 -0
- data/examples/tire-dsl.rb +876 -0
- data/lib/tire.rb +55 -0
- data/lib/tire/alias.rb +296 -0
- data/lib/tire/configuration.rb +30 -0
- data/lib/tire/dsl.rb +43 -0
- data/lib/tire/http/client.rb +62 -0
- data/lib/tire/http/clients/curb.rb +61 -0
- data/lib/tire/http/clients/faraday.rb +71 -0
- data/lib/tire/http/response.rb +27 -0
- data/lib/tire/index.rb +361 -0
- data/lib/tire/logger.rb +60 -0
- data/lib/tire/model/callbacks.rb +40 -0
- data/lib/tire/model/import.rb +26 -0
- data/lib/tire/model/indexing.rb +128 -0
- data/lib/tire/model/naming.rb +100 -0
- data/lib/tire/model/percolate.rb +99 -0
- data/lib/tire/model/persistence.rb +71 -0
- data/lib/tire/model/persistence/attributes.rb +143 -0
- data/lib/tire/model/persistence/finders.rb +66 -0
- data/lib/tire/model/persistence/storage.rb +69 -0
- data/lib/tire/model/search.rb +307 -0
- data/lib/tire/results/collection.rb +114 -0
- data/lib/tire/results/item.rb +86 -0
- data/lib/tire/results/pagination.rb +54 -0
- data/lib/tire/rubyext/hash.rb +8 -0
- data/lib/tire/rubyext/ruby_1_8.rb +7 -0
- data/lib/tire/rubyext/symbol.rb +11 -0
- data/lib/tire/search.rb +188 -0
- data/lib/tire/search/facet.rb +74 -0
- data/lib/tire/search/filter.rb +28 -0
- data/lib/tire/search/highlight.rb +37 -0
- data/lib/tire/search/query.rb +186 -0
- data/lib/tire/search/scan.rb +114 -0
- data/lib/tire/search/script_field.rb +23 -0
- data/lib/tire/search/sort.rb +25 -0
- data/lib/tire/tasks.rb +135 -0
- data/lib/tire/utils.rb +17 -0
- data/lib/tire/version.rb +22 -0
- data/test/fixtures/articles/1.json +1 -0
- data/test/fixtures/articles/2.json +1 -0
- data/test/fixtures/articles/3.json +1 -0
- data/test/fixtures/articles/4.json +1 -0
- data/test/fixtures/articles/5.json +1 -0
- data/test/integration/active_model_indexing_test.rb +51 -0
- data/test/integration/active_model_searchable_test.rb +114 -0
- data/test/integration/active_record_searchable_test.rb +446 -0
- data/test/integration/boolean_queries_test.rb +43 -0
- data/test/integration/count_test.rb +34 -0
- data/test/integration/custom_score_queries_test.rb +88 -0
- data/test/integration/dis_max_queries_test.rb +68 -0
- data/test/integration/dsl_search_test.rb +22 -0
- data/test/integration/explanation_test.rb +44 -0
- data/test/integration/facets_test.rb +259 -0
- data/test/integration/filtered_queries_test.rb +66 -0
- data/test/integration/filters_test.rb +63 -0
- data/test/integration/fuzzy_queries_test.rb +20 -0
- data/test/integration/highlight_test.rb +64 -0
- data/test/integration/index_aliases_test.rb +122 -0
- data/test/integration/index_mapping_test.rb +43 -0
- data/test/integration/index_store_test.rb +96 -0
- data/test/integration/index_update_document_test.rb +111 -0
- data/test/integration/mongoid_searchable_test.rb +309 -0
- data/test/integration/percolator_test.rb +111 -0
- data/test/integration/persistent_model_test.rb +130 -0
- data/test/integration/prefix_query_test.rb +43 -0
- data/test/integration/query_return_version_test.rb +70 -0
- data/test/integration/query_string_test.rb +52 -0
- data/test/integration/range_queries_test.rb +36 -0
- data/test/integration/reindex_test.rb +46 -0
- data/test/integration/results_test.rb +39 -0
- data/test/integration/scan_test.rb +56 -0
- data/test/integration/script_fields_test.rb +38 -0
- data/test/integration/sort_test.rb +36 -0
- data/test/integration/text_query_test.rb +39 -0
- data/test/models/active_model_article.rb +31 -0
- data/test/models/active_model_article_with_callbacks.rb +49 -0
- data/test/models/active_model_article_with_custom_document_type.rb +7 -0
- data/test/models/active_model_article_with_custom_index_name.rb +7 -0
- data/test/models/active_record_models.rb +122 -0
- data/test/models/article.rb +15 -0
- data/test/models/mongoid_models.rb +97 -0
- data/test/models/persistent_article.rb +11 -0
- data/test/models/persistent_article_in_namespace.rb +12 -0
- data/test/models/persistent_article_with_casting.rb +28 -0
- data/test/models/persistent_article_with_defaults.rb +11 -0
- data/test/models/persistent_articles_with_custom_index_name.rb +10 -0
- data/test/models/supermodel_article.rb +17 -0
- data/test/models/validated_model.rb +11 -0
- data/test/test_helper.rb +93 -0
- data/test/unit/active_model_lint_test.rb +17 -0
- data/test/unit/configuration_test.rb +74 -0
- data/test/unit/http_client_test.rb +76 -0
- data/test/unit/http_response_test.rb +49 -0
- data/test/unit/index_alias_test.rb +275 -0
- data/test/unit/index_test.rb +894 -0
- data/test/unit/logger_test.rb +125 -0
- data/test/unit/model_callbacks_test.rb +116 -0
- data/test/unit/model_import_test.rb +71 -0
- data/test/unit/model_persistence_test.rb +528 -0
- data/test/unit/model_search_test.rb +913 -0
- data/test/unit/results_collection_test.rb +281 -0
- data/test/unit/results_item_test.rb +162 -0
- data/test/unit/rubyext_test.rb +66 -0
- data/test/unit/search_facet_test.rb +153 -0
- data/test/unit/search_filter_test.rb +42 -0
- data/test/unit/search_highlight_test.rb +46 -0
- data/test/unit/search_query_test.rb +301 -0
- data/test/unit/search_scan_test.rb +113 -0
- data/test/unit/search_script_field_test.rb +26 -0
- data/test/unit/search_sort_test.rb +50 -0
- data/test/unit/search_test.rb +499 -0
- data/test/unit/tire_test.rb +126 -0
- data/tire.gemspec +90 -0
- metadata +549 -0
@@ -0,0 +1,153 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Tire::Search
|
4
|
+
|
5
|
+
class FacetTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Facet" do
|
8
|
+
|
9
|
+
should "be serialized to JSON" do
|
10
|
+
assert_respond_to Facet.new('foo'), :to_json
|
11
|
+
end
|
12
|
+
|
13
|
+
context "generally" do
|
14
|
+
|
15
|
+
should "encode facets with defaults for current query" do
|
16
|
+
assert_equal( { :foo => { :terms => {:field=>'bar',:size=>10,:all_terms=>false} } }.to_json,
|
17
|
+
Facet.new('foo').terms(:bar).to_json )
|
18
|
+
end
|
19
|
+
|
20
|
+
should "encode facets as global" do
|
21
|
+
assert_equal( { :foo => { :terms => {:field=>'bar',:size=>10,:all_terms=>false}, :global => true } }.to_json,
|
22
|
+
Facet.new('foo', :global => true).terms(:bar).to_json )
|
23
|
+
end
|
24
|
+
|
25
|
+
should "pass options to facets" do
|
26
|
+
payload = Facet.new('foo', :facet_filter => { :term => { :account_id => 'foo' } }).terms(:bar).to_hash
|
27
|
+
|
28
|
+
assert_not_nil payload['foo'][:facet_filter]
|
29
|
+
assert_equal( { :term => { :account_id => 'foo' } },
|
30
|
+
payload['foo'][:facet_filter] )
|
31
|
+
end
|
32
|
+
|
33
|
+
should "encode facet options" do
|
34
|
+
assert_equal( { :foo => { :terms => {:field=>'bar',:size=>5,:all_terms=>false} } }.to_json,
|
35
|
+
Facet.new('foo').terms(:bar, :size => 5).to_json )
|
36
|
+
end
|
37
|
+
|
38
|
+
should "encode facets when passed as a block" do
|
39
|
+
f = Facet.new('foo') do
|
40
|
+
terms :bar
|
41
|
+
end
|
42
|
+
assert_equal( { :foo => { :terms => {:field=>'bar',:size=>10,:all_terms=>false} } }.to_json, f.to_json )
|
43
|
+
end
|
44
|
+
|
45
|
+
should "encode facets when passed as a block, using variables from outer scope" do
|
46
|
+
def foo; 'bar'; end
|
47
|
+
|
48
|
+
f = Facet.new('foo') do |facet|
|
49
|
+
facet.terms foo, :size => 20
|
50
|
+
end
|
51
|
+
assert_equal( { :foo => { :terms => {:field=>'bar',:size=>20,:all_terms=>false} } }.to_json, f.to_json )
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
context "terms facet" do
|
57
|
+
|
58
|
+
should "encode the default all_terms option" do
|
59
|
+
assert_equal false, Facet.new('foo') { terms :foo }.to_hash['foo'][:terms][:all_terms]
|
60
|
+
end
|
61
|
+
|
62
|
+
should "encode the all_terms option" do
|
63
|
+
assert_equal true, Facet.new('foo') { terms :foo, :all_terms => true }.to_hash['foo'][:terms][:all_terms]
|
64
|
+
end
|
65
|
+
|
66
|
+
should "encode custom options" do
|
67
|
+
assert_equal( { :foo => { :terms => {:field=>'bar',:size=>5,:all_terms=>false,:exclude=>['moo']} } }.to_json,
|
68
|
+
Facet.new('foo').terms(:bar, :size => 5, :exclude => ['moo']).to_json )
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
context "date histogram" do
|
74
|
+
|
75
|
+
should "encode the JSON with default values" do
|
76
|
+
f = Facet.new('date') { date :published_on }
|
77
|
+
assert_equal({ :date => { :date_histogram => { :field => 'published_on', :interval => 'day' } } }.to_json, f.to_json)
|
78
|
+
end
|
79
|
+
|
80
|
+
should "encode the JSON with custom interval" do
|
81
|
+
f = Facet.new('date') { date :published_on, :interval => 'month' }
|
82
|
+
assert_equal({ :date => { :date_histogram => { :field => 'published_on', :interval => 'month' } } }.to_json, f.to_json)
|
83
|
+
end
|
84
|
+
|
85
|
+
should "encode custom options" do
|
86
|
+
f = Facet.new('date') { date :published_on, :value_field => 'price' }
|
87
|
+
assert_equal( {:date=>{:date_histogram=>{:field=>'published_on',:interval=>'day',:value_field=>'price' } } }.to_json,
|
88
|
+
f.to_json )
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
context "range facet" do
|
94
|
+
should "encode facet options" do
|
95
|
+
f = Facet.new('range') { range :published_on, [{:to => '2010-12-31'}, {:from => '2011-01-01', :to => '2011-05-27'}, {:from => '2011-05-28'}]}
|
96
|
+
assert_equal({ :range => { :range => { :field => 'published_on', :ranges => [{:to => '2010-12-31'}, {:from => '2011-01-01', :to => '2011-05-27'}, {:from => '2011-05-28'}] } } }.to_json, f.to_json)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context "histogram facet" do
|
101
|
+
should "encode facet options with default key" do
|
102
|
+
f = Facet.new('histogram') { histogram :age, {:interval => 5} }
|
103
|
+
assert_equal({ :histogram => { :histogram => { :field => 'age', :interval => 5 } } }.to_json, f.to_json)
|
104
|
+
end
|
105
|
+
|
106
|
+
should "encode the JSON if define an histogram" do
|
107
|
+
f = Facet.new('histogram') { histogram :age, {:histogram => {:key_field => "age", :value_field => "age", :interval => 100}} }
|
108
|
+
assert_equal({ :histogram => { :histogram => {:key_field => "age", :value_field => "age", :interval => 100} } }.to_json, f.to_json)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context "statistical facet" do
|
113
|
+
should "encode facet options" do
|
114
|
+
f = Facet.new('statistical') { statistical :words }
|
115
|
+
assert_equal({:statistical => {:statistical => {:field => 'words'}}}.to_json, f.to_json)
|
116
|
+
end
|
117
|
+
|
118
|
+
should "encode the JSON if a 'statistical' custom option is defined" do
|
119
|
+
f = Facet.new('statistical') { statistical :words, :statistical => {:params => {:factor => 5}} }
|
120
|
+
assert_equal({:statistical => {:statistical => {:params => {:factor => 5 }}}}.to_json, f.to_json)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context "terms_stats facet" do
|
125
|
+
should "should encode facet options" do
|
126
|
+
f = Facet.new('terms_stats') { terms_stats :tags, :words }
|
127
|
+
assert_equal({:terms_stats => {:terms_stats => {:key_field => 'tags', :value_field => 'words'}}}.to_json, f.to_json)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context "query facet" do
|
132
|
+
should "encode facet options" do
|
133
|
+
f = Facet.new('q_facet') do
|
134
|
+
query { string '_exists_:foo' }
|
135
|
+
end
|
136
|
+
assert_equal({ :q_facet => { :query => { :query_string => { :query => '_exists_:foo' } } } }.to_json, f.to_json)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context "filter facet" do
|
141
|
+
should "encode facet options" do
|
142
|
+
f = Facet.new('filter_facet') do
|
143
|
+
filter :tags, 'ruby'
|
144
|
+
end
|
145
|
+
assert_equal({ :filter_facet => { :filter => { :term => { :tags => 'ruby' } } } }.to_json, f.to_json)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Tire::Search
|
4
|
+
|
5
|
+
class FilterTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Filter" do
|
8
|
+
|
9
|
+
should "be serialized to JSON" do
|
10
|
+
assert_respond_to Filter.new(:terms, {}), :to_json
|
11
|
+
end
|
12
|
+
|
13
|
+
should "encode simple filter declarations as JSON" do
|
14
|
+
assert_equal( { :terms => {} }.to_json,
|
15
|
+
Filter.new('terms').to_json )
|
16
|
+
|
17
|
+
assert_equal( { :terms => { :tags => ['foo'] } }.to_json,
|
18
|
+
Filter.new('terms', :tags => ['foo']).to_json )
|
19
|
+
|
20
|
+
assert_equal( { :range => { :age => { :from => 10, :to => 20 } } }.to_json,
|
21
|
+
Filter.new('range', { :age => { :from => 10, :to => 20 } }).to_json )
|
22
|
+
|
23
|
+
assert_equal( { :geo_distance => { :distance => '12km', :location => [40, -70] } }.to_json,
|
24
|
+
Filter.new('geo_distance', { :distance => '12km', :location => [40, -70] }).to_json )
|
25
|
+
end
|
26
|
+
|
27
|
+
should "encode 'or' filter with multiple other filters" do
|
28
|
+
# See http://www.elasticsearch.org/guide/reference/query-dsl/or-filter.html
|
29
|
+
assert_equal( { :or => [ {:terms => {:tags => ['foo']}}, {:terms => {:tags => ['bar']}} ] }.to_json,
|
30
|
+
Filter.new('or', {:terms => {:tags => ['foo']}}, {:terms => {:tags => ['bar']}}).to_json )
|
31
|
+
end
|
32
|
+
|
33
|
+
should "encode 'bool' filter with multiple filters" do
|
34
|
+
# http://www.elasticsearch.org/guide/reference/query-dsl/bool-filter.html
|
35
|
+
assert_equal( { :bool => [ {:must => {:terms => {:tags => ['foo']}}}, {:should => {:terms => {:tags => ['bar']}}} ] }.to_json,
|
36
|
+
Filter.new('bool', {:must => {:terms => {:tags => ['foo']}}}, { :should => {:terms => {:tags => ['bar']}}}).to_json )
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Tire::Search
|
4
|
+
|
5
|
+
class HighlightTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Highlight" do
|
8
|
+
|
9
|
+
should "be serialized to JSON" do
|
10
|
+
assert_respond_to Highlight.new(:body), :to_json
|
11
|
+
end
|
12
|
+
|
13
|
+
should "specify highlight for single field" do
|
14
|
+
assert_equal( {:fields => { :body => {} }}.to_json,
|
15
|
+
Highlight.new(:body).to_json )
|
16
|
+
end
|
17
|
+
|
18
|
+
should "specify highlight for more fields" do
|
19
|
+
assert_equal( {:fields => { :title => {}, :body => {} }}.to_json,
|
20
|
+
Highlight.new(:title, :body).to_json )
|
21
|
+
end
|
22
|
+
|
23
|
+
should "specify highlight for more fields with options" do
|
24
|
+
assert_equal( {:fields => { :title => {}, :body => { :a => 1, :b => 2 } }}.to_json,
|
25
|
+
Highlight.new(:title, :body => { :a => 1, :b => 2 }).to_json )
|
26
|
+
end
|
27
|
+
|
28
|
+
should "specify highlight for more fields with highlight options" do
|
29
|
+
# p Highlight.new(:title, :body => {}, :options => { :tag => '<strong>' }).to_hash
|
30
|
+
assert_equal( {:fields => { :title => {}, :body => {} }, :pre_tags => ['<strong>'], :post_tags => ['</strong>'] }.to_json,
|
31
|
+
Highlight.new(:title, :body => {}, :options => { :tag => '<strong>' }).to_json )
|
32
|
+
end
|
33
|
+
|
34
|
+
context "with custom tags" do
|
35
|
+
|
36
|
+
should "properly parse tags with class" do
|
37
|
+
assert_equal( {:fields => { :title => {} }, :pre_tags => ['<strong class="highlight">'], :post_tags => ['</strong>'] }.to_json,
|
38
|
+
Highlight.new(:title, :options => { :tag => '<strong class="highlight">' }).to_json )
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,301 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Tire::Search
|
4
|
+
|
5
|
+
class QueryTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Query" do
|
8
|
+
should "be serialized to JSON" do
|
9
|
+
assert_respond_to Query.new, :to_json
|
10
|
+
end
|
11
|
+
|
12
|
+
should "return itself as a Hash" do
|
13
|
+
assert_respond_to Query.new, :to_hash
|
14
|
+
assert_equal( { :term => { :foo => { :term => 'bar' } } }, Query.new.term(:foo, 'bar').to_hash )
|
15
|
+
end
|
16
|
+
|
17
|
+
should "allow a block to be given" do
|
18
|
+
assert_equal( { :term => { :foo => { :term => 'bar' } } }.to_json, Query.new do
|
19
|
+
term(:foo, 'bar')
|
20
|
+
end.to_json)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "Term query" do
|
25
|
+
should "allow search for single term" do
|
26
|
+
assert_equal( { :term => { :foo => { :term => 'bar' } } }, Query.new.term(:foo, 'bar') )
|
27
|
+
end
|
28
|
+
|
29
|
+
should "allow search for single term passing an options hash" do
|
30
|
+
assert_equal( { :term => { :foo => { :term => 'bar', :boost => 2.0 } } }, Query.new.term(:foo, 'bar', :boost => 2.0) )
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "Terms query" do
|
35
|
+
should "allow search for multiple terms" do
|
36
|
+
assert_equal( { :terms => { :foo => ['bar', 'baz'] } }, Query.new.terms(:foo, ['bar', 'baz']) )
|
37
|
+
end
|
38
|
+
|
39
|
+
should "allow set minimum match when searching for multiple terms" do
|
40
|
+
assert_equal( { :terms => { :foo => ['bar', 'baz'], :minimum_match => 2 } },
|
41
|
+
Query.new.terms(:foo, ['bar', 'baz'], :minimum_match => 2) )
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "Range query" do
|
46
|
+
should "allow search for a range" do
|
47
|
+
assert_equal( { :range => { :age => { :gte => 21 } } }, Query.new.range(:age, { :gte => 21 }) )
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "Text query" do
|
52
|
+
should "allow search with a text search" do
|
53
|
+
assert_equal( { :text => {'field' => {:query => 'foo'}}}, Query.new.text('field', 'foo'))
|
54
|
+
end
|
55
|
+
|
56
|
+
should "allow search with a different operator for text search" do
|
57
|
+
assert_equal( { :text => {'field' => {:query => 'foo', :operator => 'and'}}},
|
58
|
+
Query.new.text('field', 'foo', :operator => 'and'))
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "Query String query" do
|
63
|
+
should "allow search with a query string" do
|
64
|
+
assert_equal( { :query_string => { :query => 'title:foo' } },
|
65
|
+
Query.new.string('title:foo') )
|
66
|
+
end
|
67
|
+
|
68
|
+
should "allow set default field when searching with a query string" do
|
69
|
+
assert_equal( { :query_string => { :query => 'foo', :default_field => 'title' } },
|
70
|
+
Query.new.string('foo', :default_field => 'title') )
|
71
|
+
end
|
72
|
+
|
73
|
+
should "allow set default operator when searching with a query string" do
|
74
|
+
assert_equal( { :query_string => { :query => 'foo', :default_operator => 'AND' } },
|
75
|
+
Query.new.string('foo', :default_operator => 'AND') )
|
76
|
+
end
|
77
|
+
|
78
|
+
should "allow to set options when searching with a query string" do
|
79
|
+
assert_equal( { :query_string => { :query => 'foo', :fields => ['title.*'], :use_dis_max => true } },
|
80
|
+
Query.new.string('foo', :fields => ['title.*'], :use_dis_max => true) )
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "Custom Score query" do
|
85
|
+
should "allow to set script for custom score queries" do
|
86
|
+
query = Query.new.custom_score(:script => "_score * doc['price'].value") do
|
87
|
+
string 'foo'
|
88
|
+
end
|
89
|
+
|
90
|
+
assert_equal "_score * doc['price'].value", query[:custom_score][:script]
|
91
|
+
end
|
92
|
+
|
93
|
+
should "allow to pass parameters for custom score queries" do
|
94
|
+
query = Query.new.custom_score(:script => "_score * doc['price'].value / max(a, b)",
|
95
|
+
:params => { :a => 1, :b => 2 }) do
|
96
|
+
string 'foo'
|
97
|
+
end
|
98
|
+
|
99
|
+
assert_equal 1, query[:custom_score][:params][:a]
|
100
|
+
assert_equal 2, query[:custom_score][:params][:b]
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context "All query" do
|
105
|
+
should "search for all documents" do
|
106
|
+
assert_equal( { :match_all => { } }, Query.new.all )
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "IDs query" do
|
111
|
+
should "search for documents by IDs" do
|
112
|
+
assert_equal( { :ids => { :values => [1, 2], :type => 'foo' } },
|
113
|
+
Query.new.ids([1, 2], 'foo') )
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context "FuzzyQuery" do
|
118
|
+
|
119
|
+
should "allow a fuzzy search" do
|
120
|
+
assert_equal( { :fuzzy => { :foo => { :term => 'bar' } } }, Query.new.fuzzy(:foo, 'bar') )
|
121
|
+
end
|
122
|
+
|
123
|
+
should "allow a fuzzy search with an options hash" do
|
124
|
+
assert_equal( { :term => { :foo => { :term => 'bar', :boost => 1.0, :min_similarity => 0.5 } } }, Query.new.term(:foo, 'bar', :boost => 1.0, :min_similarity => 0.5 ) )
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
context "BooleanQuery" do
|
130
|
+
|
131
|
+
should "not raise an error when no block is given" do
|
132
|
+
assert_nothing_raised { Query.new.boolean }
|
133
|
+
end
|
134
|
+
|
135
|
+
should "encode options" do
|
136
|
+
query = Query.new.boolean(:minimum_number_should_match => 1) do
|
137
|
+
must { string 'foo' }
|
138
|
+
end
|
139
|
+
|
140
|
+
assert_equal 1, query[:bool][:minimum_number_should_match]
|
141
|
+
end
|
142
|
+
|
143
|
+
should "wrap single query" do
|
144
|
+
assert_equal( { :bool => {:must => [{ :query_string => { :query => 'foo' } }] }},
|
145
|
+
Query.new.boolean { must { string 'foo' } } )
|
146
|
+
end
|
147
|
+
|
148
|
+
should "wrap multiple queries for the same condition" do
|
149
|
+
query = Query.new.boolean do
|
150
|
+
must { string 'foo' }
|
151
|
+
must { string 'bar' }
|
152
|
+
end
|
153
|
+
|
154
|
+
assert_equal( 2, query[:bool][:must].size, query[:bool][:must].inspect )
|
155
|
+
assert_equal( { :query_string => {:query => 'foo'} }, query[:bool][:must].first )
|
156
|
+
assert_equal( { :query_string => {:query => 'bar'} }, query[:bool][:must].last )
|
157
|
+
end
|
158
|
+
|
159
|
+
should "wrap queries for multiple conditions" do
|
160
|
+
query = Query.new.boolean do
|
161
|
+
should { string 'foo' }
|
162
|
+
must { string 'bar' }
|
163
|
+
must { string 'baz' }
|
164
|
+
must_not { string 'fuu' }
|
165
|
+
end
|
166
|
+
|
167
|
+
assert_equal 2, query[:bool][:must].size
|
168
|
+
assert_equal 1, query[:bool][:should].size
|
169
|
+
assert_equal 1, query[:bool][:must_not].size
|
170
|
+
|
171
|
+
assert_equal( { :query_string => {:query => 'foo'} }, query[:bool][:should].first )
|
172
|
+
assert_equal( { :query_string => {:query => 'bar'} }, query[:bool][:must].first )
|
173
|
+
assert_equal( { :query_string => {:query => 'baz'} }, query[:bool][:must].last )
|
174
|
+
assert_equal( { :query_string => {:query => 'fuu'} }, query[:bool][:must_not].first )
|
175
|
+
end
|
176
|
+
|
177
|
+
should "allow passing variables from outer scope" do
|
178
|
+
@q1 = 'foo'
|
179
|
+
@q2 = 'bar'
|
180
|
+
query = Query.new.boolean do |boolean|
|
181
|
+
boolean.must { |query| query.string @q1 }
|
182
|
+
boolean.must { |query| query.string @q2 }
|
183
|
+
end
|
184
|
+
|
185
|
+
assert_equal( 2, query[:bool][:must].size, query[:bool][:must].inspect )
|
186
|
+
assert_equal( { :query_string => {:query => 'foo'} }, query[:bool][:must].first )
|
187
|
+
assert_equal( { :query_string => {:query => 'bar'} }, query[:bool][:must].last )
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
|
192
|
+
context "FilteredQuery" do
|
193
|
+
|
194
|
+
should "not raise an error when no block is given" do
|
195
|
+
assert_nothing_raised { Query.new.filtered }
|
196
|
+
end
|
197
|
+
|
198
|
+
should "properly encode filter" do
|
199
|
+
query = Query.new.filtered do
|
200
|
+
query { term :foo, 'bar' }
|
201
|
+
filter :terms, :tags => ['ruby']
|
202
|
+
end
|
203
|
+
|
204
|
+
query[:filtered].tap do |f|
|
205
|
+
assert_equal( { :term => { :foo => { :term => 'bar' } } }, f[:query].to_hash )
|
206
|
+
assert_equal( { :tags => ['ruby'] }, f[:filter][:and].first[:terms] )
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
should "properly encode multiple filters" do
|
211
|
+
query = Query.new.filtered do
|
212
|
+
query { term :foo, 'bar' }
|
213
|
+
filter :terms, :tags => ['ruby']
|
214
|
+
filter :terms, :tags => ['python']
|
215
|
+
end
|
216
|
+
|
217
|
+
query[:filtered][:filter].tap do |filter|
|
218
|
+
assert_equal 1, filter.size
|
219
|
+
assert_equal( { :tags => ['ruby'] }, filter[:and].first[:terms] )
|
220
|
+
assert_equal( { :tags => ['python'] }, filter[:and].last[:terms] )
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
should "allow passing variables from outer scope" do
|
225
|
+
@my_query = 'bar'
|
226
|
+
@my_filter = { :tags => ['ruby'] }
|
227
|
+
|
228
|
+
query = Query.new.filtered do |f|
|
229
|
+
f.query { |q| q.term :foo, @my_query }
|
230
|
+
f.filter :terms, @my_filter
|
231
|
+
end
|
232
|
+
|
233
|
+
query[:filtered].tap do |f|
|
234
|
+
assert_equal( { :term => { :foo => { :term => 'bar' } } }, f[:query].to_hash )
|
235
|
+
assert_equal( { :tags => ['ruby'] }, f[:filter][:and].first[:terms] )
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
context "Prefix query" do
|
240
|
+
should "allow search for a prefix" do
|
241
|
+
assert_equal( { :prefix => { :user => "foo" } }, Query.new.prefix(:user, "foo") )
|
242
|
+
end
|
243
|
+
|
244
|
+
should "allow setting boost for prefix" do
|
245
|
+
assert_equal( { :prefix => {:user => {:prefix => "foo", :boost => 2.0 } } },
|
246
|
+
Query.new.prefix(:user, "foo", :boost => 2.0) )
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
end
|
251
|
+
|
252
|
+
context "DisMaxQuery" do
|
253
|
+
|
254
|
+
should "not raise an error when no block is given" do
|
255
|
+
assert_nothing_raised { Query.new.dis_max }
|
256
|
+
end
|
257
|
+
|
258
|
+
should "encode options" do
|
259
|
+
query = Query.new.dis_max(:tie_breaker => 0.7) do
|
260
|
+
query { string 'foo' }
|
261
|
+
end
|
262
|
+
|
263
|
+
assert_equal 0.7, query[:dis_max][:tie_breaker]
|
264
|
+
end
|
265
|
+
|
266
|
+
should "wrap single query" do
|
267
|
+
assert_equal( { :dis_max => {:queries => [{ :query_string => { :query => 'foo' } }] }},
|
268
|
+
Query.new.dis_max { query { string 'foo' } } )
|
269
|
+
end
|
270
|
+
|
271
|
+
should "wrap multiple queries" do
|
272
|
+
query = Query.new.dis_max do
|
273
|
+
query { string 'foo' }
|
274
|
+
query { string 'bar' }
|
275
|
+
query { string 'baz' }
|
276
|
+
end
|
277
|
+
|
278
|
+
assert_equal 3, query[:dis_max][:queries].size
|
279
|
+
|
280
|
+
assert_equal( { :query_string => {:query => 'foo'} }, query[:dis_max][:queries][0] )
|
281
|
+
assert_equal( { :query_string => {:query => 'bar'} }, query[:dis_max][:queries][1] )
|
282
|
+
assert_equal( { :query_string => {:query => 'baz'} }, query[:dis_max][:queries][2] )
|
283
|
+
end
|
284
|
+
|
285
|
+
should "allow passing variables from outer scope" do
|
286
|
+
@q1 = 'foo'
|
287
|
+
@q2 = 'bar'
|
288
|
+
query = Query.new.dis_max do |dis_max|
|
289
|
+
dis_max.query { |query| query.string @q1 }
|
290
|
+
dis_max.query { |query| query.string @q2 }
|
291
|
+
end
|
292
|
+
|
293
|
+
assert_equal( 2, query[:dis_max][:queries].size, query[:dis_max][:queries].inspect )
|
294
|
+
assert_equal( { :query_string => {:query => 'foo'} }, query[:dis_max][:queries].first )
|
295
|
+
assert_equal( { :query_string => {:query => 'bar'} }, query[:dis_max][:queries].last )
|
296
|
+
end
|
297
|
+
|
298
|
+
end
|
299
|
+
|
300
|
+
end
|
301
|
+
end
|