tire 0.1.14 → 0.1.15
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/README.markdown +1 -1
- data/examples/tire-dsl.rb +66 -19
- data/lib/tire/client.rb +1 -19
- data/lib/tire/configuration.rb +1 -1
- data/lib/tire/index.rb +74 -59
- data/lib/tire/model/search.rb +6 -6
- data/lib/tire/search/sort.rb +6 -7
- data/lib/tire/version.rb +5 -5
- data/lib/tire.rb +6 -1
- data/test/integration/active_record_searchable_test.rb +3 -3
- data/test/integration/index_mapping_test.rb +1 -1
- data/test/integration/percolator_test.rb +3 -3
- data/test/integration/sort_test.rb +2 -2
- data/test/unit/client_test.rb +0 -19
- data/test/unit/configuration_test.rb +12 -15
- data/test/unit/index_test.rb +69 -21
- data/test/unit/model_search_test.rb +14 -14
- data/test/unit/search_sort_test.rb +59 -26
- data/test/unit/search_test.rb +7 -3
- metadata +10 -12
data/README.markdown
CHANGED
data/examples/tire-dsl.rb
CHANGED
@@ -61,14 +61,56 @@ Tire.index 'articles' do
|
|
61
61
|
create
|
62
62
|
|
63
63
|
# We want to store and index some articles with `title`, `tags` and `published_on` properties.
|
64
|
-
# Simple Hashes are OK.
|
64
|
+
# Simple Hashes are OK. The default type is „document”.
|
65
65
|
#
|
66
66
|
store :title => 'One', :tags => ['ruby'], :published_on => '2011-01-01'
|
67
67
|
store :title => 'Two', :tags => ['ruby', 'python'], :published_on => '2011-01-02'
|
68
|
-
store :title => 'Three', :tags => ['java'], :published_on => '2011-01-02'
|
69
|
-
store :title => 'Four', :tags => ['ruby', 'php'], :published_on => '2011-01-03'
|
70
68
|
|
71
|
-
# We
|
69
|
+
# We usually want to set a specific _type_ for the document in _ElasticSearch_.
|
70
|
+
# Simply setting a `type` property is OK.
|
71
|
+
#
|
72
|
+
store :type => 'article',
|
73
|
+
:title => 'Three',
|
74
|
+
:tags => ['java'],
|
75
|
+
:published_on => '2011-01-02'
|
76
|
+
|
77
|
+
# We may want to wrap your data in a Ruby class, and use it when storing data.
|
78
|
+
# The contract required of such a class is very simple.
|
79
|
+
#
|
80
|
+
class Article
|
81
|
+
|
82
|
+
#
|
83
|
+
attr_reader :title, :tags, :published_on
|
84
|
+
def initialize(attributes={})
|
85
|
+
@attributes = attributes
|
86
|
+
@attributes.each_pair { |name,value| instance_variable_set :"@#{name}", value }
|
87
|
+
end
|
88
|
+
|
89
|
+
# It must provide a `type`, `_type` or `document_type` method for propper mapping.
|
90
|
+
#
|
91
|
+
def type
|
92
|
+
'article'
|
93
|
+
end
|
94
|
+
|
95
|
+
# And it must provide a `to_indexed_json` method for conversion to JSON.
|
96
|
+
#
|
97
|
+
def to_indexed_json
|
98
|
+
@attributes.to_json
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Note: Since our class takes a Hash of attributes on initialization, we may even
|
103
|
+
# wrap the results in instances of this class; we'll see how to do that further below.
|
104
|
+
#
|
105
|
+
article = Article.new :title => 'Four',
|
106
|
+
:tags => ['ruby', 'php'],
|
107
|
+
:published_on => '2011-01-03'
|
108
|
+
|
109
|
+
# Let's store the `article`, now.
|
110
|
+
#
|
111
|
+
store article
|
112
|
+
|
113
|
+
# And let's „force refresh“ the index, so we can query it immediately.
|
72
114
|
#
|
73
115
|
refresh
|
74
116
|
end
|
@@ -77,22 +119,23 @@ end
|
|
77
119
|
# for the index.
|
78
120
|
|
79
121
|
Tire.index 'articles' do
|
80
|
-
# To do so, just pass a Hash containing the specified mapping to the `Index#create` method.
|
122
|
+
# To do so, let's just pass a Hash containing the specified mapping to the `Index#create` method.
|
81
123
|
#
|
82
124
|
create :mappings => {
|
83
125
|
|
84
|
-
#
|
126
|
+
# Let's specify for which _type_ of documents this mapping should be used:
|
127
|
+
# „article”, in our case.
|
85
128
|
#
|
86
129
|
:article => {
|
87
130
|
:properties => {
|
88
131
|
|
89
|
-
#
|
132
|
+
# Let's specify the type of the field, whether it should be analyzed, ...
|
90
133
|
#
|
91
134
|
:id => { :type => 'string', :index => 'not_analyzed', :include_in_all => false },
|
92
135
|
|
93
|
-
#
|
94
|
-
# has [more information](http://elasticsearch.org/guide/reference/mapping/index.html)
|
95
|
-
#
|
136
|
+
# ... set the boost or analyzer settings for the field, etc. The _ElasticSearch_ guide
|
137
|
+
# has [more information](http://elasticsearch.org/guide/reference/mapping/index.html).
|
138
|
+
# Don't forget, that proper mapping is key to efficient and effective search.
|
96
139
|
# But don't fret about getting the mapping right the first time, you won't.
|
97
140
|
# In most cases, the default, dynamic mapping is just fine for prototyping.
|
98
141
|
#
|
@@ -116,10 +159,13 @@ articles = [
|
|
116
159
|
|
117
160
|
# Notice that such objects must have an `id` property!
|
118
161
|
#
|
119
|
-
{ :id => '1', :title => 'one', :tags => ['ruby'], :published_on => '2011-01-01' },
|
120
|
-
|
121
|
-
|
122
|
-
|
162
|
+
{ :id => '1', :type => 'article', :title => 'one', :tags => ['ruby'], :published_on => '2011-01-01' },
|
163
|
+
|
164
|
+
# And, of course, they should contain the `type` property for the mapping to work!
|
165
|
+
#
|
166
|
+
{ :id => '2', :type => 'article', :title => 'two', :tags => ['ruby', 'python'], :published_on => '2011-01-02' },
|
167
|
+
{ :id => '3', :type => 'article', :title => 'three', :tags => ['java'], :published_on => '2011-01-02' },
|
168
|
+
{ :id => '4', :type => 'article', :title => 'four', :tags => ['ruby', 'php'], :published_on => '2011-01-03' }
|
123
169
|
]
|
124
170
|
|
125
171
|
# We can just push them into the index in one go.
|
@@ -209,7 +255,7 @@ end
|
|
209
255
|
# To do that, we have to use a slight variation of the DSL.
|
210
256
|
#
|
211
257
|
|
212
|
-
# Let's assume we have a plain
|
258
|
+
# Let's assume we have a plain Ruby class, named `Article`.
|
213
259
|
#
|
214
260
|
class Article
|
215
261
|
|
@@ -219,7 +265,7 @@ class Article
|
|
219
265
|
"title:T*"
|
220
266
|
end
|
221
267
|
|
222
|
-
# ... and wrap the _Tire_ search method.
|
268
|
+
# ... and wrap the _Tire_ search method in another one.
|
223
269
|
def self.search
|
224
270
|
|
225
271
|
# Notice how we pass the `search` object around as a block argument.
|
@@ -298,13 +344,14 @@ Tire.configure do
|
|
298
344
|
#
|
299
345
|
url "http://search.example.com"
|
300
346
|
|
301
|
-
# Second, we may want to wrap the result items in our own class
|
347
|
+
# Second, we may want to wrap the result items in our own class, for instance
|
348
|
+
# the `Article` class set above.
|
302
349
|
#
|
303
|
-
|
304
|
-
wrapper MySpecialWrapper
|
350
|
+
wrapper Article
|
305
351
|
|
306
352
|
# Finally, we can reset one or all configuration settings to their defaults.
|
307
353
|
#
|
354
|
+
reset :url
|
308
355
|
reset
|
309
356
|
|
310
357
|
end
|
data/lib/tire/client.rb
CHANGED
@@ -2,25 +2,7 @@ module Tire
|
|
2
2
|
|
3
3
|
module Client
|
4
4
|
|
5
|
-
class
|
6
|
-
def get(url, data=nil)
|
7
|
-
raise_no_method_error
|
8
|
-
end
|
9
|
-
def post(url, data)
|
10
|
-
raise_no_method_error
|
11
|
-
end
|
12
|
-
def put(url, data)
|
13
|
-
raise NoMethodError, "Implement this method in your client class"
|
14
|
-
end
|
15
|
-
def delete(url)
|
16
|
-
raise_no_method_error
|
17
|
-
end
|
18
|
-
def raise_no_method_error
|
19
|
-
raise NoMethodError, "Implement this method in your client class"
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
class RestClient < Base
|
5
|
+
class RestClient
|
24
6
|
def self.get(url, data=nil)
|
25
7
|
::RestClient::Request.new(:method => :get, :url => url, :payload => data).execute
|
26
8
|
end
|
data/lib/tire/configuration.rb
CHANGED
data/lib/tire/index.rb
CHANGED
@@ -41,13 +41,20 @@ module Tire
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def store(*args)
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
44
|
+
case
|
45
|
+
when ( args.size === 3 && (args.first.is_a?(String) || args.first.is_a?(Symbol)) )
|
46
|
+
Tire.warn "Passing the document type as argument in Index#store has been deprecated, " +
|
47
|
+
"please pass a Hash with _type/type property, or " +
|
48
|
+
"an object with _type/type/document_type method."
|
49
|
+
type, document, options = args
|
50
|
+
when ( args.size === 2 && (args.first.is_a?(String) || args.first.is_a?(Symbol)) )
|
51
|
+
Tire.warn "Passing the document type as argument in Index#store has been deprecated" +
|
52
|
+
"please pass a Hash with _type/type property, or " +
|
53
|
+
"an object with _type/type/document_type method."
|
54
|
+
type, document = args
|
55
|
+
else
|
56
|
+
document, options = args
|
57
|
+
type = get_type_from_document(document)
|
51
58
|
end
|
52
59
|
|
53
60
|
if options
|
@@ -55,18 +62,8 @@ module Tire
|
|
55
62
|
percolate = "*" if percolate === true
|
56
63
|
end
|
57
64
|
|
58
|
-
|
59
|
-
|
60
|
-
when document.is_a?(Hash) then document[:id] || document['id']
|
61
|
-
when document.respond_to?(:id) && document.id != document.object_id then document.id
|
62
|
-
end
|
63
|
-
$VERBOSE = old_verbose
|
64
|
-
|
65
|
-
document = case true
|
66
|
-
when document.is_a?(String) then document
|
67
|
-
when document.respond_to?(:to_indexed_json) then document.to_indexed_json
|
68
|
-
else raise ArgumentError, "Please pass a JSON string or object with a 'to_indexed_json' method"
|
69
|
-
end
|
65
|
+
id = get_id_from_document(document)
|
66
|
+
document = convert_document_to_json(document)
|
70
67
|
|
71
68
|
url = id ? "#{Configuration.url}/#{@name}/#{type}/#{id}" : "#{Configuration.url}/#{@name}/#{type}/"
|
72
69
|
url += "?percolate=#{percolate}" if percolate
|
@@ -83,22 +80,14 @@ module Tire
|
|
83
80
|
|
84
81
|
def bulk_store documents
|
85
82
|
payload = documents.map do |document|
|
86
|
-
|
87
|
-
|
88
|
-
when document.is_a?(Hash) then document[:id] || document['id']
|
89
|
-
when document.respond_to?(:id) && document.id != document.object_id then document.id
|
90
|
-
# TODO: Raise error when no id present
|
91
|
-
end
|
92
|
-
$VERBOSE = old_verbose
|
83
|
+
id = get_id_from_document(document)
|
84
|
+
type = get_type_from_document(document)
|
93
85
|
|
94
|
-
|
95
|
-
when document.is_a?(Hash) then document[:type] || document['type']
|
96
|
-
when document.respond_to?(:document_type) then document.document_type
|
97
|
-
end || 'document'
|
86
|
+
STDERR.puts "[ERROR] Document #{document.inspect} does not have ID" unless id
|
98
87
|
|
99
88
|
output = []
|
100
89
|
output << %Q|{"index":{"_index":"#{@name}","_type":"#{type}","_id":"#{id}"}}|
|
101
|
-
output << document
|
90
|
+
output << convert_document_to_json(document)
|
102
91
|
output.join("\n")
|
103
92
|
end
|
104
93
|
payload << ""
|
@@ -107,8 +96,6 @@ module Tire
|
|
107
96
|
count = 0
|
108
97
|
|
109
98
|
begin
|
110
|
-
# STDERR.puts "Posting payload..."
|
111
|
-
# STDERR.puts payload.join("\n")
|
112
99
|
Configuration.client.post("#{Configuration.url}/_bulk", payload.join("\n"))
|
113
100
|
rescue Exception => error
|
114
101
|
if count < tries
|
@@ -127,14 +114,11 @@ module Tire
|
|
127
114
|
end
|
128
115
|
|
129
116
|
def import(klass_or_collection, method=nil, options={})
|
130
|
-
# p [klass_or_collection, method, options]
|
131
|
-
|
132
117
|
case
|
133
|
-
|
134
118
|
when method
|
135
119
|
options = {:page => 1, :per_page => 1000}.merge options
|
136
120
|
while documents = klass_or_collection.send(method.to_sym, options.merge(:page => options[:page])) \
|
137
|
-
and
|
121
|
+
and documents.size > 0
|
138
122
|
documents = yield documents if block_given?
|
139
123
|
|
140
124
|
bulk_store documents
|
@@ -144,34 +128,31 @@ module Tire
|
|
144
128
|
when klass_or_collection.respond_to?(:map)
|
145
129
|
documents = block_given? ? yield(klass_or_collection) : klass_or_collection
|
146
130
|
bulk_store documents
|
131
|
+
|
147
132
|
else
|
148
|
-
raise ArgumentError, "Please pass either a collection of objects, "+
|
133
|
+
raise ArgumentError, "Please pass either a collection of objects, " +
|
149
134
|
"or method for fetching records, or Enumerable compatible class"
|
150
135
|
end
|
151
136
|
end
|
152
137
|
|
153
138
|
def remove(*args)
|
154
|
-
# TODO: Infer type from the document (hash property, method)
|
155
|
-
|
156
139
|
if args.size > 1
|
157
|
-
|
140
|
+
type, document = args
|
141
|
+
id = get_id_from_document(document) || document
|
158
142
|
else
|
159
|
-
|
143
|
+
document = args.pop
|
144
|
+
type = get_type_from_document(document)
|
145
|
+
id = get_id_from_document(document) || document
|
160
146
|
end
|
161
|
-
|
162
|
-
old_verbose, $VERBOSE = $VERBOSE, nil # Silence Object#id deprecation warnings
|
163
|
-
id = case true
|
164
|
-
when document.is_a?(Hash) then document[:id] || document['id']
|
165
|
-
when document.respond_to?(:id) && document.id != document.object_id then document.id
|
166
|
-
else document
|
167
|
-
end
|
168
|
-
$VERBOSE = old_verbose
|
147
|
+
raise ArgumentError, "Please pass a document ID" unless id
|
169
148
|
|
170
149
|
result = Configuration.client.delete "#{Configuration.url}/#{@name}/#{type}/#{id}"
|
171
150
|
MultiJson.decode(result) if result
|
172
151
|
end
|
173
152
|
|
174
153
|
def retrieve(type, id)
|
154
|
+
raise ArgumentError, "Please pass a document ID" unless id
|
155
|
+
|
175
156
|
@response = Configuration.client.get "#{Configuration.url}/#{@name}/#{type}/#{id}"
|
176
157
|
h = MultiJson.decode(@response.body)
|
177
158
|
if Configuration.wrapper == Hash then h
|
@@ -237,19 +218,17 @@ module Tire
|
|
237
218
|
end
|
238
219
|
|
239
220
|
def percolate(*args, &block)
|
240
|
-
# TODO: Infer type from the document (hash property, method)
|
241
|
-
|
242
221
|
if args.size > 1
|
243
|
-
|
222
|
+
Tire.warn "Passing the document type as argument in Index#percolate has been deprecated, " +
|
223
|
+
"please pass a Hash with _type/type property, or " +
|
224
|
+
"an object with _type/type/document_type method."
|
225
|
+
type, document = args
|
244
226
|
else
|
245
|
-
|
227
|
+
document = args.pop
|
228
|
+
type = get_type_from_document(document)
|
246
229
|
end
|
247
230
|
|
248
|
-
document =
|
249
|
-
when document.is_a?(String) then document
|
250
|
-
when document.respond_to?(:to_hash) then document.to_hash
|
251
|
-
else raise ArgumentError, "Please pass a JSON string or object with a 'to_hash' method"
|
252
|
-
end
|
231
|
+
document = MultiJson.decode convert_document_to_json(document)
|
253
232
|
|
254
233
|
query = Search::Query.new(&block).to_hash if block_given?
|
255
234
|
|
@@ -288,5 +267,41 @@ module Tire
|
|
288
267
|
end
|
289
268
|
end
|
290
269
|
|
270
|
+
def get_type_from_document(document)
|
271
|
+
old_verbose, $VERBOSE = $VERBOSE, nil # Silence Object#type deprecation warnings
|
272
|
+
type = case
|
273
|
+
when document.respond_to?(:document_type)
|
274
|
+
document.document_type
|
275
|
+
when document.is_a?(Hash)
|
276
|
+
document.delete(:_type) || document.delete('_type') || document.delete(:type) || document.delete('type')
|
277
|
+
when document.respond_to?(:_type)
|
278
|
+
document._type
|
279
|
+
when document.respond_to?(:type) && document.type != document.class
|
280
|
+
document.type
|
281
|
+
end
|
282
|
+
$VERBOSE = old_verbose
|
283
|
+
type ||= :document
|
284
|
+
end
|
285
|
+
|
286
|
+
def get_id_from_document(document)
|
287
|
+
old_verbose, $VERBOSE = $VERBOSE, nil # Silence Object#id deprecation warnings
|
288
|
+
id = case
|
289
|
+
when document.is_a?(Hash)
|
290
|
+
document[:_id] || document['_id'] || document[:id] || document['id']
|
291
|
+
when document.respond_to?(:id) && document.id != document.object_id
|
292
|
+
document.id
|
293
|
+
end
|
294
|
+
$VERBOSE = old_verbose
|
295
|
+
id
|
296
|
+
end
|
297
|
+
|
298
|
+
def convert_document_to_json(document)
|
299
|
+
document = case
|
300
|
+
when document.is_a?(String) then document
|
301
|
+
when document.respond_to?(:to_indexed_json) then document.to_indexed_json
|
302
|
+
else raise ArgumentError, "Please pass a JSON string or object with a 'to_indexed_json' method"
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
291
306
|
end
|
292
307
|
end
|
data/lib/tire/model/search.rb
CHANGED
@@ -35,15 +35,14 @@ module Tire
|
|
35
35
|
def search(query=nil, options={}, &block)
|
36
36
|
old_wrapper = Tire::Configuration.wrapper
|
37
37
|
Tire::Configuration.wrapper self
|
38
|
-
sort = options[:order] || options[:sort]
|
39
|
-
sort = Array(sort)
|
38
|
+
sort = Array( options[:order] || options[:sort] )
|
40
39
|
unless block_given?
|
41
40
|
s = Tire::Search::Search.new(elasticsearch_index.name, options)
|
42
41
|
s.query { string query }
|
43
42
|
s.sort do
|
44
43
|
sort.each do |t|
|
45
44
|
field_name, direction = t.split(' ')
|
46
|
-
|
45
|
+
by field_name, direction
|
47
46
|
end
|
48
47
|
end unless sort.empty?
|
49
48
|
s.size( options[:per_page].to_i ) if options[:per_page]
|
@@ -75,7 +74,7 @@ module Tire
|
|
75
74
|
module InstanceMethods
|
76
75
|
|
77
76
|
def score
|
78
|
-
|
77
|
+
Tire.warn "#{self.class}#score has been deprecated, please use #{self.class}#_score instead."
|
79
78
|
attributes['_score']
|
80
79
|
end
|
81
80
|
|
@@ -86,9 +85,9 @@ module Tire
|
|
86
85
|
def update_elastic_search_index
|
87
86
|
_run_update_elastic_search_index_callbacks do
|
88
87
|
if destroyed?
|
89
|
-
index.remove
|
88
|
+
index.remove self
|
90
89
|
else
|
91
|
-
response = index.store(
|
90
|
+
response = index.store( self, {:percolate => self.percolator} )
|
92
91
|
self.id ||= response['_id'] if self.respond_to?(:id=)
|
93
92
|
self._index = response['_index']
|
94
93
|
self._type = response['_type']
|
@@ -98,6 +97,7 @@ module Tire
|
|
98
97
|
end
|
99
98
|
end
|
100
99
|
end
|
100
|
+
alias :update_elasticsearch_index :update_elastic_search_index
|
101
101
|
|
102
102
|
def to_indexed_json
|
103
103
|
if self.class.mapping.empty?
|
data/lib/tire/search/sort.rb
CHANGED
@@ -4,20 +4,19 @@ module Tire
|
|
4
4
|
class Sort
|
5
5
|
def initialize(&block)
|
6
6
|
@value = []
|
7
|
-
self.instance_eval(&block) if block_given?
|
7
|
+
block.arity < 1 ? self.instance_eval(&block) : block.call(self) if block_given?
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
10
|
+
def by(name, direction=nil)
|
11
11
|
@value << ( direction ? { name => direction } : name )
|
12
12
|
self
|
13
13
|
end
|
14
14
|
|
15
15
|
def method_missing(id, *args, &block)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
self
|
16
|
+
Tire.warn "Using methods when sorting has been deprecated, please use the `by` method: " +
|
17
|
+
"sort { by :#{id}#{ args.empty? ? '' : ', ' + args.first.inspect } }"
|
18
|
+
|
19
|
+
by id, args.shift
|
21
20
|
end
|
22
21
|
|
23
22
|
def to_ary
|
data/lib/tire/version.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
module Tire
|
2
|
-
VERSION = "0.1.
|
2
|
+
VERSION = "0.1.15"
|
3
3
|
|
4
4
|
CHANGELOG =<<-END
|
5
5
|
IMPORTANT CHANGES LATELY:
|
6
6
|
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
7
|
+
# Cleanup of code for getting document type, id, JSON serialization
|
8
|
+
# Bunch of deprecations: sorting, passing document type to store/remove
|
9
|
+
# Displaying a warning when no ID is passed when storing in bulk
|
10
|
+
# Correct handling of import for Mongoid/Kaminari combos
|
11
11
|
END
|
12
12
|
end
|
data/lib/tire.rb
CHANGED
@@ -7,7 +7,6 @@ require 'tire/rubyext/symbol'
|
|
7
7
|
require 'tire/logger'
|
8
8
|
require 'tire/configuration'
|
9
9
|
require 'tire/client'
|
10
|
-
require 'tire/client'
|
11
10
|
require 'tire/search'
|
12
11
|
require 'tire/search/query'
|
13
12
|
require 'tire/search/sort'
|
@@ -33,4 +32,10 @@ require 'tire/tasks'
|
|
33
32
|
|
34
33
|
module Tire
|
35
34
|
extend DSL
|
35
|
+
|
36
|
+
def warn(message)
|
37
|
+
line = caller.detect { |line| line !~ %r|lib\/tire\/| }.sub(/:in .*/, '')
|
38
|
+
STDERR.puts "", "\e[31m[DEPRECATION WARNING] #{message}", "(Called from #{line})", "\e[0m"
|
39
|
+
end
|
40
|
+
module_function :warn
|
36
41
|
end
|
@@ -132,7 +132,7 @@ module Tire
|
|
132
132
|
should "find first page with five results" do
|
133
133
|
results = ActiveRecordArticle.search do |search|
|
134
134
|
search.query { |query| query.string @q }
|
135
|
-
search.sort { title }
|
135
|
+
search.sort { by :title }
|
136
136
|
search.from 0
|
137
137
|
search.size 5
|
138
138
|
end
|
@@ -149,7 +149,7 @@ module Tire
|
|
149
149
|
should "find next page with five results" do
|
150
150
|
results = ActiveRecordArticle.search do |search|
|
151
151
|
search.query { |query| query.string @q }
|
152
|
-
search.sort { title }
|
152
|
+
search.sort { by :title }
|
153
153
|
search.from 5
|
154
154
|
search.size 5
|
155
155
|
end
|
@@ -166,7 +166,7 @@ module Tire
|
|
166
166
|
should "not find a missing page" do
|
167
167
|
results = ActiveRecordArticle.search do |search|
|
168
168
|
search.query { |query| query.string @q }
|
169
|
-
search.sort { title }
|
169
|
+
search.sort { by :title }
|
170
170
|
search.from 10
|
171
171
|
search.size 5
|
172
172
|
end
|
@@ -83,17 +83,17 @@ module Tire
|
|
83
83
|
end
|
84
84
|
|
85
85
|
should "return an empty array when no query matches" do
|
86
|
-
response = @index.store
|
86
|
+
response = @index.store( {:message => 'Situation normal'}, {:percolate => true} )
|
87
87
|
assert_equal [], response['matches']
|
88
88
|
end
|
89
89
|
|
90
90
|
should "return an array of matching query names" do
|
91
|
-
response = @index.store
|
91
|
+
response = @index.store( {:message => 'Severe weather warning'}, {:percolate => true} )
|
92
92
|
assert_equal ['alert','weather'], response['matches'].sort
|
93
93
|
end
|
94
94
|
|
95
95
|
should "return an array of matching query names for specific percolated queries" do
|
96
|
-
response = @index.store
|
96
|
+
response = @index.store( {:message => 'Severe weather warning'}, {:percolate => 'tags:weather'} )
|
97
97
|
assert_equal ['weather'], response['matches']
|
98
98
|
end
|
99
99
|
end
|
@@ -11,7 +11,7 @@ module Tire
|
|
11
11
|
q = '*'
|
12
12
|
s = Tire.search('articles-test') do
|
13
13
|
query { string q }
|
14
|
-
sort { title }
|
14
|
+
sort { by :title }
|
15
15
|
end
|
16
16
|
|
17
17
|
assert_equal 5, s.results.count
|
@@ -22,7 +22,7 @@ module Tire
|
|
22
22
|
q = '*'
|
23
23
|
s = Tire.search('articles-test') do
|
24
24
|
query { string q }
|
25
|
-
sort { title :desc }
|
25
|
+
sort { by :title, :desc }
|
26
26
|
end
|
27
27
|
|
28
28
|
assert_equal 5, s.results.count
|
data/test/unit/client_test.rb
CHANGED
@@ -4,25 +4,6 @@ module Tire
|
|
4
4
|
|
5
5
|
class ClientTest < Test::Unit::TestCase
|
6
6
|
|
7
|
-
context "Base" do
|
8
|
-
setup { @http ||= Client::Base.new }
|
9
|
-
|
10
|
-
should "have abstract methods" do
|
11
|
-
assert_raise(ArgumentError) { @http.get }
|
12
|
-
assert_raise(NoMethodError) { @http.get 'URL' }
|
13
|
-
|
14
|
-
assert_raise(ArgumentError) { @http.post }
|
15
|
-
assert_raise(ArgumentError) { @http.post 'URL' }
|
16
|
-
assert_raise(NoMethodError) { @http.post 'URL', 'DATA' }
|
17
|
-
|
18
|
-
assert_raise(ArgumentError) { @http.put }
|
19
|
-
assert_raise(ArgumentError) { @http.put 'URL' }
|
20
|
-
|
21
|
-
assert_raise(ArgumentError) { @http.delete }
|
22
|
-
assert_raise(NoMethodError) { @http.delete 'URL' }
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
7
|
context "RestClient" do
|
27
8
|
|
28
9
|
should "be default" do
|
@@ -27,13 +27,13 @@ module Tire
|
|
27
27
|
assert_equal 'http://example.com', Configuration.url
|
28
28
|
end
|
29
29
|
|
30
|
-
should "
|
31
|
-
|
30
|
+
should "strip trailing slash from the URL" do
|
31
|
+
assert_nothing_raised { Configuration.url 'http://slash.com:9200/' }
|
32
|
+
assert_equal 'http://slash.com:9200', Configuration.url
|
32
33
|
end
|
33
34
|
|
34
|
-
should "
|
35
|
-
|
36
|
-
assert_equal Client::Base, Configuration.client
|
35
|
+
should "return default client" do
|
36
|
+
assert_equal Client::RestClient, Configuration.client
|
37
37
|
end
|
38
38
|
|
39
39
|
should "return nil as logger by default" do
|
@@ -48,21 +48,18 @@ module Tire
|
|
48
48
|
|
49
49
|
should "allow to reset the configuration for specific property" do
|
50
50
|
Configuration.url 'http://example.com'
|
51
|
-
Configuration.
|
52
|
-
assert_equal 'http://example.com', Configuration.url
|
51
|
+
assert_equal 'http://example.com', Configuration.url
|
53
52
|
Configuration.reset :url
|
54
|
-
assert_equal
|
55
|
-
assert_equal Client::Base, Configuration.client
|
53
|
+
assert_equal 'http://localhost:9200', Configuration.url
|
56
54
|
end
|
57
55
|
|
58
56
|
should "allow to reset the configuration for all properties" do
|
59
|
-
Configuration.url
|
60
|
-
Configuration.
|
61
|
-
assert_equal
|
62
|
-
assert_equal Client::Base, Configuration.client
|
57
|
+
Configuration.url 'http://example.com'
|
58
|
+
Configuration.wrapper Hash
|
59
|
+
assert_equal 'http://example.com', Configuration.url
|
63
60
|
Configuration.reset
|
64
|
-
assert_equal
|
65
|
-
assert_equal
|
61
|
+
assert_equal 'http://localhost:9200', Configuration.url
|
62
|
+
assert_equal Client::RestClient, Configuration.client
|
66
63
|
end
|
67
64
|
end
|
68
65
|
|
data/test/unit/index_test.rb
CHANGED
@@ -101,10 +101,42 @@ module Tire
|
|
101
101
|
|
102
102
|
context "when storing" do
|
103
103
|
|
104
|
-
should "
|
105
|
-
Configuration.client.expects(:post).with
|
106
|
-
|
107
|
-
|
104
|
+
should "set type from Hash :type property" do
|
105
|
+
Configuration.client.expects(:post).with do |url,document|
|
106
|
+
url == "#{Configuration.url}/dummy/article/"
|
107
|
+
end.returns(mock_response('{"ok":true,"_id":"test"}'))
|
108
|
+
@index.store :type => 'article', :title => 'Test'
|
109
|
+
end
|
110
|
+
|
111
|
+
should "set type from Hash :_type property" do
|
112
|
+
Configuration.client.expects(:post).with do |url,document|
|
113
|
+
url == "#{Configuration.url}/dummy/article/"
|
114
|
+
end.returns(mock_response('{"ok":true,"_id":"test"}'))
|
115
|
+
@index.store :_type => 'article', :title => 'Test'
|
116
|
+
end
|
117
|
+
|
118
|
+
should "set type from Object _type method" do
|
119
|
+
Configuration.client.expects(:post).with do |url,document|
|
120
|
+
url == "#{Configuration.url}/dummy/article/"
|
121
|
+
end.returns(mock_response('{"ok":true,"_id":"test"}'))
|
122
|
+
|
123
|
+
article = Class.new do
|
124
|
+
def _type; 'article'; end
|
125
|
+
def to_indexed_json; "{}"; end
|
126
|
+
end.new
|
127
|
+
@index.store article
|
128
|
+
end
|
129
|
+
|
130
|
+
should "set type from Object type method" do
|
131
|
+
Configuration.client.expects(:post).with do |url,document|
|
132
|
+
url == "#{Configuration.url}/dummy/article/"
|
133
|
+
end.returns(mock_response('{"ok":true,"_id":"test"}'))
|
134
|
+
|
135
|
+
article = Class.new do
|
136
|
+
def type; 'article'; end
|
137
|
+
def to_indexed_json; "{}"; end
|
138
|
+
end.new
|
139
|
+
@index.store article
|
108
140
|
end
|
109
141
|
|
110
142
|
should "set default type" do
|
@@ -151,7 +183,7 @@ module Tire
|
|
151
183
|
|
152
184
|
Configuration.client.stubs(:post).with("#{Configuration.url}/dummy/article/", '{"title":"Test"}').
|
153
185
|
returns(mock_response('{"ok":true,"_id":"id-1"}'))
|
154
|
-
@index.store :article, :title => 'Test'
|
186
|
+
@index.store :type => 'article', :title => 'Test'
|
155
187
|
end
|
156
188
|
|
157
189
|
should "return document in default wrapper" do
|
@@ -182,21 +214,27 @@ module Tire
|
|
182
214
|
assert_equal 'Test', article.title
|
183
215
|
end
|
184
216
|
|
217
|
+
should "raise error when no ID passed" do
|
218
|
+
assert_raise ArgumentError do
|
219
|
+
@index.retrieve 'article', nil
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
185
223
|
end
|
186
224
|
|
187
225
|
context "when removing" do
|
188
226
|
|
189
|
-
should "
|
190
|
-
Configuration.client.expects(:delete).with("#{Configuration.url}/dummy/article/").
|
191
|
-
returns('{"ok":true,"_id":"
|
192
|
-
@index.remove 'article', :title => 'Test'
|
193
|
-
@index.remove :article,
|
227
|
+
should "get type from document" do
|
228
|
+
Configuration.client.expects(:delete).with("#{Configuration.url}/dummy/article/1").
|
229
|
+
returns('{"ok":true,"_id":"1"}').twice
|
230
|
+
@index.remove :id => 1, :type => 'article', :title => 'Test'
|
231
|
+
@index.remove :id => 1, :type => 'article', :title => 'Test'
|
194
232
|
end
|
195
233
|
|
196
234
|
should "set default type" do
|
197
|
-
Configuration.client.expects(:delete).with("#{Configuration.url}/dummy/document/").
|
198
|
-
returns('{"ok":true,"_id":"
|
199
|
-
@index.remove :title => 'Test'
|
235
|
+
Configuration.client.expects(:delete).with("#{Configuration.url}/dummy/document/1").
|
236
|
+
returns('{"ok":true,"_id":"1"}')
|
237
|
+
@index.remove :id => 1, :title => 'Test'
|
200
238
|
end
|
201
239
|
|
202
240
|
should "get ID from hash" do
|
@@ -212,10 +250,16 @@ module Tire
|
|
212
250
|
@index.remove document
|
213
251
|
end
|
214
252
|
|
215
|
-
should "get ID from arguments" do
|
216
|
-
Configuration.client.expects(:delete).with("#{Configuration.url}/dummy/
|
253
|
+
should "get type and ID from arguments" do
|
254
|
+
Configuration.client.expects(:delete).with("#{Configuration.url}/dummy/article/1").
|
217
255
|
returns('{"ok":true,"_id":"1"}')
|
218
|
-
@index.remove :
|
256
|
+
@index.remove :article, 1
|
257
|
+
end
|
258
|
+
|
259
|
+
should "raise error when no ID passed" do
|
260
|
+
assert_raise ArgumentError do
|
261
|
+
@index.remove :document, nil
|
262
|
+
end
|
219
263
|
end
|
220
264
|
|
221
265
|
end
|
@@ -275,8 +319,12 @@ module Tire
|
|
275
319
|
end
|
276
320
|
end
|
277
321
|
|
278
|
-
|
279
|
-
|
322
|
+
should "raise exception when collection item does not have ID" do
|
323
|
+
Configuration.client.expects(:post).with { |url, json| url == "#{Configuration.url}/_bulk" }
|
324
|
+
STDERR.expects(:puts).once
|
325
|
+
|
326
|
+
documents = [ { :title => 'Bogus' }, { :title => 'Real', :id => 1 } ]
|
327
|
+
ActiveModelArticle.elasticsearch_index.bulk_store documents
|
280
328
|
end
|
281
329
|
|
282
330
|
end
|
@@ -479,7 +527,7 @@ module Tire
|
|
479
527
|
end.
|
480
528
|
returns(mock_response('{"ok":true,"_id":"test","matches":["alerts"]}'))
|
481
529
|
|
482
|
-
matches = @index.percolate :article, :title => 'Test'
|
530
|
+
matches = @index.percolate :type => 'article', :title => 'Test'
|
483
531
|
assert_equal ["alerts"], matches
|
484
532
|
end
|
485
533
|
|
@@ -502,13 +550,13 @@ module Tire
|
|
502
550
|
should "percolate document against all registered queries" do
|
503
551
|
Configuration.client.expects(:post).with("#{Configuration.url}/dummy/article/?percolate=*", '{"title":"Test"}').
|
504
552
|
returns(mock_response('{"ok":true,"_id":"test","matches":["alerts"]}'))
|
505
|
-
@index.store :article,
|
553
|
+
@index.store( {:type => 'article', :title => 'Test'}, {:percolate => true} )
|
506
554
|
end
|
507
555
|
|
508
556
|
should "percolate document against specific queries" do
|
509
557
|
Configuration.client.expects(:post).with("#{Configuration.url}/dummy/article/?percolate=tag:alerts", '{"title":"Test"}').
|
510
558
|
returns(mock_response('{"ok":true,"_id":"test","matches":["alerts"]}'))
|
511
|
-
response = @index.store :article,
|
559
|
+
response = @index.store( {:type => 'article', :title => 'Test'}, {:percolate => 'tag:alerts'} )
|
512
560
|
assert_equal response['matches'], ['alerts']
|
513
561
|
end
|
514
562
|
|
@@ -96,7 +96,7 @@ module Tire
|
|
96
96
|
document = collection.first
|
97
97
|
|
98
98
|
assert_instance_of ActiveModelArticle, document
|
99
|
-
assert_not_nil document.
|
99
|
+
assert_not_nil document._score
|
100
100
|
assert_equal 1, document.id
|
101
101
|
assert_equal 'Article', document.title
|
102
102
|
end
|
@@ -139,26 +139,26 @@ module Tire
|
|
139
139
|
end
|
140
140
|
|
141
141
|
should "allow to pass :order option" do
|
142
|
-
Tire::Search::Sort.any_instance.expects(:title)
|
142
|
+
Tire::Search::Sort.any_instance.expects(:by).with('title', nil)
|
143
143
|
|
144
144
|
ActiveModelArticle.search @q, :order => 'title'
|
145
145
|
end
|
146
146
|
|
147
147
|
should "allow to pass :sort option as :order option" do
|
148
|
-
Tire::Search::Sort.any_instance.expects(:title)
|
148
|
+
Tire::Search::Sort.any_instance.expects(:by).with('title', nil)
|
149
149
|
|
150
150
|
ActiveModelArticle.search @q, :sort => 'title'
|
151
151
|
end
|
152
152
|
|
153
153
|
should "allow to specify sort direction" do
|
154
|
-
Tire::Search::Sort.any_instance.expects(:
|
154
|
+
Tire::Search::Sort.any_instance.expects(:by).with('title', 'DESC')
|
155
155
|
|
156
156
|
ActiveModelArticle.search @q, :order => 'title DESC'
|
157
157
|
end
|
158
158
|
|
159
159
|
should "allow to specify more fields to sort on" do
|
160
|
-
Tire::Search::Sort.any_instance.expects(:
|
161
|
-
Tire::Search::Sort.any_instance.expects(:
|
160
|
+
Tire::Search::Sort.any_instance.expects(:by).with('title', 'DESC')
|
161
|
+
Tire::Search::Sort.any_instance.expects(:by).with('author.name', nil)
|
162
162
|
|
163
163
|
ActiveModelArticle.search @q, :order => ['title DESC', 'author.name']
|
164
164
|
end
|
@@ -417,8 +417,8 @@ module Tire
|
|
417
417
|
should "mark the instance for percolation on index update" do
|
418
418
|
@article.percolate = true
|
419
419
|
|
420
|
-
Tire::Index.any_instance.expects(:store).with do |
|
421
|
-
# p [
|
420
|
+
Tire::Index.any_instance.expects(:store).with do |doc,options|
|
421
|
+
# p [doc,options]
|
422
422
|
options[:percolate] == true
|
423
423
|
end.returns(MultiJson.decode('{"ok":true,"_id":"test","matches":["alerts"]}'))
|
424
424
|
|
@@ -426,8 +426,8 @@ module Tire
|
|
426
426
|
end
|
427
427
|
|
428
428
|
should "not percolate document on index update when not set for percolation" do
|
429
|
-
Tire::Index.any_instance.expects(:store).with do |
|
430
|
-
# p [
|
429
|
+
Tire::Index.any_instance.expects(:store).with do |doc,options|
|
430
|
+
# p [doc,options]
|
431
431
|
options[:percolate] == nil
|
432
432
|
end.returns(MultiJson.decode('{"ok":true,"_id":"test"}'))
|
433
433
|
|
@@ -455,8 +455,8 @@ module Tire
|
|
455
455
|
percolate!
|
456
456
|
end
|
457
457
|
|
458
|
-
Tire::Index.any_instance.expects(:store).with do |
|
459
|
-
# p [
|
458
|
+
Tire::Index.any_instance.expects(:store).with do |doc,options|
|
459
|
+
# p [doc,options]
|
460
460
|
options[:percolate] == true
|
461
461
|
end.returns(MultiJson.decode('{"ok":true,"_id":"test","matches":["alerts"]}'))
|
462
462
|
|
@@ -472,7 +472,7 @@ module Tire
|
|
472
472
|
percolated = ActiveModelArticleWithPercolation.new :title => 'Percolate me!'
|
473
473
|
|
474
474
|
Tire::Index.any_instance.expects(:store).
|
475
|
-
with do |
|
475
|
+
with do |doc,options|
|
476
476
|
doc == percolated &&
|
477
477
|
options[:percolate] == true
|
478
478
|
end.
|
@@ -491,7 +491,7 @@ module Tire
|
|
491
491
|
percolated = ActiveModelArticleWithPercolation.new :title => 'Percolate me!'
|
492
492
|
|
493
493
|
Tire::Index.any_instance.expects(:store).
|
494
|
-
with do |
|
494
|
+
with do |doc,options|
|
495
495
|
doc == percolated &&
|
496
496
|
options[:percolate] == 'tags:alert'
|
497
497
|
end.
|
@@ -6,41 +6,74 @@ module Tire::Search
|
|
6
6
|
|
7
7
|
context "Sort" do
|
8
8
|
|
9
|
-
|
10
|
-
assert_respond_to Sort.new, :to_json
|
11
|
-
end
|
9
|
+
context "with the old interface" do
|
12
10
|
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
should "encode simple strings" do
|
12
|
+
assert_equal [:foo].to_json, Sort.new.foo.to_json
|
13
|
+
end
|
16
14
|
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
should "encode method arguments" do
|
16
|
+
assert_equal [:foo => 'desc'].to_json, Sort.new.foo('desc').to_json
|
17
|
+
end
|
20
18
|
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
should "encode hash" do
|
20
|
+
assert_equal [ :foo => { :reverse => true } ].to_json, Sort.new.foo(:reverse => true).to_json
|
21
|
+
end
|
24
22
|
|
25
|
-
|
26
|
-
|
27
|
-
|
23
|
+
should "encode multiple sort fields" do
|
24
|
+
assert_equal [:foo, :bar].to_json, Sort.new.foo.bar.to_json
|
25
|
+
end
|
28
26
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
27
|
+
should "encode fields when passed as a block to constructor with deprecated interface" do
|
28
|
+
s = Sort.new do
|
29
|
+
foo
|
30
|
+
bar 'desc'
|
31
|
+
_score
|
32
|
+
end
|
33
|
+
assert_equal [ :foo, {:bar => 'desc'}, :_score ].to_json, s.to_json
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
end
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
context "with the new interface" do
|
39
|
+
|
40
|
+
should "be serialized to JSON" do
|
41
|
+
assert_respond_to Sort.new, :to_json
|
42
|
+
end
|
43
|
+
|
44
|
+
should "encode simple strings" do
|
45
|
+
assert_equal [:foo].to_json, Sort.new.by(:foo).to_json
|
46
|
+
end
|
47
|
+
|
48
|
+
should "encode method arguments" do
|
49
|
+
assert_equal [:foo => 'desc'].to_json, Sort.new.by(:foo, 'desc').to_json
|
50
|
+
end
|
51
|
+
|
52
|
+
should "encode hash" do
|
53
|
+
assert_equal [ :foo => { :reverse => true } ].to_json, Sort.new.by(:foo, :reverse => true).to_json
|
54
|
+
end
|
55
|
+
|
56
|
+
should "encode multiple sort fields in chain" do
|
57
|
+
assert_equal [:foo, :bar].to_json, Sort.new.by(:foo).by(:bar).to_json
|
58
|
+
end
|
59
|
+
|
60
|
+
should "encode fields when passed as a block to constructor" do
|
61
|
+
s = Sort.new do
|
62
|
+
by :foo
|
63
|
+
by :bar, 'desc'
|
64
|
+
by :_score
|
65
|
+
end
|
66
|
+
assert_equal [ :foo, {:bar => 'desc'}, :_score ].to_json, s.to_json
|
67
|
+
end
|
68
|
+
|
69
|
+
should "encode fields deeper in json" do
|
70
|
+
s = Sort.new { by 'author.name' }
|
71
|
+
assert_equal [ 'author.name' ].to_json, s.to_json
|
72
|
+
|
73
|
+
s = Sort.new { by 'author.name', 'desc' }
|
74
|
+
assert_equal [ {'author.name' => 'desc'} ].to_json, s.to_json
|
75
|
+
end
|
41
76
|
|
42
|
-
s = Sort.new { field 'author.name', :desc }
|
43
|
-
assert_equal [ {'author.name' => 'desc'} ].to_json, s.to_json
|
44
77
|
end
|
45
78
|
|
46
79
|
end
|
data/test/unit/search_test.rb
CHANGED
@@ -67,7 +67,11 @@ module Tire
|
|
67
67
|
|
68
68
|
should "allow chaining" do
|
69
69
|
assert_nothing_raised do
|
70
|
-
Search::Search.new('index').query { }.
|
70
|
+
Search::Search.new('index').query { }.
|
71
|
+
sort { by :title, 'desc' }.
|
72
|
+
size(5).
|
73
|
+
sort { by :name, 'asc' }.
|
74
|
+
from(1)
|
71
75
|
end
|
72
76
|
end
|
73
77
|
|
@@ -108,8 +112,8 @@ module Tire
|
|
108
112
|
should "allow sorting by multiple fields" do
|
109
113
|
s = Search::Search.new('index') do
|
110
114
|
sort do
|
111
|
-
title 'desc'
|
112
|
-
_score
|
115
|
+
by :title, 'desc'
|
116
|
+
by :_score
|
113
117
|
end
|
114
118
|
end
|
115
119
|
hash = MultiJson.decode( s.to_json )
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tire
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 5
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 15
|
10
|
+
version: 0.1.15
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Karel Minarik
|
@@ -15,8 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
19
|
-
default_executable:
|
18
|
+
date: 2011-07-04 00:00:00 Z
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
22
21
|
name: rake
|
@@ -336,7 +335,6 @@ files:
|
|
336
335
|
- test/unit/search_test.rb
|
337
336
|
- test/unit/tire_test.rb
|
338
337
|
- tire.gemspec
|
339
|
-
has_rdoc: true
|
340
338
|
homepage: http://github.com/karmi/tire
|
341
339
|
licenses: []
|
342
340
|
|
@@ -349,12 +347,12 @@ post_install_message: |
|
|
349
347
|
|
350
348
|
IMPORTANT CHANGES LATELY:
|
351
349
|
|
352
|
-
#
|
353
|
-
#
|
354
|
-
#
|
355
|
-
#
|
350
|
+
# Cleanup of code for getting document type, id, JSON serialization
|
351
|
+
# Bunch of deprecations: sorting, passing document type to store/remove
|
352
|
+
# Displaying a warning when no ID is passed when storing in bulk
|
353
|
+
# Correct handling of import for Mongoid/Kaminari combos
|
356
354
|
|
357
|
-
See the full changelog at <http://github.com/karmi/tire/commits/v0.1.
|
355
|
+
See the full changelog at <http://github.com/karmi/tire/commits/v0.1.15>.
|
358
356
|
|
359
357
|
--------------------------------------------------------------------------------
|
360
358
|
|
@@ -385,7 +383,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
385
383
|
requirements: []
|
386
384
|
|
387
385
|
rubyforge_project: tire
|
388
|
-
rubygems_version: 1.5
|
386
|
+
rubygems_version: 1.8.5
|
389
387
|
signing_key:
|
390
388
|
specification_version: 3
|
391
389
|
summary: Ruby client for ElasticSearch
|