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,43 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Tire
|
4
|
+
|
5
|
+
class BooleanQueriesIntegrationTest < Test::Unit::TestCase
|
6
|
+
include Test::Integration
|
7
|
+
|
8
|
+
context "Boolean queries" do
|
9
|
+
|
10
|
+
should "allow to set multiple queries per condition" do
|
11
|
+
s = Tire.search('articles-test') do
|
12
|
+
query do
|
13
|
+
boolean do
|
14
|
+
must { term :tags, 'ruby' }
|
15
|
+
must { term :tags, 'python' }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
assert_equal 1, s.results.size
|
21
|
+
assert_equal 'Two', s.results.first.title
|
22
|
+
end
|
23
|
+
|
24
|
+
should "allow to set multiple queries for multiple conditions" do
|
25
|
+
s = Tire.search('articles-test') do
|
26
|
+
query do
|
27
|
+
boolean do
|
28
|
+
must { term :tags, 'ruby' }
|
29
|
+
should { term :tags, 'python' }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
assert_equal 2, s.results.size
|
35
|
+
assert_equal 'Two', s.results[0].title
|
36
|
+
assert_equal 'One', s.results[1].title
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Tire
|
4
|
+
|
5
|
+
class CountIntegrationTest < Test::Unit::TestCase
|
6
|
+
include Test::Integration
|
7
|
+
|
8
|
+
context "Count" do
|
9
|
+
|
10
|
+
should "return total number of hits for the query, but no hits" do
|
11
|
+
s = Tire.search 'articles-test', :search_type => 'count' do
|
12
|
+
query { term :tags, 'ruby' }
|
13
|
+
end
|
14
|
+
|
15
|
+
assert_equal 2, s.results.total
|
16
|
+
assert_equal 0, s.results.count
|
17
|
+
assert s.results.empty?
|
18
|
+
end
|
19
|
+
|
20
|
+
should "return facets in results" do
|
21
|
+
s = Tire.search 'articles-test', :search_type => 'count' do
|
22
|
+
query { term :tags, 'ruby' }
|
23
|
+
facet('tags') { terms :tags }
|
24
|
+
end
|
25
|
+
|
26
|
+
assert ! s.results.facets['tags'].empty?
|
27
|
+
assert_equal 2, s.results.facets['tags']['terms'].select { |t| t['term'] == 'ruby' }. first['count']
|
28
|
+
assert_equal 1, s.results.facets['tags']['terms'].select { |t| t['term'] == 'python' }.first['count']
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Tire
|
4
|
+
|
5
|
+
class CustomScoreQueriesIntegrationTest < Test::Unit::TestCase
|
6
|
+
include Test::Integration
|
7
|
+
|
8
|
+
context "Custom score queries" do
|
9
|
+
|
10
|
+
should "allow to define custom score queries (base score on field value)" do
|
11
|
+
s = Tire.search('articles-test') do
|
12
|
+
query do
|
13
|
+
# Give longer documents higher score
|
14
|
+
#
|
15
|
+
custom_score :script => "1.0 / doc['words'].value" do
|
16
|
+
string "title:T*"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
assert_equal 2, s.results.size
|
22
|
+
assert_equal ['Two', 'Three'], s.results.map(&:title)
|
23
|
+
|
24
|
+
assert s.results[0]._score > 0
|
25
|
+
assert s.results[1]._score > 0
|
26
|
+
assert s.results[0]._score > s.results[1]._score
|
27
|
+
end
|
28
|
+
|
29
|
+
should "allow to manipulate the default score (boost recent)" do
|
30
|
+
s = Tire.search('articles-test') do
|
31
|
+
query do
|
32
|
+
# Boost recent documents
|
33
|
+
#
|
34
|
+
custom_score :script => "_score + ( doc['published_on'].date.getMillis() / time() )" do
|
35
|
+
string 'title:F*'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
assert_equal 2, s.results.size
|
41
|
+
assert_equal ['Five', 'Four'], s.results.map(&:title)
|
42
|
+
|
43
|
+
assert s.results[0]._score > 1
|
44
|
+
assert s.results[1]._score > 1
|
45
|
+
end
|
46
|
+
|
47
|
+
should "allow to define arbitrary custom scoring" do
|
48
|
+
s = Tire.search('articles-test') do
|
49
|
+
query do
|
50
|
+
# Replace documents score with the count of characters in their title
|
51
|
+
#
|
52
|
+
custom_score :script => "doc['title'].value.length()" do
|
53
|
+
string "title:T*"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
assert_equal 2, s.results.size
|
59
|
+
assert_equal ['Three', 'Two'], s.results.map(&:title)
|
60
|
+
|
61
|
+
assert_equal 5.0, s.results[0]._score
|
62
|
+
assert_equal 3.0, s.results[1]._score
|
63
|
+
end
|
64
|
+
|
65
|
+
should "allow to pass parameters to the script" do
|
66
|
+
s = Tire.search('articles-test') do
|
67
|
+
query do
|
68
|
+
# Replace documents score with parameterized computation
|
69
|
+
#
|
70
|
+
custom_score :script => "doc['words'].doubleValue / max(a, b)",
|
71
|
+
:params => { :a => 1, :b => 2 } do
|
72
|
+
string "title:T*"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
assert_equal 2, s.results.size
|
78
|
+
assert_equal ['Three', 'Two'], s.results.map(&:title)
|
79
|
+
|
80
|
+
assert_equal 187.5, s.results[0]._score
|
81
|
+
assert_equal 125.0, s.results[1]._score
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Tire
|
4
|
+
|
5
|
+
class DisMaxQueriesIntegrationTest < Test::Unit::TestCase
|
6
|
+
include Test::Integration
|
7
|
+
|
8
|
+
context "Dis Max queries" do
|
9
|
+
setup do
|
10
|
+
Tire.index 'dis_max_test' do
|
11
|
+
delete
|
12
|
+
create
|
13
|
+
|
14
|
+
store title: "It's an Albino, Albino, Albino thing!", text: "Albino, albino, albino! Wanna know about albino? ..."
|
15
|
+
store title: "Albino Vampire Monkey Attacks!", text: "The night was just setting in when ..."
|
16
|
+
store title: "Pinky Elephant", text: "An albino walks into a ZOO and ..."
|
17
|
+
refresh
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
teardown do
|
22
|
+
Tire.index('dis_max_test').delete
|
23
|
+
end
|
24
|
+
|
25
|
+
should "boost matches in both fields" do
|
26
|
+
dis_max = Tire.search 'dis_max_test' do
|
27
|
+
query do
|
28
|
+
dis_max do
|
29
|
+
query { string "albino elephant", fields: ['title', 'text'] }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
# p "DisMax:", dis_max.results.map(&:title)
|
34
|
+
|
35
|
+
assert_equal 'Pinky Elephant', dis_max.results.first.title
|
36
|
+
|
37
|
+
# NOTE: This gives exactly the same result as a boolean query:
|
38
|
+
# boolean = Tire.search 'dis_max_test' do
|
39
|
+
# query do
|
40
|
+
# boolean do
|
41
|
+
# should { string "albino", fields: ['title', 'text'] }
|
42
|
+
# should { string "elephant", fields: ['title', 'text'] }
|
43
|
+
# end
|
44
|
+
# end
|
45
|
+
# end
|
46
|
+
# p "Boolean:", boolean.results.map(&:title)
|
47
|
+
end
|
48
|
+
|
49
|
+
should "allow to set multiple queries" do
|
50
|
+
s = Tire.search('articles-test') do
|
51
|
+
query do
|
52
|
+
dis_max do
|
53
|
+
query { term :tags, 'ruby' }
|
54
|
+
query { term :tags, 'python' }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
assert_equal 2, s.results.size
|
60
|
+
assert_equal 'Two', s.results[0].title
|
61
|
+
assert_equal 'One', s.results[1].title
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Tire
|
4
|
+
|
5
|
+
class DSLSearchIntegrationTest < Test::Unit::TestCase
|
6
|
+
include Test::Integration
|
7
|
+
|
8
|
+
context "DSL" do
|
9
|
+
|
10
|
+
should "allow passing search payload as a Hash" do
|
11
|
+
s = Tire.search 'articles-test', :query => { :query_string => { :query => 'ruby' } },
|
12
|
+
:facets => { 'tags' => { :filter => { :term => {:tags => 'ruby' } } } }
|
13
|
+
# p s.results
|
14
|
+
assert_equal 2, s.results.count
|
15
|
+
assert_equal 2, s.results.facets['tags']['count']
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Tire
|
4
|
+
|
5
|
+
class ExplanationIntegrationTest < Test::Unit::TestCase
|
6
|
+
include Test::Integration
|
7
|
+
|
8
|
+
context "Explanation" do
|
9
|
+
teardown { Tire.index('explanation-test').delete }
|
10
|
+
|
11
|
+
setup do
|
12
|
+
content = "A Fox one day fell into a deep well and could find no means of escape."
|
13
|
+
|
14
|
+
Tire.index 'explanation-test' do
|
15
|
+
delete
|
16
|
+
create
|
17
|
+
store :id => 1, :content => content
|
18
|
+
refresh
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
should "add '_explanation' field to the result item" do
|
23
|
+
# Tire::Configuration.logger STDERR, :level => 'debug'
|
24
|
+
s = Tire.search 'explanation-test', :explain => true do
|
25
|
+
query do
|
26
|
+
boolean do
|
27
|
+
should { string 'content:Fox' }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
doc = s.results.first
|
33
|
+
|
34
|
+
explanation = doc._explanation
|
35
|
+
|
36
|
+
assert explanation.description.include?("product of:")
|
37
|
+
assert explanation.value < 0.6
|
38
|
+
assert_not_nil explanation.details
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,259 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
module Tire
|
5
|
+
|
6
|
+
class FacetsIntegrationTest < Test::Unit::TestCase
|
7
|
+
include Test::Integration
|
8
|
+
|
9
|
+
context "Facets" do
|
10
|
+
|
11
|
+
should "return results scoped to current query" do
|
12
|
+
q = 'tags:ruby'
|
13
|
+
s = Tire.search('articles-test') do
|
14
|
+
query { string q }
|
15
|
+
facet 'tags' do
|
16
|
+
terms :tags
|
17
|
+
end
|
18
|
+
end
|
19
|
+
facets = s.results.facets['tags']['terms']
|
20
|
+
assert_equal 2, facets.count
|
21
|
+
assert_equal 'ruby', facets.first['term']
|
22
|
+
assert_equal 2, facets.first['count']
|
23
|
+
end
|
24
|
+
|
25
|
+
should "allow to specify global facets and query-scoped facets" do
|
26
|
+
q = 'tags:ruby'
|
27
|
+
s = Tire.search('articles-test') do
|
28
|
+
query { string q }
|
29
|
+
facet('scoped-tags') { terms :tags }
|
30
|
+
facet('global-tags', :global => true) { terms :tags }
|
31
|
+
end
|
32
|
+
|
33
|
+
scoped_facets = s.results.facets['scoped-tags']['terms']
|
34
|
+
global_facets = s.results.facets['global-tags']['terms']
|
35
|
+
|
36
|
+
assert_equal 2, scoped_facets.count
|
37
|
+
assert_equal 5, global_facets.count
|
38
|
+
end
|
39
|
+
|
40
|
+
should "allow to define multiple facets" do
|
41
|
+
s = Tire.search('articles-test') do
|
42
|
+
facet('tags') { terms :tags }
|
43
|
+
facet('date') { date :published_on }
|
44
|
+
end
|
45
|
+
|
46
|
+
assert_equal 2, s.results.facets.size
|
47
|
+
end
|
48
|
+
|
49
|
+
should "allow to restrict facets with filters" do
|
50
|
+
s = Tire.search('articles-test') do
|
51
|
+
query { string 'tags:ruby' }
|
52
|
+
facet('tags', :facet_filter => { :range => { :published_on => { :from => '2011-01-01', :to => '2011-01-01' } } }) do
|
53
|
+
terms :tags
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
assert_equal 1, s.results.facets.size
|
58
|
+
assert_equal 'ruby', s.results.facets['tags']['terms'].first['term']
|
59
|
+
assert_equal 1, s.results.facets['tags']['terms'].first['count'].to_i
|
60
|
+
end
|
61
|
+
|
62
|
+
context "terms" do
|
63
|
+
setup do
|
64
|
+
@s = Tire.search('articles-test') do
|
65
|
+
query { string 'tags:ruby' }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
should "return results ordered by term" do
|
70
|
+
@s.facet('tags') { terms :tags }
|
71
|
+
@s.facet('term-ordered-tags') { terms :tags, order: 'term' }
|
72
|
+
|
73
|
+
facets = @s.results.facets
|
74
|
+
# p facets
|
75
|
+
assert_equal 'ruby', facets['tags']['terms'] .first['term']
|
76
|
+
assert_equal 'python', facets['term-ordered-tags']['terms'].first['term']
|
77
|
+
end
|
78
|
+
|
79
|
+
should "return results aggregated over multiple fields" do
|
80
|
+
@s.facet('multiple-fields') { terms ['tags', 'words'] }
|
81
|
+
|
82
|
+
facets = @s.results.facets
|
83
|
+
# p facets
|
84
|
+
assert_equal 4, facets['multiple-fields']['terms'].size
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
context "date histogram" do
|
90
|
+
|
91
|
+
should "return aggregated values for all results" do
|
92
|
+
s = Tire.search('articles-test') do
|
93
|
+
query { all }
|
94
|
+
facet 'published_on' do
|
95
|
+
date :published_on
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
facets = s.results.facets['published_on']['entries']
|
100
|
+
assert_equal 4, facets.size, facets.inspect
|
101
|
+
assert_equal 2, facets.entries[1]["count"], facets.inspect
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
context "date ranges" do
|
107
|
+
|
108
|
+
should "return aggregated values for all results" do
|
109
|
+
s = Tire.search('articles-test') do
|
110
|
+
query { all }
|
111
|
+
facet 'published_on' do
|
112
|
+
range :published_on, [{:to => '2010-12-31'}, {:from => '2011-01-01', :to => '2011-01-05'}]
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
facets = s.results.facets['published_on']['ranges']
|
117
|
+
assert_equal 2, facets.size, facets.inspect
|
118
|
+
assert_equal 0, facets.entries[0]["count"], facets.inspect
|
119
|
+
assert_equal 5, facets.entries[1]["count"], facets.inspect
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
context "histogram" do
|
125
|
+
|
126
|
+
should "return aggregated values for all results" do
|
127
|
+
s = Tire.search('articles-test') do
|
128
|
+
query { all }
|
129
|
+
facet 'words_histogram' do
|
130
|
+
histogram :words, :interval => 100
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
facets = s.results.facets['words_histogram']['entries']
|
135
|
+
assert_equal 3, facets.size, facets.inspect
|
136
|
+
assert_equal({"key" => 100, "count" => 2}, facets.entries[0], facets.inspect)
|
137
|
+
assert_equal({"key" => 200, "count" => 2}, facets.entries[1], facets.inspect)
|
138
|
+
assert_equal({"key" => 300, "count" => 1}, facets.entries[2], facets.inspect)
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
|
143
|
+
context "statistical" do
|
144
|
+
|
145
|
+
should "return computed statistical data on a numeric field" do
|
146
|
+
s = Tire.search('articles-test') do
|
147
|
+
query { all }
|
148
|
+
facet 'word_stats' do
|
149
|
+
statistical :words
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
facets = s.results.facets["word_stats"]
|
154
|
+
assert_equal 5, facets["count"], facets.inspect
|
155
|
+
assert_equal 1125.0, facets["total"], facets.inspect
|
156
|
+
assert_equal 125.0, facets["min"], facets.inspect
|
157
|
+
assert_equal 375.0, facets["max"], facets.inspect
|
158
|
+
assert_equal 225.0, facets["mean"], facets.inspect
|
159
|
+
end
|
160
|
+
|
161
|
+
should "return computed statistical data by given script" do
|
162
|
+
s = Tire.search('articles-test') do
|
163
|
+
query { all }
|
164
|
+
facet 'word_stats' do
|
165
|
+
statistical :statistical => { :script => "doc['words'].value * factor",
|
166
|
+
:params => { :factor => 2 } }
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
facets = s.results.facets["word_stats"]
|
171
|
+
assert_equal 2250.0, facets["total"], facets.inspect
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
context "terms_stats" do
|
177
|
+
|
178
|
+
should "return computed stats computed on a field, per term value driven by another field" do
|
179
|
+
s = Tire.search('articles-test') do
|
180
|
+
query { all }
|
181
|
+
facet 'words_per_tag_stats' do
|
182
|
+
terms_stats :tags, :words
|
183
|
+
end
|
184
|
+
end
|
185
|
+
facets = s.results.facets['words_per_tag_stats']['terms']
|
186
|
+
|
187
|
+
assert_equal({"term" => "ruby", "count" => 2, "total_count"=> 2, "min"=> 125.0, "max"=> 250.0, "total"=> 375.0, "mean"=> 187.5}, facets[0], facets.inspect)
|
188
|
+
assert_equal({"term" => "java", "count" => 2, "total_count"=> 2, "min"=> 125.0, "max"=> 375.0, "total"=> 500.0, "mean"=> 250.0}, facets[1], facets.inspect)
|
189
|
+
assert_equal({"term" => "python", "count" => 1, "total_count"=> 1, "min"=> 250.0, "max"=> 250.0, "total"=> 250.0, "mean"=> 250.0}, facets[2], facets.inspect)
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
193
|
+
|
194
|
+
context "query facets" do
|
195
|
+
|
196
|
+
should "return aggregated values for a string query" do
|
197
|
+
s = Tire.search('articles-test') do
|
198
|
+
facet 'tees' do
|
199
|
+
query { string 'T*' }
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
count = s.results.facets['tees']['count']
|
204
|
+
assert_equal 2, count, s.results.facets['tees'].inspect
|
205
|
+
end
|
206
|
+
|
207
|
+
should "return aggregated values for _exists_ string query" do
|
208
|
+
s = Tire.search('articles-test') do
|
209
|
+
facet 'drafts' do
|
210
|
+
query { string '_exists_:draft' }
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
count = s.results.facets['drafts']['count']
|
215
|
+
assert_equal 1, count, s.results.facets['drafts'].inspect
|
216
|
+
end
|
217
|
+
|
218
|
+
should "return aggregated values for a terms query" do
|
219
|
+
s = Tire.search('articles-test') do
|
220
|
+
facet 'friends' do
|
221
|
+
query { terms :tags, ['ruby', 'python'] }
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
count = s.results.facets['friends']['count']
|
226
|
+
assert_equal 2, count, s.results.facets['friends'].inspect
|
227
|
+
|
228
|
+
s = Tire.search('articles-test') do
|
229
|
+
facet 'friends' do
|
230
|
+
query { terms :tags, ['ruby', 'python'], :minimum_match => 2 }
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
count = s.results.facets['friends']['count']
|
235
|
+
assert_equal 1, count, s.results.facets['friends'].inspect
|
236
|
+
end
|
237
|
+
|
238
|
+
end
|
239
|
+
|
240
|
+
context "filter" do
|
241
|
+
should "return a filtered facet" do
|
242
|
+
s = Tire.search('articles-test') do
|
243
|
+
query { all }
|
244
|
+
facet 'filtered' do
|
245
|
+
filter :tags, 'ruby'
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
assert_equal 5, s.results.size, s.results.inspect
|
250
|
+
facets = s.results.facets["filtered"]
|
251
|
+
assert_equal 2, facets["count"], facets.inspect
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
end
|
256
|
+
|
257
|
+
end
|
258
|
+
|
259
|
+
end
|