tire 0.1.14 → 0.1.15
Sign up to get free protection for your applications and to get access to all the features.
- 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
|