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