tire 0.4.3 → 0.5.0
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 +1 -1
- data/.yardopts +1 -0
- data/README.markdown +2 -2
- data/examples/rails-application-template.rb +20 -6
- data/lib/tire.rb +2 -0
- data/lib/tire/alias.rb +1 -1
- data/lib/tire/configuration.rb +8 -0
- data/lib/tire/dsl.rb +69 -2
- data/lib/tire/index.rb +33 -20
- data/lib/tire/model/indexing.rb +7 -1
- data/lib/tire/model/persistence.rb +7 -4
- data/lib/tire/model/persistence/attributes.rb +1 -1
- data/lib/tire/model/persistence/finders.rb +4 -16
- data/lib/tire/model/search.rb +21 -8
- data/lib/tire/multi_search.rb +263 -0
- data/lib/tire/results/collection.rb +78 -49
- data/lib/tire/results/item.rb +6 -3
- data/lib/tire/results/pagination.rb +15 -1
- data/lib/tire/rubyext/ruby_1_8.rb +1 -7
- data/lib/tire/rubyext/uri_escape.rb +74 -0
- data/lib/tire/search.rb +33 -11
- data/lib/tire/search/facet.rb +8 -3
- data/lib/tire/search/filter.rb +1 -1
- data/lib/tire/search/highlight.rb +1 -1
- data/lib/tire/search/queries/match.rb +40 -0
- data/lib/tire/search/query.rb +42 -6
- data/lib/tire/search/scan.rb +1 -1
- data/lib/tire/search/script_field.rb +1 -1
- data/lib/tire/search/sort.rb +1 -1
- data/lib/tire/tasks.rb +17 -14
- data/lib/tire/version.rb +26 -8
- data/test/integration/active_record_searchable_test.rb +248 -129
- data/test/integration/boosting_queries_test.rb +32 -0
- data/test/integration/custom_score_queries_test.rb +1 -0
- data/test/integration/dsl_search_test.rb +9 -1
- data/test/integration/facets_test.rb +19 -6
- data/test/integration/match_query_test.rb +79 -0
- data/test/integration/multi_search_test.rb +114 -0
- data/test/integration/persistent_model_test.rb +58 -0
- data/test/models/article.rb +1 -1
- data/test/models/persistent_article_in_index.rb +16 -0
- data/test/models/persistent_article_with_defaults.rb +4 -3
- data/test/test_helper.rb +3 -1
- data/test/unit/configuration_test.rb +10 -0
- data/test/unit/index_test.rb +69 -27
- data/test/unit/model_initialization_test.rb +31 -0
- data/test/unit/model_persistence_test.rb +21 -7
- data/test/unit/model_search_test.rb +56 -5
- data/test/unit/multi_search_test.rb +304 -0
- data/test/unit/results_collection_test.rb +42 -2
- data/test/unit/results_item_test.rb +4 -0
- data/test/unit/search_facet_test.rb +35 -11
- data/test/unit/search_query_test.rb +96 -0
- data/test/unit/search_test.rb +60 -3
- data/test/unit/tire_test.rb +14 -0
- data/tire.gemspec +0 -1
- metadata +75 -44
data/.gitignore
CHANGED
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--markup markdown
|
data/README.markdown
CHANGED
@@ -247,7 +247,7 @@ The best thing about `boolean` queries is that we can easily save these partial
|
|
247
247
|
to mix and reuse them later. So, we may define a query for the _tags_ property:
|
248
248
|
|
249
249
|
```ruby
|
250
|
-
tags_query = lambda do
|
250
|
+
tags_query = lambda do |boolean|
|
251
251
|
boolean.should { string 'tags:ruby' }
|
252
252
|
boolean.should { string 'tags:java' }
|
253
253
|
end
|
@@ -256,7 +256,7 @@ to mix and reuse them later. So, we may define a query for the _tags_ property:
|
|
256
256
|
And a query for the _published_on_ property:
|
257
257
|
|
258
258
|
```ruby
|
259
|
-
published_on_query = lambda do
|
259
|
+
published_on_query = lambda do |boolean|
|
260
260
|
boolean.must { string 'published_on:[2011-01-01 TO 2011-01-02]' }
|
261
261
|
end
|
262
262
|
```
|
@@ -105,7 +105,7 @@ puts
|
|
105
105
|
say_status "Rubygems", "Adding Rubygems into Gemfile...\n", :yellow
|
106
106
|
puts '-'*80, ''; sleep 1
|
107
107
|
|
108
|
-
gem 'tire'
|
108
|
+
gem 'tire', :git => 'git://github.com/karmi/tire.git'
|
109
109
|
gem 'will_paginate', '~> 3.0'
|
110
110
|
|
111
111
|
git :add => '.'
|
@@ -137,7 +137,7 @@ say_status "Database", "Seeding the database with data...", :yellow
|
|
137
137
|
puts '-'*80, ''; sleep 0.25
|
138
138
|
|
139
139
|
run "rm -f db/seeds.rb"
|
140
|
-
file 'db/seeds.rb',
|
140
|
+
file 'db/seeds.rb', %q{
|
141
141
|
contents = [
|
142
142
|
'Lorem ipsum dolor sit amet.',
|
143
143
|
'Consectetur adipisicing elit, sed do eiusmod tempor incididunt.',
|
@@ -149,11 +149,23 @@ contents = [
|
|
149
149
|
puts "Deleting all articles..."
|
150
150
|
Article.delete_all
|
151
151
|
|
152
|
-
|
153
|
-
|
154
|
-
|
152
|
+
unless ENV['COUNT']
|
153
|
+
|
154
|
+
puts "Creating articles..."
|
155
|
+
%w[ One Two Three Four Five ].each_with_index do |title, i|
|
156
|
+
Article.create :title => title, :content => contents[i], :published_on => i.days.ago.utc
|
157
|
+
end
|
158
|
+
|
159
|
+
else
|
160
|
+
|
161
|
+
puts "Creating 10,000 articles..."
|
162
|
+
(1..ENV['COUNT'].to_i).each_with_index do |title, i|
|
163
|
+
Article.create :title => "Title #{title}", :content => 'Lorem', :published_on => i.days.ago.utc
|
164
|
+
print '.'
|
165
|
+
end
|
166
|
+
|
155
167
|
end
|
156
|
-
|
168
|
+
}
|
157
169
|
|
158
170
|
rake "db:seed"
|
159
171
|
|
@@ -169,6 +181,8 @@ file 'app/models/article.rb', <<-CODE
|
|
169
181
|
class Article < ActiveRecord::Base
|
170
182
|
include Tire::Model::Search
|
171
183
|
include Tire::Model::Callbacks
|
184
|
+
|
185
|
+
attr_accessible :title, :content, :published_on
|
172
186
|
end
|
173
187
|
CODE
|
174
188
|
|
data/lib/tire.rb
CHANGED
@@ -20,12 +20,14 @@ require 'tire/http/response'
|
|
20
20
|
require 'tire/http/client'
|
21
21
|
require 'tire/search'
|
22
22
|
require 'tire/search/query'
|
23
|
+
require 'tire/search/queries/match'
|
23
24
|
require 'tire/search/sort'
|
24
25
|
require 'tire/search/facet'
|
25
26
|
require 'tire/search/filter'
|
26
27
|
require 'tire/search/highlight'
|
27
28
|
require 'tire/search/scan'
|
28
29
|
require 'tire/search/script_field'
|
30
|
+
require 'tire/multi_search'
|
29
31
|
require 'tire/results/pagination'
|
30
32
|
require 'tire/results/collection'
|
31
33
|
require 'tire/results/item'
|
data/lib/tire/alias.rb
CHANGED
@@ -209,7 +209,7 @@ module Tire
|
|
209
209
|
|
210
210
|
if Configuration.logger.level.to_s == 'debug'
|
211
211
|
body = if @response
|
212
|
-
|
212
|
+
MultiJson.encode(@response.body, :pretty => Configuration.pretty)
|
213
213
|
else
|
214
214
|
error.message rescue ''
|
215
215
|
end
|
data/lib/tire/configuration.rb
CHANGED
@@ -19,6 +19,14 @@ module Tire
|
|
19
19
|
@logger || nil
|
20
20
|
end
|
21
21
|
|
22
|
+
def self.pretty(value=nil, options={})
|
23
|
+
if value === false
|
24
|
+
return @pretty = false
|
25
|
+
else
|
26
|
+
@pretty.nil? ? true : @pretty
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
22
30
|
def self.reset(*properties)
|
23
31
|
reset_variables = properties.empty? ? instance_variables : instance_variables.map { |p| p.to_s} & \
|
24
32
|
properties.map { |p| "@#{p}" }
|
data/lib/tire/dsl.rb
CHANGED
@@ -18,8 +18,11 @@ module Tire
|
|
18
18
|
options
|
19
19
|
else raise ArgumentError, "Please pass a Ruby Hash or String with JSON"
|
20
20
|
end
|
21
|
-
|
22
|
-
|
21
|
+
unless options.empty?
|
22
|
+
Search::Search.new(indices, :payload => payload)
|
23
|
+
else
|
24
|
+
Search::Search.new(indices)
|
25
|
+
end
|
23
26
|
end
|
24
27
|
rescue Exception => error
|
25
28
|
STDERR.puts "[REQUEST FAILED] #{error.class} #{error.message rescue nil}\n"
|
@@ -27,6 +30,70 @@ module Tire
|
|
27
30
|
ensure
|
28
31
|
end
|
29
32
|
|
33
|
+
# Build and perform a [multi-search](http://elasticsearch.org/guide/reference/api/multi-search.html)
|
34
|
+
# request.
|
35
|
+
#
|
36
|
+
# s = Tire.search 'clients' do
|
37
|
+
# search :names do
|
38
|
+
# query { match :name, 'carpenter' }
|
39
|
+
# end
|
40
|
+
# search :counts, search_type: 'count' do
|
41
|
+
# query { match [:name, :street, :occupation], 'carpenter' }
|
42
|
+
# end
|
43
|
+
# search :vip, index: 'clients-vip' do
|
44
|
+
# query { string "last_name:carpenter" }
|
45
|
+
# end
|
46
|
+
# search() { query {all} }
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# The DSL allows you to perform multiple searches and get corresponding results
|
50
|
+
# in a single HTTP request, saving network roundtrips.
|
51
|
+
#
|
52
|
+
# Use the `search` method in the block to define a search request with the
|
53
|
+
# regular Tire's DSL (`query`, `facet`, etc).
|
54
|
+
#
|
55
|
+
# You can pass options such as `search_type`, `routing`, etc.,
|
56
|
+
# as well as a different `index` and/or `type` to individual searches.
|
57
|
+
#
|
58
|
+
# You can give single searches names, to be able to refer to them later.
|
59
|
+
#
|
60
|
+
# The results are returned as an enumerable collection of {Tire::Results::Collection} instances.
|
61
|
+
#
|
62
|
+
# You may simply iterate over them with `each`:
|
63
|
+
#
|
64
|
+
# s.results.each do |results|
|
65
|
+
# puts results.map(&:name)
|
66
|
+
# end
|
67
|
+
#
|
68
|
+
# To iterate over named results, use the `each_pair` method:
|
69
|
+
#
|
70
|
+
# s.results.each_pair do |name,results|
|
71
|
+
# puts "Search #{name} got #{results.size} results"
|
72
|
+
# end
|
73
|
+
#
|
74
|
+
# You can get a specific named result:
|
75
|
+
#
|
76
|
+
# search.results[:vip]
|
77
|
+
#
|
78
|
+
# You can mix & match named and non-named searches in the definition; the non-named
|
79
|
+
# searches will be zero-based numbered, so you can refer to them:
|
80
|
+
#
|
81
|
+
# search.results[3] # Results for the last query
|
82
|
+
#
|
83
|
+
# To log the multi-search request, use the standard `to_curl` method (or set up a logger):
|
84
|
+
#
|
85
|
+
# print search.to_curl
|
86
|
+
#
|
87
|
+
def multi_search(indices=nil, options={}, &block)
|
88
|
+
Search::Multi::Search.new(indices, options, &block)
|
89
|
+
rescue Exception => error
|
90
|
+
STDERR.puts "[REQUEST FAILED] #{error.class} #{error.message rescue nil}\n"
|
91
|
+
raise
|
92
|
+
ensure
|
93
|
+
end
|
94
|
+
alias :multisearch :multi_search
|
95
|
+
alias :msearch :multi_search
|
96
|
+
|
30
97
|
def index(name, &block)
|
31
98
|
Index.new(name, &block)
|
32
99
|
end
|
data/lib/tire/index.rb
CHANGED
@@ -36,7 +36,7 @@ module Tire
|
|
36
36
|
@response.success? ? @response : false
|
37
37
|
|
38
38
|
ensure
|
39
|
-
curl = %Q|curl -X POST #{url} -d '#{MultiJson.encode(options)}'|
|
39
|
+
curl = %Q|curl -X POST #{url} -d '#{MultiJson.encode(options, :pretty => Configuration.pretty)}'|
|
40
40
|
logged('CREATE', curl)
|
41
41
|
end
|
42
42
|
|
@@ -64,22 +64,27 @@ module Tire
|
|
64
64
|
|
65
65
|
def store(*args)
|
66
66
|
document, options = args
|
67
|
-
type = get_type_from_document(document)
|
68
|
-
|
69
|
-
if options
|
70
|
-
percolate = options[:percolate]
|
71
|
-
percolate = "*" if percolate === true
|
72
|
-
end
|
73
67
|
|
74
68
|
id = get_id_from_document(document)
|
69
|
+
type = get_type_from_document(document)
|
75
70
|
document = convert_document_to_json(document)
|
76
71
|
|
77
|
-
|
78
|
-
|
72
|
+
options ||= {}
|
73
|
+
params = {}
|
74
|
+
|
75
|
+
if options[:percolate]
|
76
|
+
params[:percolate] = options[:percolate]
|
77
|
+
params[:percolate] = "*" if params[:percolate] === true
|
78
|
+
end
|
79
|
+
|
80
|
+
params[:parent] = options[:parent] if options[:parent]
|
81
|
+
|
82
|
+
params_encoded = params.empty? ? '' : "?#{params.to_param}"
|
83
|
+
|
84
|
+
url = id ? "#{self.url}/#{type}/#{id}#{params_encoded}" : "#{self.url}/#{type}/#{params_encoded}"
|
79
85
|
|
80
86
|
@response = Configuration.client.post url, document
|
81
87
|
MultiJson.decode(@response.body)
|
82
|
-
|
83
88
|
ensure
|
84
89
|
curl = %Q|curl -X POST "#{url}" -d '#{document}'|
|
85
90
|
logged([type, id].join('/'), curl)
|
@@ -117,7 +122,7 @@ module Tire
|
|
117
122
|
end
|
118
123
|
|
119
124
|
ensure
|
120
|
-
curl = %Q|curl -X POST "#{url}/_bulk" -
|
125
|
+
curl = %Q|curl -X POST "#{url}/_bulk" --data-binary '{... data omitted ...}'|
|
121
126
|
logged('BULK', curl)
|
122
127
|
end
|
123
128
|
end
|
@@ -184,20 +189,28 @@ module Tire
|
|
184
189
|
logged(id, curl)
|
185
190
|
end
|
186
191
|
|
187
|
-
def retrieve(type, id)
|
192
|
+
def retrieve(type, id, options={})
|
188
193
|
raise ArgumentError, "Please pass a document ID" unless id
|
189
194
|
|
190
195
|
type = Utils.escape(type)
|
191
196
|
url = "#{self.url}/#{type}/#{id}"
|
192
|
-
|
197
|
+
|
198
|
+
params = {}
|
199
|
+
params[:routing] = options[:routing] if options[:routing]
|
200
|
+
params[:fields] = options[:fields] if options[:fields]
|
201
|
+
params[:preference] = options[:preference] if options[:preference]
|
202
|
+
params_encoded = params.empty? ? '' : "?#{params.to_param}"
|
203
|
+
|
204
|
+
@response = Configuration.client.get "#{url}#{params_encoded}"
|
193
205
|
|
194
206
|
h = MultiJson.decode(@response.body)
|
195
|
-
|
207
|
+
wrapper = options[:wrapper] || Configuration.wrapper
|
208
|
+
if wrapper == Hash then h
|
196
209
|
else
|
197
210
|
return nil if h['exists'] == false
|
198
211
|
document = h['_source'] || h['fields'] || {}
|
199
212
|
document.update('id' => h['_id'], '_type' => h['_type'], '_index' => h['_index'], '_version' => h['_version'])
|
200
|
-
|
213
|
+
wrapper.new(document)
|
201
214
|
end
|
202
215
|
|
203
216
|
ensure
|
@@ -217,7 +230,7 @@ module Tire
|
|
217
230
|
MultiJson.decode(@response.body)
|
218
231
|
|
219
232
|
ensure
|
220
|
-
curl = %Q|curl -X POST "#{url}" -d '#{MultiJson.encode(payload)}'|
|
233
|
+
curl = %Q|curl -X POST "#{url}" -d '#{MultiJson.encode(payload, :pretty => Configuration.pretty)}'|
|
221
234
|
logged(id, curl)
|
222
235
|
end
|
223
236
|
|
@@ -266,7 +279,7 @@ module Tire
|
|
266
279
|
MultiJson.decode(@response.body)['ok']
|
267
280
|
|
268
281
|
ensure
|
269
|
-
curl = %Q|curl -X PUT "#{Configuration.url}/_percolator/#{@name}/#{name}?pretty
|
282
|
+
curl = %Q|curl -X PUT "#{Configuration.url}/_percolator/#{@name}/#{name}?pretty" -d '#{MultiJson.encode(options, :pretty => Configuration.pretty)}'|
|
270
283
|
logged('_percolator', curl)
|
271
284
|
end
|
272
285
|
|
@@ -294,7 +307,7 @@ module Tire
|
|
294
307
|
MultiJson.decode(@response.body)['matches']
|
295
308
|
|
296
309
|
ensure
|
297
|
-
curl = %Q|curl -X GET "#{url}/#{type}/_percolate?pretty
|
310
|
+
curl = %Q|curl -X GET "#{url}/#{type}/_percolate?pretty" -d '#{MultiJson.encode(payload, :pretty => Configuration.pretty)}'|
|
298
311
|
logged('_percolate', curl)
|
299
312
|
end
|
300
313
|
|
@@ -308,9 +321,9 @@ module Tire
|
|
308
321
|
|
309
322
|
if Configuration.logger.level.to_s == 'debug'
|
310
323
|
body = if @response
|
311
|
-
|
324
|
+
MultiJson.encode( MultiJson.load(@response.body), :pretty => Configuration.pretty)
|
312
325
|
else
|
313
|
-
error.message rescue ''
|
326
|
+
MultiJson.encode( MultiJson.load(error.message), :pretty => Configuration.pretty) rescue ''
|
314
327
|
end
|
315
328
|
else
|
316
329
|
body = ''
|
data/lib/tire/model/indexing.rb
CHANGED
@@ -105,11 +105,17 @@ module Tire
|
|
105
105
|
#
|
106
106
|
def create_elasticsearch_index
|
107
107
|
unless index.exists?
|
108
|
-
|
108
|
+
new_index = index
|
109
|
+
unless result = new_index.create(:mappings => mapping_to_hash, :settings => settings)
|
110
|
+
STDERR.puts "[ERROR] There has been an error when creating the index -- elasticsearch returned:",
|
111
|
+
new_index.response
|
112
|
+
result
|
113
|
+
end
|
109
114
|
end
|
110
115
|
rescue Errno::ECONNREFUSED => e
|
111
116
|
STDERR.puts "Skipping index creation, cannot connect to ElasticSearch",
|
112
117
|
"(The original exception was: #{e.inspect})"
|
118
|
+
false
|
113
119
|
end
|
114
120
|
|
115
121
|
def mapping_options
|
@@ -11,7 +11,7 @@ module Tire
|
|
11
11
|
#
|
12
12
|
# class Article
|
13
13
|
# include Tire::Model::Persistence
|
14
|
-
#
|
14
|
+
#
|
15
15
|
# property :title
|
16
16
|
# end
|
17
17
|
#
|
@@ -54,11 +54,14 @@ module Tire
|
|
54
54
|
args.last.update(:wrapper => self, :version => true) if args.last.is_a? Hash
|
55
55
|
args << { :wrapper => self, :version => true } unless args.any? { |a| a.is_a? Hash }
|
56
56
|
|
57
|
-
self.
|
57
|
+
self.tire.search(*args, &block)
|
58
58
|
end
|
59
59
|
|
60
|
-
def self.
|
61
|
-
|
60
|
+
def self.multi_search(*args, &block)
|
61
|
+
args.last.update(:wrapper => self, :version => true) if args.last.is_a? Hash
|
62
|
+
args << { :wrapper => self, :version => true } unless args.any? { |a| a.is_a? Hash }
|
63
|
+
|
64
|
+
self.tire.multi_search(*args, &block)
|
62
65
|
end
|
63
66
|
|
64
67
|
end
|
@@ -46,7 +46,7 @@ module Tire
|
|
46
46
|
|
47
47
|
# Save property default value (when relevant):
|
48
48
|
unless (default_value = options.delete(:default)).nil?
|
49
|
-
property_defaults[name.to_sym] = default_value
|
49
|
+
property_defaults[name.to_sym] = default_value.respond_to?(:call) ? default_value.call : default_value
|
50
50
|
end
|
51
51
|
|
52
52
|
# Save property casting (when relevant):
|
@@ -11,12 +11,10 @@ module Tire
|
|
11
11
|
|
12
12
|
def find *args
|
13
13
|
# TODO: Options like `sort`
|
14
|
-
old_wrapper = Tire::Configuration.wrapper
|
15
|
-
Tire::Configuration.wrapper self
|
16
14
|
options = args.pop if args.last.is_a?(Hash)
|
17
15
|
args.flatten!
|
18
16
|
if args.size > 1
|
19
|
-
Tire::Search::Search.new(index.name) do |search|
|
17
|
+
Tire::Search::Search.new(index.name, :wrapper => self) do |search|
|
20
18
|
search.query do |query|
|
21
19
|
query.ids(args, document_type)
|
22
20
|
end
|
@@ -25,35 +23,25 @@ module Tire
|
|
25
23
|
else
|
26
24
|
case args = args.pop
|
27
25
|
when Fixnum, String
|
28
|
-
index.retrieve document_type, args
|
26
|
+
index.retrieve document_type, args, :wrapper => self
|
29
27
|
when :all, :first
|
30
28
|
send(args)
|
31
29
|
else
|
32
30
|
raise ArgumentError, "Please pass either ID as Fixnum or String, or :all, :first as an argument"
|
33
31
|
end
|
34
32
|
end
|
35
|
-
ensure
|
36
|
-
Tire::Configuration.wrapper old_wrapper
|
37
33
|
end
|
38
34
|
|
39
35
|
def all
|
40
36
|
# TODO: Options like `sort`; Possibly `filters`
|
41
|
-
|
42
|
-
Tire::Configuration.wrapper self
|
43
|
-
s = Tire::Search::Search.new(index.name).query { all }
|
37
|
+
s = Tire::Search::Search.new(index.name, :type => document_type, :wrapper => self).query { all }
|
44
38
|
s.version(true).results
|
45
|
-
ensure
|
46
|
-
Tire::Configuration.wrapper old_wrapper
|
47
39
|
end
|
48
40
|
|
49
41
|
def first
|
50
42
|
# TODO: Options like `sort`; Possibly `filters`
|
51
|
-
|
52
|
-
Tire::Configuration.wrapper self
|
53
|
-
s = Tire::Search::Search.new(index.name).query { all }.size(1)
|
43
|
+
s = Tire::Search::Search.new(index.name, :type => document_type, :wrapper => self).query { all }.size(1)
|
54
44
|
s.version(true).results.first
|
55
|
-
ensure
|
56
|
-
Tire::Configuration.wrapper old_wrapper
|
57
45
|
end
|
58
46
|
|
59
47
|
end
|
data/lib/tire/model/search.rb
CHANGED
@@ -72,20 +72,26 @@ module Tire
|
|
72
72
|
options ||= {}
|
73
73
|
end
|
74
74
|
|
75
|
-
sort = Array( options[:order] || options[:sort] )
|
76
75
|
options = default_options.update(options)
|
76
|
+
sort = Array( options.delete(:order) || options.delete(:sort) )
|
77
77
|
|
78
78
|
s = Tire::Search::Search.new(options.delete(:index), options)
|
79
|
-
|
80
|
-
|
79
|
+
|
80
|
+
page = options.delete(:page)
|
81
|
+
per_page = options.delete(:per_page) || Tire::Results::Pagination::default_per_page
|
82
|
+
|
83
|
+
s.size( per_page.to_i ) if per_page
|
84
|
+
s.from( page.to_i <= 1 ? 0 : (per_page.to_i * (page.to_i-1)) ) if page && per_page
|
85
|
+
|
81
86
|
s.sort do
|
82
87
|
sort.each do |t|
|
83
|
-
field_name, direction = t.split('
|
88
|
+
field_name, direction = t.split(':')
|
84
89
|
by field_name, direction
|
85
90
|
end
|
86
91
|
end unless sort.empty?
|
87
92
|
|
88
|
-
|
93
|
+
version = options.delete(:version)
|
94
|
+
s.version(version) if version
|
89
95
|
|
90
96
|
if block_given?
|
91
97
|
block.arity < 1 ? s.instance_eval(&block) : block.call(s)
|
@@ -99,6 +105,12 @@ module Tire
|
|
99
105
|
s.results
|
100
106
|
end
|
101
107
|
|
108
|
+
def multi_search(options={}, &block)
|
109
|
+
default_options = {:type => document_type}
|
110
|
+
options = default_options.update(options)
|
111
|
+
Tire::Search::Multi::Search.new(index.name, options, &block).results
|
112
|
+
end
|
113
|
+
|
102
114
|
# Returns a Tire::Index instance for this model.
|
103
115
|
#
|
104
116
|
# Example usage: `Article.index.refresh`.
|
@@ -154,7 +166,7 @@ module Tire
|
|
154
166
|
# declared in the mapping are serialized.
|
155
167
|
#
|
156
168
|
# For properties declared with the `:as` option, the passed String or Proc
|
157
|
-
# is evaluated in the instance context.
|
169
|
+
# is evaluated in the instance context. Other objects are indexed "as is".
|
158
170
|
#
|
159
171
|
def to_indexed_json
|
160
172
|
if instance.class.tire.mapping.empty?
|
@@ -172,7 +184,9 @@ module Tire
|
|
172
184
|
hash[key] = instance.instance_eval(options[:as])
|
173
185
|
when Proc
|
174
186
|
hash[key] = instance.instance_eval(&options[:as])
|
175
|
-
|
187
|
+
else
|
188
|
+
hash[key] = options[:as]
|
189
|
+
end if options[:as]
|
176
190
|
end
|
177
191
|
|
178
192
|
hash.to_json
|
@@ -300,7 +314,6 @@ module Tire
|
|
300
314
|
Results::Item.send :include, Loader
|
301
315
|
end
|
302
316
|
|
303
|
-
|
304
317
|
end
|
305
318
|
|
306
319
|
end
|