tire 0.1.16 → 0.2.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/README.markdown +131 -62
- data/examples/rails-application-template.rb +1 -1
- data/examples/tire-dsl.rb +6 -6
- data/lib/tire/index.rb +7 -27
- data/lib/tire/model/callbacks.rb +1 -1
- data/lib/tire/model/search.rb +63 -27
- data/lib/tire/results/collection.rb +33 -15
- data/lib/tire/results/item.rb +46 -8
- data/lib/tire/search.rb +2 -5
- data/lib/tire/search/sort.rb +0 -7
- data/lib/tire/version.rb +6 -6
- data/test/integration/active_model_searchable_test.rb +26 -5
- data/test/integration/active_record_searchable_test.rb +94 -9
- data/test/integration/filters_test.rb +1 -1
- data/test/integration/highlight_test.rb +0 -1
- data/test/integration/index_mapping_test.rb +3 -4
- data/test/integration/percolator_test.rb +6 -6
- data/test/integration/persistent_model_test.rb +19 -1
- data/test/integration/query_string_test.rb +9 -0
- data/test/integration/results_test.rb +11 -0
- data/test/models/active_record_models.rb +49 -0
- data/test/test_helper.rb +2 -0
- data/test/unit/index_test.rb +16 -5
- data/test/unit/model_search_test.rb +45 -6
- data/test/unit/results_collection_test.rb +51 -2
- data/test/unit/results_item_test.rb +64 -1
- data/test/unit/search_sort_test.rb +26 -59
- data/test/unit/search_test.rb +17 -1
- metadata +16 -49
- data/test/models/active_record_article.rb +0 -12
data/README.markdown
CHANGED
@@ -1,29 +1,33 @@
|
|
1
1
|
Tire
|
2
2
|
=========
|
3
3
|
|
4
|
-
_Tire_ is a Ruby client for the [ElasticSearch](http://www.elasticsearch.org/)
|
4
|
+
_Tire_ is a Ruby (1.8 or 1.9) client for the [ElasticSearch](http://www.elasticsearch.org/)
|
5
|
+
search engine/database.
|
5
6
|
|
6
7
|
_ElasticSearch_ is a scalable, distributed, cloud-ready, highly-available,
|
7
|
-
full-text search engine and database
|
8
|
-
|
8
|
+
full-text search engine and database with
|
9
|
+
[powerfull aggregation features](http://www.elasticsearch.org/guide/reference/api/search/facets/),
|
10
|
+
communicating by JSON over RESTful HTTP, based on [Lucene](http://lucene.apache.org/), written in Java.
|
9
11
|
|
10
|
-
This
|
11
|
-
|
12
|
+
This Readme provides a brief overview of _Tire's_ features. The more detailed documentation is at <http://karmi.github.com/tire/>.
|
13
|
+
|
14
|
+
Both of these documents contain a lot of information. Please set aside some time to read them thoroughly, before you blindly dive into „somehow making it work“. Just skimming through it **won't work** for you. For more information, please refer to the [integration test suite](https://github.com/karmi/tire/tree/master/test/integration)
|
15
|
+
and [issues](https://github.com/karmi/tire/issues).
|
12
16
|
|
13
17
|
Installation
|
14
18
|
------------
|
15
19
|
|
16
|
-
First, you need a running _ElasticSearch_ server. Thankfully, it's easy. Let's define easy:
|
20
|
+
OK. First, you need a running _ElasticSearch_ server. Thankfully, it's easy. Let's define easy:
|
17
21
|
|
18
|
-
$ curl -k -L -o elasticsearch-0.
|
19
|
-
$ tar -zxvf elasticsearch-0.
|
20
|
-
$ ./elasticsearch-0.
|
22
|
+
$ curl -k -L -o elasticsearch-0.17.2.tar.gz http://github.com/downloads/elasticsearch/elasticsearch/elasticsearch-0.17.2.tar.gz
|
23
|
+
$ tar -zxvf elasticsearch-0.17.2.tar.gz
|
24
|
+
$ ./elasticsearch-0.17.2/bin/elasticsearch -f
|
21
25
|
|
22
|
-
|
26
|
+
See, easy. On a Mac, you can also use _Homebrew_:
|
23
27
|
|
24
28
|
$ brew install elasticsearch
|
25
29
|
|
26
|
-
|
30
|
+
Now, let's install the gem via Rubygems:
|
27
31
|
|
28
32
|
$ gem install tire
|
29
33
|
|
@@ -39,8 +43,7 @@ Usage
|
|
39
43
|
|
40
44
|
_Tire_ exposes easy-to-use domain specific language for fluent communication with _ElasticSearch_.
|
41
45
|
|
42
|
-
It
|
43
|
-
classes for convenient usage in Rails applications.
|
46
|
+
It easily blends with your _ActiveModel_/_ActiveRecord_ classes for convenient usage in _Rails_ applications.
|
44
47
|
|
45
48
|
To test-drive the core _ElasticSearch_ functionality, let's require the gem:
|
46
49
|
|
@@ -61,7 +64,7 @@ which allows you to use your preferred JSON library. We'll use the
|
|
61
64
|
require 'yajl/json_gem'
|
62
65
|
```
|
63
66
|
|
64
|
-
|
67
|
+
Let's create an index named `articles` and store/index some documents:
|
65
68
|
|
66
69
|
```ruby
|
67
70
|
Tire.index 'articles' do
|
@@ -83,6 +86,8 @@ for a specific document type:
|
|
83
86
|
|
84
87
|
```ruby
|
85
88
|
Tire.index 'articles' do
|
89
|
+
delete
|
90
|
+
|
86
91
|
create :mappings => {
|
87
92
|
:article => {
|
88
93
|
:properties => {
|
@@ -97,29 +102,35 @@ for a specific document type:
|
|
97
102
|
```
|
98
103
|
|
99
104
|
Of course, we may have large amounts of data, and it may be impossible or impractical to add them to the index
|
100
|
-
one by one. We can use _ElasticSearch's_
|
105
|
+
one by one. We can use _ElasticSearch's_
|
106
|
+
[bulk storage](http://www.elasticsearch.org/guide/reference/api/bulk.html).
|
107
|
+
Notice, that collection items must have an `id` property or method,
|
108
|
+
and should have a `type` property, if you've set any specific mapping for the index.
|
101
109
|
|
102
110
|
```ruby
|
103
111
|
articles = [
|
104
|
-
{ :id => '1', :title => 'one' },
|
105
|
-
{ :id => '2', :title => 'two' },
|
106
|
-
{ :id => '3', :title => 'three' }
|
112
|
+
{ :id => '1', :type => 'article', :title => 'one', :tags => ['ruby'] },
|
113
|
+
{ :id => '2', :type => 'article', :title => 'two', :tags => ['ruby', 'python'] },
|
114
|
+
{ :id => '3', :type => 'article', :title => 'three', :tags => ['java'] },
|
115
|
+
{ :id => '4', :type => 'article', :title => 'four', :tags => ['ruby', 'php'] }
|
107
116
|
]
|
108
117
|
|
109
|
-
Tire.index '
|
118
|
+
Tire.index 'articles' do
|
110
119
|
import articles
|
111
120
|
end
|
112
121
|
```
|
113
122
|
|
114
|
-
We can
|
115
|
-
`import` method:
|
123
|
+
We can easily manipulate the documents before storing them in the index, by passing a block to the
|
124
|
+
`import` method, like this:
|
116
125
|
|
117
126
|
```ruby
|
118
|
-
Tire.index '
|
127
|
+
Tire.index 'articles' do
|
119
128
|
import articles do |documents|
|
120
129
|
|
121
130
|
documents.each { |document| document[:title].capitalize! }
|
122
131
|
end
|
132
|
+
|
133
|
+
refresh
|
123
134
|
end
|
124
135
|
```
|
125
136
|
|
@@ -137,7 +148,7 @@ from the database:
|
|
137
148
|
|
138
149
|
filter :terms, :tags => ['ruby']
|
139
150
|
|
140
|
-
sort { title 'desc' }
|
151
|
+
sort { by :title, 'desc' }
|
141
152
|
|
142
153
|
facet 'global-tags' do
|
143
154
|
terms :tags, :global => true
|
@@ -189,7 +200,7 @@ count for articles tagged 'php' is excluded, since they don't match the current
|
|
189
200
|
# java 1
|
190
201
|
```
|
191
202
|
|
192
|
-
Notice, that only variables from the enclosing scope are
|
203
|
+
Notice, that only variables from the enclosing scope are accessible.
|
193
204
|
If we want to access the variables or methods from outer scope,
|
194
205
|
we have to use a slight variation of the DSL, by passing the
|
195
206
|
`search` and `query` objects around.
|
@@ -210,7 +221,7 @@ we can use the [_bool_](http://www.elasticsearch.org/guide/reference/query-dsl/b
|
|
210
221
|
query. In _Tire_, we build them declaratively.
|
211
222
|
|
212
223
|
```ruby
|
213
|
-
Tire.search
|
224
|
+
Tire.search 'articles' do
|
214
225
|
query do
|
215
226
|
boolean do
|
216
227
|
should { string 'tags:ruby' }
|
@@ -242,7 +253,7 @@ And a query for the _published_on_ property:
|
|
242
253
|
Now, we can combine these queries for different searches:
|
243
254
|
|
244
255
|
```ruby
|
245
|
-
Tire.search
|
256
|
+
Tire.search 'articles' do
|
246
257
|
query do
|
247
258
|
boolean &tags_query
|
248
259
|
boolean &published_on_query
|
@@ -250,7 +261,17 @@ Now, we can combine these queries for different searches:
|
|
250
261
|
end
|
251
262
|
```
|
252
263
|
|
253
|
-
|
264
|
+
Note, that you can pass options for configuring queries, facets, etc. by passing a Hash as the last argument to the method call:
|
265
|
+
|
266
|
+
```ruby
|
267
|
+
Tire.search 'articles' do
|
268
|
+
query do
|
269
|
+
string 'ruby python', :default_operator => 'AND', :use_dis_max => true
|
270
|
+
end
|
271
|
+
end
|
272
|
+
```
|
273
|
+
|
274
|
+
If configuring the search payload with blocks feels somehow too weak for you, you can pass
|
254
275
|
a plain old Ruby `Hash` (or JSON string) with the query declaration to the `search` method:
|
255
276
|
|
256
277
|
```ruby
|
@@ -260,7 +281,7 @@ a plain old Ruby `Hash` (or JSON string) with the query declaration to the `sear
|
|
260
281
|
If this sounds like a great idea to you, you are probably able to write your application
|
261
282
|
using just `curl`, `sed` and `awk`.
|
262
283
|
|
263
|
-
|
284
|
+
For debugging purposes, we can display the full query JSON for close inspection:
|
264
285
|
|
265
286
|
```ruby
|
266
287
|
puts s.to_json
|
@@ -293,13 +314,14 @@ The _Tire_ DSL tries hard to provide a strong Ruby-like API for the main _Elasti
|
|
293
314
|
|
294
315
|
By default, _Tire_ wraps the results collection in a enumerable `Results::Collection` class,
|
295
316
|
and result items in a `Results::Item` class, which looks like a child of `Hash` and `Openstruct`,
|
296
|
-
for smooth iterating and displaying the results.
|
317
|
+
for smooth iterating over and displaying the results.
|
297
318
|
|
298
319
|
You may wrap the result items in your own class by setting the `Tire.configuration.wrapper`
|
299
320
|
property. Your class must take a `Hash` of attributes on initialization.
|
300
321
|
|
301
|
-
If that seems like a great idea to you, there's a big chance you already have such class
|
302
|
-
|
322
|
+
If that seems like a great idea to you, there's a big chance you already have such class.
|
323
|
+
|
324
|
+
One would bet it's an `ActiveRecord` or `ActiveModel` class, containing model of your Rails application.
|
303
325
|
|
304
326
|
Fortunately, _Tire_ makes blending _ElasticSearch_ features into your models trivially possible.
|
305
327
|
|
@@ -308,12 +330,15 @@ ActiveModel Integration
|
|
308
330
|
-----------------------
|
309
331
|
|
310
332
|
If you're the type with no time for lengthy introductions, you can generate a fully working
|
311
|
-
example Rails application, with an `ActiveRecord` model and a search form, to play with
|
333
|
+
example Rails application, with an `ActiveRecord` model and a search form, to play with
|
334
|
+
(it even downloads _ElasticSearch_ itself, generates the application skeleton and leaves you with
|
335
|
+
a _Git_ repository to explore the steps and the code):
|
312
336
|
|
313
337
|
$ rails new searchapp -m https://github.com/karmi/tire/raw/master/examples/rails-application-template.rb
|
314
338
|
|
315
|
-
For the rest, let's suppose you have an `Article` class in your
|
316
|
-
|
339
|
+
For the rest of us, let's suppose you have an `Article` class in your _Rails_ application.
|
340
|
+
|
341
|
+
To make it searchable with _Tire_, just `include` it:
|
317
342
|
|
318
343
|
```ruby
|
319
344
|
class Article < ActiveRecord::Base
|
@@ -333,8 +358,8 @@ When you now save a record:
|
|
333
358
|
|
334
359
|
it is automatically added into the index, because of the included callbacks.
|
335
360
|
(You may want to skip them in special cases, like when your records are indexed via some external
|
336
|
-
mechanism, let's say
|
337
|
-
|
361
|
+
mechanism, let's say a _CouchDB_ or _RabbitMQ_
|
362
|
+
[river](http://www.elasticsearch.org/blog/2010/09/28/the_river.html).
|
338
363
|
|
339
364
|
The document attributes are indexed exactly as when you call the `Article#to_json` method.
|
340
365
|
|
@@ -344,22 +369,21 @@ Now you can search the records:
|
|
344
369
|
Article.search 'love'
|
345
370
|
```
|
346
371
|
|
347
|
-
OK. This is where the game stops, often. Not here.
|
372
|
+
OK. This is where the search game stops, often. Not here.
|
348
373
|
|
349
374
|
First of all, you may use the full query DSL, as explained above, with filters, sorting,
|
350
375
|
advanced facet aggregation, highlighting, etc:
|
351
376
|
|
352
377
|
```ruby
|
353
|
-
q = 'love'
|
354
378
|
Article.search do
|
355
|
-
query
|
356
|
-
facet('timeline') { date
|
357
|
-
sort
|
379
|
+
query { string 'love' }
|
380
|
+
facet('timeline') { date :published_on, :interval => 'month' }
|
381
|
+
sort { by :published_on, 'desc' }
|
358
382
|
end
|
359
383
|
```
|
360
384
|
|
361
|
-
|
362
|
-
For serious usage, though, you'll definitely want to define a custom mapping for your
|
385
|
+
Second, dynamic mapping is a godsend when you're prototyping.
|
386
|
+
For serious usage, though, you'll definitely want to define a custom mapping for your models:
|
363
387
|
|
364
388
|
```ruby
|
365
389
|
class Article < ActiveRecord::Base
|
@@ -367,7 +391,7 @@ For serious usage, though, you'll definitely want to define a custom mapping for
|
|
367
391
|
include Tire::Model::Callbacks
|
368
392
|
|
369
393
|
mapping do
|
370
|
-
indexes :id, :type => 'string', :
|
394
|
+
indexes :id, :type => 'string', :index => :not_analyzed
|
371
395
|
indexes :title, :type => 'string', :analyzer => 'snowball', :boost => 100
|
372
396
|
indexes :content, :type => 'string', :analyzer => 'snowball'
|
373
397
|
indexes :author, :type => 'string', :analyzer => 'keyword'
|
@@ -376,10 +400,13 @@ For serious usage, though, you'll definitely want to define a custom mapping for
|
|
376
400
|
end
|
377
401
|
```
|
378
402
|
|
379
|
-
In this case, _only_ the defined model attributes are indexed
|
403
|
+
In this case, _only_ the defined model attributes are indexed. The `mapping` declaration creates the
|
404
|
+
index when the class is loaded or when the importing features are used, and _only_ when it does not yet exist.
|
405
|
+
(It may well be reasonable to wrap the index creation logic in a class method of your model, so you
|
406
|
+
have better control on index creation when bootstrapping your application or when setting up the test suite.)
|
380
407
|
|
381
|
-
When you want tight grip on how
|
382
|
-
|
408
|
+
When you want a tight grip on how the attributes are added to the index, just
|
409
|
+
implement the `to_indexed_json` method in your model:
|
383
410
|
|
384
411
|
```ruby
|
385
412
|
class Article < ActiveRecord::Base
|
@@ -404,24 +431,66 @@ provide the `to_indexed_json` method yourself:
|
|
404
431
|
end
|
405
432
|
```
|
406
433
|
|
407
|
-
|
408
|
-
|
434
|
+
The results returned by `Article.search` are wrapped in the aforementioned `Item` class, by default.
|
435
|
+
This way, we have a fast and flexible access to the properties returned from _ElasticSearch_ (via the
|
436
|
+
`_source` or `fields` JSON properties). This way, we can index whatever JSON we like in _ElasticSearch_,
|
437
|
+
and retrieve it, simply, via the dot notation:
|
438
|
+
|
439
|
+
```ruby
|
440
|
+
articles = Article.search 'love'
|
441
|
+
articles.each do |article|
|
442
|
+
puts article.title
|
443
|
+
puts article.author.last_name
|
444
|
+
end
|
445
|
+
```
|
446
|
+
|
447
|
+
The `Item` instances masquerade themselves as instances of your model within a _Rails_ application
|
448
|
+
(based on the `_type` property retrieved from _ElasticSearch_), so you can use them carefree;
|
449
|
+
all the `url_for` or `dom_id` helpers work as expected.
|
450
|
+
|
451
|
+
If you need to access the “real” model (eg. to access its assocations or methods not
|
452
|
+
stored in _ElasticSearch_), just load it from the database:
|
453
|
+
|
454
|
+
```ruby
|
455
|
+
puts article.load(:include => 'comments').comments.size
|
456
|
+
```
|
457
|
+
|
458
|
+
You can see that _Tire_ stays as far from the database as possible. That's because it believes
|
459
|
+
you have most of the data you want to display stored in _ElasticSearch_. When you need
|
460
|
+
to eagerly load the records from the database itself, for whatever reason,
|
461
|
+
you can do it with the `:load` option when searching:
|
462
|
+
|
463
|
+
```ruby
|
464
|
+
# Will call `Article.search [1, 2, 3]`
|
465
|
+
Article.search 'love', :load => true
|
466
|
+
```
|
467
|
+
|
468
|
+
Instead of simple `true`, you can pass any options for the model's find method:
|
469
|
+
|
470
|
+
```ruby
|
471
|
+
# Will call `Article.search [1, 2, 3], :include => 'comments'`
|
472
|
+
Article.search :load => { :include => 'comments' } do
|
473
|
+
query { string 'love' }
|
474
|
+
end
|
475
|
+
```
|
476
|
+
|
477
|
+
Note that _Tire_ search results are fully compatible with [`will_paginate`](https://github.com/mislav/will_paginate),
|
478
|
+
so you can pass all the usual parameters to the `search` method in the controller:
|
409
479
|
|
410
480
|
```ruby
|
411
481
|
@articles = Article.search params[:q], :page => (params[:page] || 1)
|
412
482
|
```
|
413
483
|
|
414
|
-
OK. Chances are, you have lots of records stored in
|
484
|
+
OK. Chances are, you have lots of records stored in your database. How will you get them to _ElasticSearch_? Easy:
|
415
485
|
|
416
486
|
```ruby
|
417
487
|
Article.elasticsearch_index.import Article.all
|
418
488
|
```
|
419
489
|
|
420
|
-
|
490
|
+
This way, however, all your records are loaded into memory, serialized into JSON,
|
421
491
|
and sent down the wire to _ElasticSearch_. Not practical, you say? You're right.
|
422
492
|
|
423
|
-
Provided your model implements some sort of _pagination_ — and it probably does
|
424
|
-
you can just run:
|
493
|
+
Provided your model implements some sort of _pagination_ — and it probably does —, you can just run:
|
425
494
|
|
426
495
|
```ruby
|
427
496
|
Article.import
|
@@ -453,14 +522,14 @@ provided by the `mapping` block in your model):
|
|
453
522
|
When you'll spend more time with _ElasticSearch_, you'll notice how
|
454
523
|
[index aliases](http://www.elasticsearch.org/guide/reference/api/admin-indices-aliases.html)
|
455
524
|
are the best idea since the invention of inverted index.
|
456
|
-
You can index your data into a fresh index (and possibly update an alias
|
525
|
+
You can index your data into a fresh index (and possibly update an alias once everything's fine):
|
457
526
|
|
458
527
|
```bash
|
459
528
|
$ rake environment tire:import CLASS='Article' INDEX='articles-2011-05'
|
460
529
|
```
|
461
530
|
|
462
531
|
OK. All this time we have been talking about `ActiveRecord` models, since
|
463
|
-
it is a reasonable
|
532
|
+
it is a reasonable _Rails_' default for the storage layer.
|
464
533
|
|
465
534
|
But what if you use another database such as [MongoDB](http://www.mongodb.org/),
|
466
535
|
another object mapping library, such as [Mongoid](http://mongoid.org/)?
|
@@ -494,12 +563,10 @@ Well, things stay mostly the same:
|
|
494
563
|
Article.search 'love'
|
495
564
|
```
|
496
565
|
|
497
|
-
|
566
|
+
_Tire_ does not care what's your primary data storage solution, if it has an _ActiveModel_-compatible
|
567
|
+
adapter. But there's more.
|
498
568
|
|
499
|
-
_Tire_ implements not only _searchable_ features, but also _persistence_ features.
|
500
|
-
|
501
|
-
This means that you can use a _Tire_ model **instead of** your database, not just
|
502
|
-
for searching your database. Why would you like to do that?
|
569
|
+
_Tire_ implements not only _searchable_ features, but also _persistence_ features. This means you can use a _Tire_ model **instead of your database**, not just for _searching_ your database. Why would you like to do that?
|
503
570
|
|
504
571
|
Well, because you're tired of database migrations and lots of hand-holding with your
|
505
572
|
database to store stuff like `{ :name => 'Tire', :tags => [ 'ruby', 'search' ] }`.
|
@@ -510,8 +577,7 @@ then constructing elaborate database query conditions.
|
|
510
577
|
Because you have _lots_ of data and want to use _ElasticSearch's_
|
511
578
|
advanced distributed features.
|
512
579
|
|
513
|
-
To use the persistence features,
|
514
|
-
in your class and define the properties (analogous to the way you do with CouchDB- or MongoDB-based models):
|
580
|
+
To use the persistence features, just include the `Tire::Persistence` module in your class and define the properties (like with _CouchDB_- or _MongoDB_-based models):
|
515
581
|
|
516
582
|
```ruby
|
517
583
|
class Article
|
@@ -532,6 +598,9 @@ Of course, not all validations or `ActionPack` helpers will be available to your
|
|
532
598
|
but if you can live with that, you've just got a schema-free, highly-scalable storage
|
533
599
|
and retrieval engine for your data.
|
534
600
|
|
601
|
+
Please be sure to peruse the [integration test suite](https://github.com/karmi/tire/tree/master/test/integration)
|
602
|
+
for examples of the API and _ActiveModel_ integration usage.
|
603
|
+
|
535
604
|
Todo, Plans & Ideas
|
536
605
|
-------------------
|
537
606
|
|
data/examples/tire-dsl.rb
CHANGED
@@ -43,9 +43,9 @@ require 'tire'
|
|
43
43
|
|
44
44
|
[ERROR] You don’t appear to have ElasticSearch installed. Please install and launch it with the following commands:
|
45
45
|
|
46
|
-
curl -k -L -o elasticsearch-0.
|
47
|
-
tar -zxvf elasticsearch-0.
|
48
|
-
./elasticsearch-0.
|
46
|
+
curl -k -L -o elasticsearch-0.17.2.tar.gz http://github.com/downloads/elasticsearch/elasticsearch/elasticsearch-0.17.2.tar.gz
|
47
|
+
tar -zxvf elasticsearch-0.17.2.tar.gz
|
48
|
+
./elasticsearch-0.17.2/bin/elasticsearch -f
|
49
49
|
INSTALL
|
50
50
|
|
51
51
|
### Storing and indexing documents
|
@@ -667,7 +667,7 @@ s = Tire.search 'articles' do
|
|
667
667
|
|
668
668
|
# ... but will sort them by their `title`, in descending order.
|
669
669
|
#
|
670
|
-
sort { title 'desc' }
|
670
|
+
sort { by :title, 'desc' }
|
671
671
|
end
|
672
672
|
|
673
673
|
# The results:
|
@@ -692,11 +692,11 @@ s = Tire.search 'articles' do
|
|
692
692
|
|
693
693
|
# We will sort the results by their `published_on` property in _ascending_ order (the default),
|
694
694
|
#
|
695
|
-
published_on
|
695
|
+
by :published_on
|
696
696
|
|
697
697
|
# and by their `title` property, in _descending_ order.
|
698
698
|
#
|
699
|
-
title 'desc'
|
699
|
+
by :title 'desc'
|
700
700
|
end
|
701
701
|
end
|
702
702
|
|
data/lib/tire/index.rb
CHANGED
@@ -41,21 +41,8 @@ module Tire
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def store(*args)
|
44
|
-
|
45
|
-
|
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)
|
58
|
-
end
|
44
|
+
document, options = args
|
45
|
+
type = get_type_from_document(document)
|
59
46
|
|
60
47
|
if options
|
61
48
|
percolate = options[:percolate]
|
@@ -118,7 +105,7 @@ module Tire
|
|
118
105
|
when method
|
119
106
|
options = {:page => 1, :per_page => 1000}.merge options
|
120
107
|
while documents = klass_or_collection.send(method.to_sym, options.merge(:page => options[:page])) \
|
121
|
-
and documents.
|
108
|
+
and not documents.empty?
|
122
109
|
documents = yield documents if block_given?
|
123
110
|
|
124
111
|
bulk_store documents
|
@@ -218,15 +205,8 @@ module Tire
|
|
218
205
|
end
|
219
206
|
|
220
207
|
def percolate(*args, &block)
|
221
|
-
|
222
|
-
|
223
|
-
"please pass a Hash with _type/type property, or " +
|
224
|
-
"an object with _type/type/document_type method."
|
225
|
-
type, document = args
|
226
|
-
else
|
227
|
-
document = args.pop
|
228
|
-
type = get_type_from_document(document)
|
229
|
-
end
|
208
|
+
document = args.pop
|
209
|
+
type = get_type_from_document(document)
|
230
210
|
|
231
211
|
document = MultiJson.decode convert_document_to_json(document)
|
232
212
|
|
@@ -273,14 +253,14 @@ module Tire
|
|
273
253
|
when document.respond_to?(:document_type)
|
274
254
|
document.document_type
|
275
255
|
when document.is_a?(Hash)
|
276
|
-
document
|
256
|
+
document[:_type] || document['_type'] || document[:type] || document['type']
|
277
257
|
when document.respond_to?(:_type)
|
278
258
|
document._type
|
279
259
|
when document.respond_to?(:type) && document.type != document.class
|
280
260
|
document.type
|
281
261
|
end
|
282
262
|
$VERBOSE = old_verbose
|
283
|
-
type
|
263
|
+
type || :document
|
284
264
|
end
|
285
265
|
|
286
266
|
def get_id_from_document(document)
|