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,38 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Tire
|
4
|
+
|
5
|
+
class ScriptFieldsIntegrationTest < Test::Unit::TestCase
|
6
|
+
include Test::Integration
|
7
|
+
|
8
|
+
context "ScriptFields" do
|
9
|
+
|
10
|
+
should "add multiple fields to the results" do
|
11
|
+
# 1.json > title: "One", words: 125
|
12
|
+
|
13
|
+
s = Tire.search('articles-test') do
|
14
|
+
query { string "One" }
|
15
|
+
script_field :double_words, :script => "doc['words'].value * 2"
|
16
|
+
script_field :triple_words, :script => "doc['words'].value * 3"
|
17
|
+
end
|
18
|
+
|
19
|
+
assert_equal 250, s.results.first.double_words
|
20
|
+
assert_equal 375, s.results.first.triple_words
|
21
|
+
end
|
22
|
+
|
23
|
+
should "allow passing parameters to the script" do
|
24
|
+
# 1.json > title: "One", words: 125
|
25
|
+
|
26
|
+
s = Tire.search('articles-test') do
|
27
|
+
query { string "One" }
|
28
|
+
script_field :double_words, :script => "doc['words'].value * factor", :params => { :factor => 2 }
|
29
|
+
end
|
30
|
+
|
31
|
+
assert_equal 250, s.results.first.double_words
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Tire
|
4
|
+
|
5
|
+
class SortIntegrationTest < Test::Unit::TestCase
|
6
|
+
include Test::Integration
|
7
|
+
|
8
|
+
context "Sort" do
|
9
|
+
|
10
|
+
should "sort by title" do
|
11
|
+
q = '*'
|
12
|
+
s = Tire.search('articles-test') do
|
13
|
+
query { string q }
|
14
|
+
sort { by :title }
|
15
|
+
end
|
16
|
+
|
17
|
+
assert_equal 5, s.results.count
|
18
|
+
assert_equal 'Five', s.results.first[:title]
|
19
|
+
end
|
20
|
+
|
21
|
+
should "sort by title, descending" do
|
22
|
+
q = '*'
|
23
|
+
s = Tire.search('articles-test') do
|
24
|
+
query { string q }
|
25
|
+
sort { by :title, :desc }
|
26
|
+
end
|
27
|
+
|
28
|
+
assert_equal 5, s.results.count
|
29
|
+
assert_equal 'Two', s.results.first[:title]
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Tire
|
4
|
+
|
5
|
+
class QueryStringIntegrationTest < Test::Unit::TestCase
|
6
|
+
include Test::Integration
|
7
|
+
|
8
|
+
context "Text query" do
|
9
|
+
setup do
|
10
|
+
Tire.index('articles-test') do
|
11
|
+
store :type => 'article', :title => '+1 !!!'
|
12
|
+
store :type => 'article', :title => 'Furry Kitten'
|
13
|
+
refresh
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
should "find article by title" do
|
18
|
+
results = Tire.search('articles-test') do
|
19
|
+
query { text :title, '+1' }
|
20
|
+
end.results
|
21
|
+
|
22
|
+
assert_equal 1, results.count
|
23
|
+
assert_equal "+1 !!!", results.first[:title]
|
24
|
+
end
|
25
|
+
|
26
|
+
should "allow to pass options (fuzziness)" do
|
27
|
+
results = Tire.search('articles-test') do
|
28
|
+
query { text :title, 'fuzzy mitten', :fuzziness => 0.5, :operator => 'and' }
|
29
|
+
end.results
|
30
|
+
|
31
|
+
assert_equal 1, results.count
|
32
|
+
assert_equal "Furry Kitten", results.first[:title]
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# Example ActiveModel class
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'active_model'
|
5
|
+
|
6
|
+
class ActiveModelArticle
|
7
|
+
|
8
|
+
extend ActiveModel::Naming
|
9
|
+
include ActiveModel::AttributeMethods
|
10
|
+
include ActiveModel::Serialization
|
11
|
+
include ActiveModel::Serializers::JSON
|
12
|
+
|
13
|
+
include Tire::Model::Search
|
14
|
+
|
15
|
+
attr_reader :attributes
|
16
|
+
|
17
|
+
def initialize(attributes = {})
|
18
|
+
@attributes = attributes
|
19
|
+
end
|
20
|
+
|
21
|
+
def id; attributes['id'] || attributes['_id']; end
|
22
|
+
def id=(value); attributes['id'] = value; end
|
23
|
+
|
24
|
+
def method_missing(name, *args, &block)
|
25
|
+
attributes[name.to_sym] || attributes[name.to_s] || super
|
26
|
+
end
|
27
|
+
|
28
|
+
def persisted?; true; end
|
29
|
+
def save; true; end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# Example ActiveModel class with callbacks
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'active_model'
|
5
|
+
|
6
|
+
class ActiveModelArticleWithCallbacks
|
7
|
+
|
8
|
+
include ActiveModel::AttributeMethods
|
9
|
+
include ActiveModel::Validations
|
10
|
+
include ActiveModel::Serialization
|
11
|
+
include ActiveModel::Serializers::JSON
|
12
|
+
include ActiveModel::Naming
|
13
|
+
|
14
|
+
extend ActiveModel::Callbacks
|
15
|
+
define_model_callbacks :save, :destroy
|
16
|
+
|
17
|
+
include Tire::Model::Search
|
18
|
+
include Tire::Model::Callbacks
|
19
|
+
|
20
|
+
attr_reader :attributes
|
21
|
+
|
22
|
+
def initialize(attributes = {})
|
23
|
+
@attributes = attributes
|
24
|
+
end
|
25
|
+
|
26
|
+
def method_missing(id, *args, &block)
|
27
|
+
attributes[id.to_sym] || attributes[id.to_s] || super
|
28
|
+
end
|
29
|
+
|
30
|
+
def persisted?
|
31
|
+
true
|
32
|
+
end
|
33
|
+
|
34
|
+
def save
|
35
|
+
_run_save_callbacks do
|
36
|
+
STDERR.puts "[Saving ...]"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def destroy
|
41
|
+
_run_destroy_callbacks do
|
42
|
+
STDERR.puts "[Destroying ...]"
|
43
|
+
@destroyed = true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def destroyed?; !!@destroyed; end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
class ActiveRecordArticle < ActiveRecord::Base
|
4
|
+
has_many :comments, :class_name => "ActiveRecordComment", :foreign_key => "article_id"
|
5
|
+
has_many :stats, :class_name => "ActiveRecordStat", :foreign_key => "article_id"
|
6
|
+
|
7
|
+
include Tire::Model::Search
|
8
|
+
include Tire::Model::Callbacks
|
9
|
+
|
10
|
+
tire do
|
11
|
+
mapping do
|
12
|
+
indexes :title, :type => 'string', :boost => 10, :analyzer => 'snowball'
|
13
|
+
indexes :created_at, :type => 'date'
|
14
|
+
|
15
|
+
indexes :comments do
|
16
|
+
indexes :author
|
17
|
+
indexes :body
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_indexed_json
|
23
|
+
{
|
24
|
+
:title => title,
|
25
|
+
:length => length,
|
26
|
+
|
27
|
+
:comments => comments.map { |c| { :_type => 'active_record_comment',
|
28
|
+
:_id => c.id,
|
29
|
+
:author => c.author,
|
30
|
+
:body => c.body } },
|
31
|
+
:stats => stats.map { |s| { :pageviews => s.pageviews } }
|
32
|
+
}.to_json
|
33
|
+
end
|
34
|
+
|
35
|
+
def length
|
36
|
+
title.length
|
37
|
+
end
|
38
|
+
|
39
|
+
def comment_authors
|
40
|
+
comments.map(&:author).to_sentence
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class ActiveRecordComment < ActiveRecord::Base
|
45
|
+
belongs_to :article, :class_name => "ActiveRecordArticle", :foreign_key => "article_id"
|
46
|
+
end
|
47
|
+
|
48
|
+
class ActiveRecordStat < ActiveRecord::Base
|
49
|
+
belongs_to :article, :class_name => "ActiveRecordArticle", :foreign_key => "article_id"
|
50
|
+
end
|
51
|
+
|
52
|
+
class ActiveRecordClassWithTireMethods < ActiveRecord::Base
|
53
|
+
|
54
|
+
def self.mapping
|
55
|
+
"THIS IS MY MAPPING!"
|
56
|
+
end
|
57
|
+
|
58
|
+
def index
|
59
|
+
"THIS IS MY INDEX!"
|
60
|
+
end
|
61
|
+
|
62
|
+
include Tire::Model::Search
|
63
|
+
include Tire::Model::Callbacks
|
64
|
+
|
65
|
+
tire do
|
66
|
+
mapping do
|
67
|
+
indexes :title, :type => 'string', :analyzer => 'snowball'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class ActiveRecordClassWithDynamicIndexName < ActiveRecord::Base
|
73
|
+
include Tire::Model::Search
|
74
|
+
include Tire::Model::Callbacks
|
75
|
+
|
76
|
+
index_name do
|
77
|
+
"dynamic" + '_' + "index"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Used in test for multiple class instances in one index,
|
82
|
+
# and single table inheritance (STI) support.
|
83
|
+
|
84
|
+
class ActiveRecordModelOne < ActiveRecord::Base
|
85
|
+
include Tire::Model::Search
|
86
|
+
include Tire::Model::Callbacks
|
87
|
+
self.table_name = 'active_record_model_one'
|
88
|
+
index_name 'active_record_model_one'
|
89
|
+
end
|
90
|
+
|
91
|
+
class ActiveRecordModelTwo < ActiveRecord::Base
|
92
|
+
include Tire::Model::Search
|
93
|
+
include Tire::Model::Callbacks
|
94
|
+
self.table_name = 'active_record_model_two'
|
95
|
+
index_name 'active_record_model_two'
|
96
|
+
end
|
97
|
+
|
98
|
+
class ActiveRecordAsset < ActiveRecord::Base
|
99
|
+
include Tire::Model::Search
|
100
|
+
include Tire::Model::Callbacks
|
101
|
+
end
|
102
|
+
|
103
|
+
class ActiveRecordVideo < ActiveRecordAsset
|
104
|
+
index_name 'active_record_assets'
|
105
|
+
end
|
106
|
+
|
107
|
+
class ActiveRecordPhoto < ActiveRecordAsset
|
108
|
+
index_name 'active_record_assets'
|
109
|
+
end
|
110
|
+
|
111
|
+
# Namespaced ActiveRecord models
|
112
|
+
|
113
|
+
module ActiveRecordNamespace
|
114
|
+
def self.table_name_prefix
|
115
|
+
'active_record_namespace_'
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
class ActiveRecordNamespace::MyModel < ActiveRecord::Base
|
120
|
+
include Tire::Model::Search
|
121
|
+
include Tire::Model::Callbacks
|
122
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# Example non-ActiveModel custom wrapper for result item
|
2
|
+
|
3
|
+
class Article
|
4
|
+
attr_reader :id, :title, :body
|
5
|
+
|
6
|
+
def initialize(attributes={})
|
7
|
+
attributes.each { |k,v| instance_variable_set(:"@#{k}", v) }
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_json
|
11
|
+
{ :id => @id, :title => @title, :body => @body }.to_json
|
12
|
+
end
|
13
|
+
|
14
|
+
alias :to_indexed_json :to_json
|
15
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'mongoid'
|
2
|
+
|
3
|
+
class MongoidArticle
|
4
|
+
|
5
|
+
include Mongoid::Document
|
6
|
+
|
7
|
+
|
8
|
+
has_many :comments, :class_name => "MongoidComment", :foreign_key => "article_id"
|
9
|
+
has_many :stats, :class_name => "MongoidStat", :foreign_key => "article_id"
|
10
|
+
|
11
|
+
# def index
|
12
|
+
# "KEEP OFF MY INDEX!!!"
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# def self.settings
|
16
|
+
# "KEEP OFF MY SETTINGS!!!"
|
17
|
+
# end
|
18
|
+
|
19
|
+
include Tire::Model::Search
|
20
|
+
include Tire::Model::Callbacks
|
21
|
+
|
22
|
+
tire do
|
23
|
+
mapping do
|
24
|
+
indexes :title, :type => 'string', :boost => 10, :analyzer => 'snowball'
|
25
|
+
indexes :created_at, :type => 'date'
|
26
|
+
|
27
|
+
indexes :comments do
|
28
|
+
indexes :author
|
29
|
+
indexes :body
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# tire.mapping do
|
35
|
+
# indexes :title, :type => 'string', :boost => 10, :analyzer => 'snowball'
|
36
|
+
# end
|
37
|
+
|
38
|
+
def to_indexed_json
|
39
|
+
{
|
40
|
+
:title => title,
|
41
|
+
:length => length,
|
42
|
+
|
43
|
+
:comments => comments.map { |c| { :_type => 'mongoid_comment',
|
44
|
+
:_id => c.id,
|
45
|
+
:author => c.author,
|
46
|
+
:body => c.body } },
|
47
|
+
:stats => stats.map { |s| { :pageviews => s.pageviews } }
|
48
|
+
}.to_json
|
49
|
+
end
|
50
|
+
|
51
|
+
def length
|
52
|
+
title.length
|
53
|
+
end
|
54
|
+
|
55
|
+
def comment_authors
|
56
|
+
comments.map(&:author).to_sentence
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
class MongoidComment
|
61
|
+
|
62
|
+
include Mongoid::Document
|
63
|
+
|
64
|
+
|
65
|
+
belongs_to :article, :class_name => "MongoidArticle", :foreign_key => "article_id"
|
66
|
+
end
|
67
|
+
|
68
|
+
class MongoidStat
|
69
|
+
|
70
|
+
include Mongoid::Document
|
71
|
+
|
72
|
+
|
73
|
+
belongs_to :article, :class_name => "MongoidArticle", :foreign_key => "article_id"
|
74
|
+
end
|
75
|
+
|
76
|
+
class MongoidClassWithTireMethods
|
77
|
+
|
78
|
+
include Mongoid::Document
|
79
|
+
|
80
|
+
|
81
|
+
def self.mapping
|
82
|
+
"THIS IS MY MAPPING!"
|
83
|
+
end
|
84
|
+
|
85
|
+
def index
|
86
|
+
"THIS IS MY INDEX!"
|
87
|
+
end
|
88
|
+
|
89
|
+
include Tire::Model::Search
|
90
|
+
include Tire::Model::Callbacks
|
91
|
+
|
92
|
+
tire do
|
93
|
+
mapping do
|
94
|
+
indexes :title, :type => 'string', :analyzer => 'snowball'
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|