tire 0.5.2 → 0.5.3
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 +12 -0
- data/Rakefile +5 -1
- data/examples/tire-dsl.rb +62 -6
- data/lib/tire/index.rb +1 -1
- data/lib/tire/results/collection.rb +10 -1
- data/lib/tire/search/query.rb +28 -0
- data/lib/tire/version.rb +4 -5
- data/test/integration/active_record_searchable_test.rb +13 -0
- data/test/integration/index_update_document_test.rb +10 -0
- data/test/integration/nested_query_test.rb +135 -0
- data/test/integration/results_test.rb +13 -1
- data/test/unit/index_test.rb +20 -6
- data/test/unit/results_collection_test.rb +34 -0
- data/test/unit/search_query_test.rb +23 -1
- metadata +43 -42
data/README.markdown
CHANGED
@@ -617,6 +617,18 @@ Instead of simple `true`, you can pass any options for the model's find method:
|
|
617
617
|
end
|
618
618
|
```
|
619
619
|
|
620
|
+
If you would like to access properties returned by Elasticsearch (such as `_score`),
|
621
|
+
in addition to model instance, use the `each_with_hit` method:
|
622
|
+
|
623
|
+
```ruby
|
624
|
+
results = Article.search 'One', :load => true
|
625
|
+
results.each_with_hit do |result, hit|
|
626
|
+
puts "#{result.title} (score: #{hit['_score']})"
|
627
|
+
end
|
628
|
+
|
629
|
+
# One (score: 0.300123)
|
630
|
+
```
|
631
|
+
|
620
632
|
Note that _Tire_ search results are fully compatible with [`will_paginate`](https://github.com/mislav/will_paginate),
|
621
633
|
so you can pass all the usual parameters to the `search` method in the controller:
|
622
634
|
|
data/Rakefile
CHANGED
@@ -28,7 +28,11 @@ namespace :web do
|
|
28
28
|
|
29
29
|
desc "Update the Github website"
|
30
30
|
task :update => :generate do
|
31
|
-
current_branch = `git branch --no-color`.
|
31
|
+
current_branch = `git branch --no-color`.
|
32
|
+
split("\n").
|
33
|
+
select { |line| line =~ /^\* / }.
|
34
|
+
first.to_s.
|
35
|
+
gsub(/\* (.*)/, '\1')
|
32
36
|
(puts "Unable to determine current branch"; exit(1) ) unless current_branch
|
33
37
|
system "git checkout web"
|
34
38
|
system "cp examples/tire-dsl.html index.html"
|
data/examples/tire-dsl.rb
CHANGED
@@ -121,6 +121,8 @@ end
|
|
121
121
|
# for the index.
|
122
122
|
|
123
123
|
Tire.index 'articles' do
|
124
|
+
delete
|
125
|
+
|
124
126
|
# To do so, let's just pass a Hash containing the specified mapping to the `Index#create` method.
|
125
127
|
#
|
126
128
|
create :mappings => {
|
@@ -179,8 +181,6 @@ end
|
|
179
181
|
# Of course, we can easily manipulate the documents before storing them in the index.
|
180
182
|
#
|
181
183
|
Tire.index 'articles' do
|
182
|
-
delete
|
183
|
-
|
184
184
|
# ... by passing a block to the `import` method. The collection will
|
185
185
|
# be available in the block argument.
|
186
186
|
#
|
@@ -710,6 +710,7 @@ s = Tire.search 'articles' do
|
|
710
710
|
end
|
711
711
|
|
712
712
|
# The results:
|
713
|
+
#
|
713
714
|
# * One (Published on: 2011-01-01)
|
714
715
|
# * Two (Published on: 2011-01-02)
|
715
716
|
# * Three (Published on: 2011-01-02)
|
@@ -719,6 +720,60 @@ s.results.each do |document|
|
|
719
720
|
puts "* #{ document.title.ljust(10) } (Published on: #{ document.published_on })"
|
720
721
|
end
|
721
722
|
|
723
|
+
#### Nested Documents and Queries
|
724
|
+
|
725
|
+
# Often, we want to store more complex entities in _Elasticsearch_;
|
726
|
+
# for example, we may want to store the information about comments for each article,
|
727
|
+
# and then search for articles where a certain person left a certain note.
|
728
|
+
|
729
|
+
# In the simplest case, we can store the comments as an Array of JSON documents in the
|
730
|
+
# article document. If we do that naively, our search results will be incorrect, though.
|
731
|
+
# That's because a match in just one field will be enough to match a document.
|
732
|
+
# We need to query parts of the document as if they were separate entities.
|
733
|
+
|
734
|
+
# _Elasticsearch_ provides a specific `nested`
|
735
|
+
# [field type](http://www.elasticsearch.org/guide/reference/mapping/nested-type.html) and
|
736
|
+
# [query](http://www.elasticsearch.org/guide/reference/query-dsl/nested-query.html)
|
737
|
+
# for working with "embedded" documents like these.
|
738
|
+
|
739
|
+
# So, let's update the mapping for the index first, adding the `comments` property as a `nested` type:
|
740
|
+
#
|
741
|
+
Tire::Configuration.client.put Tire.index('articles').url+'/article/_mapping',
|
742
|
+
{ :article => { :properties => { :comments => { :type => 'nested' } } } }.to_json
|
743
|
+
|
744
|
+
# And let's add comments to articles (notice that both articles contain a comment with the _Cool!_ message,
|
745
|
+
# though by different authors):
|
746
|
+
#
|
747
|
+
Tire.index 'articles' do
|
748
|
+
update :article, 1,
|
749
|
+
:doc => { :comments => [ { :author => 'John', :message => 'Great!' }, { :author => 'Bob', :message => 'Cool!' } ] }
|
750
|
+
update :article, 2,
|
751
|
+
:doc => { :comments => [ { :author => 'John', :message => 'Cool!' }, { :author => 'Mary', :message => 'Thanks!' } ] }
|
752
|
+
refresh
|
753
|
+
end
|
754
|
+
|
755
|
+
# We'll use the `nested` query to search for articles where _John_ left a _"Cool"_ message:
|
756
|
+
#
|
757
|
+
s = Tire.search 'articles' do
|
758
|
+
query do
|
759
|
+
nested :path => 'comments' do
|
760
|
+
query do
|
761
|
+
match 'comments.author', 'John'
|
762
|
+
match 'comments.message', 'cool'
|
763
|
+
end
|
764
|
+
end
|
765
|
+
end
|
766
|
+
end
|
767
|
+
|
768
|
+
# The results contain just the second document, correctly:
|
769
|
+
#
|
770
|
+
# * Two (comments: 2)
|
771
|
+
#
|
772
|
+
s.results.each do |document|
|
773
|
+
puts "* #{ document.title } (comments: #{document.comments.size})"
|
774
|
+
end
|
775
|
+
|
776
|
+
|
722
777
|
#### Highlighting
|
723
778
|
|
724
779
|
# Often, we want to highlight the snippets matching our query in the displayed results.
|
@@ -839,7 +894,8 @@ puts "Matching queries: " + matches.inspect
|
|
839
894
|
|
840
895
|
# Let's store a document with some trigger words in the index, and mark it for percolation.
|
841
896
|
#
|
842
|
-
response = index.store :message => '[Warning] Severe floods expected after tsunami wave.',
|
897
|
+
response = index.store( { :message => '[Warning] Severe floods expected after tsunami wave.' },
|
898
|
+
{ :percolate => true } )
|
843
899
|
|
844
900
|
# We will get the names of all matching queries in response.
|
845
901
|
#
|
@@ -849,9 +905,9 @@ puts "Matching queries: " + response['matches'].inspect
|
|
849
905
|
|
850
906
|
# As with the _percolate_ example, we can filter the executed queries.
|
851
907
|
#
|
852
|
-
response = index.store :message => '[Warning] Severe floods expected after tsunami wave.',
|
853
|
-
|
854
|
-
|
908
|
+
response = index.store( { :message => '[Warning] Severe floods expected after tsunami wave.' },
|
909
|
+
# Let's use a simple string query for the “tsunami” tag.
|
910
|
+
{ :percolate => 'tags:tsunami' } )
|
855
911
|
|
856
912
|
# Unsurprisingly, the response will contain just the name of the “tsunami” query.
|
857
913
|
#
|
data/lib/tire/index.rb
CHANGED
@@ -276,7 +276,7 @@ module Tire
|
|
276
276
|
def update(type, id, payload={}, options={})
|
277
277
|
raise ArgumentError, "Please pass a document type" unless type
|
278
278
|
raise ArgumentError, "Please pass a document ID" unless id
|
279
|
-
raise ArgumentError, "Please pass a script in the payload hash" unless payload[:script]
|
279
|
+
raise ArgumentError, "Please pass a script or partial document in the payload hash" unless payload[:script] || payload[:doc]
|
280
280
|
|
281
281
|
type = Utils.escape(type)
|
282
282
|
url = "#{self.url}/#{type}/#{id}/_update"
|
@@ -29,10 +29,20 @@ module Tire
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
# Iterates over the `results` collection
|
33
|
+
#
|
32
34
|
def each(&block)
|
33
35
|
results.each(&block)
|
34
36
|
end
|
35
37
|
|
38
|
+
# Iterates over the `results` collection and yields
|
39
|
+
# the `result` object (Item or model instance) and the
|
40
|
+
# `hit` -- raw Elasticsearch response parsed as a Hash
|
41
|
+
#
|
42
|
+
def each_with_hit(&block)
|
43
|
+
results.zip(@response['hits']['hits']).each(&block)
|
44
|
+
end
|
45
|
+
|
36
46
|
def empty?
|
37
47
|
results.empty?
|
38
48
|
end
|
@@ -136,7 +146,6 @@ module Tire
|
|
136
146
|
def __find_records_by_ids(klass, ids)
|
137
147
|
@options[:load] === true ? klass.find(ids) : klass.find(ids, @options[:load])
|
138
148
|
end
|
139
|
-
|
140
149
|
end
|
141
150
|
|
142
151
|
end
|
data/lib/tire/search/query.rb
CHANGED
@@ -82,6 +82,13 @@ module Tire
|
|
82
82
|
@value
|
83
83
|
end
|
84
84
|
|
85
|
+
def nested(options={}, &block)
|
86
|
+
@nested = NestedQuery.new(options)
|
87
|
+
block.arity < 1 ? @nested.instance_eval(&block) : block.call(@nested) if block_given?
|
88
|
+
@value[:nested] = @nested.to_hash
|
89
|
+
@value
|
90
|
+
end
|
91
|
+
|
85
92
|
def all(options = {})
|
86
93
|
@value = { :match_all => options }
|
87
94
|
@value
|
@@ -196,6 +203,27 @@ module Tire
|
|
196
203
|
end
|
197
204
|
end
|
198
205
|
|
206
|
+
class NestedQuery
|
207
|
+
def initialize(options={}, &block)
|
208
|
+
@options = options
|
209
|
+
@value = {}
|
210
|
+
block.arity < 1 ? self.instance_eval(&block) : block.call(self) if block_given?
|
211
|
+
end
|
212
|
+
|
213
|
+
def query(&block)
|
214
|
+
@value[:query] = Query.new(&block).to_hash
|
215
|
+
@value
|
216
|
+
end
|
217
|
+
|
218
|
+
def to_hash
|
219
|
+
@value.update(@options)
|
220
|
+
end
|
221
|
+
|
222
|
+
def to_json
|
223
|
+
to_hash.to_json
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
199
227
|
class BoostingQuery
|
200
228
|
def initialize(options={}, &block)
|
201
229
|
@options = options
|
data/lib/tire/version.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
module Tire
|
2
|
-
VERSION = "0.5.
|
2
|
+
VERSION = "0.5.3"
|
3
3
|
|
4
4
|
CHANGELOG =<<-END
|
5
5
|
IMPORTANT CHANGES LATELY:
|
6
6
|
|
7
|
-
*
|
8
|
-
*
|
9
|
-
*
|
10
|
-
* Fix issues with Mongoid gem (incorrect JSON serialization of Moped::BSON::ObjectId)
|
7
|
+
* Added `Tire::Results::Collection#each_with_hit`
|
8
|
+
* Added support for passing partial document to `Index#update`
|
9
|
+
* Added `nested` query support
|
11
10
|
END
|
12
11
|
end
|
@@ -145,6 +145,19 @@ module Tire
|
|
145
145
|
assert ! results.any?
|
146
146
|
end
|
147
147
|
end
|
148
|
+
|
149
|
+
should "iterate results with hits" do
|
150
|
+
results = ActiveRecordArticle.search :load => true do
|
151
|
+
query { string '"Test 1" OR "Test 2"' }
|
152
|
+
end
|
153
|
+
results.each_with_hit do |result, hit|
|
154
|
+
assert_instance_of ActiveRecordArticle, result
|
155
|
+
assert_instance_of Hash, hit
|
156
|
+
assert_match /Test \d/, result.title
|
157
|
+
assert_match /Test \d/, hit['_source']['title']
|
158
|
+
assert hit['_score'] > 0
|
159
|
+
end
|
160
|
+
end
|
148
161
|
end
|
149
162
|
|
150
163
|
context "with pagination" do
|
@@ -79,6 +79,16 @@ module Tire
|
|
79
79
|
assert_equal 3, document.tags.size, document.inspect
|
80
80
|
end
|
81
81
|
|
82
|
+
should "update the document with a partial one" do
|
83
|
+
Tire.index('articles-with-tags') do
|
84
|
+
update( 'article', '1', :doc => { :title => 'One UPDATED' } )
|
85
|
+
refresh
|
86
|
+
end
|
87
|
+
|
88
|
+
document = Tire.search('articles-with-tags') { query { string 'title:one' } }.results.first
|
89
|
+
assert_equal 'One UPDATED', document.title, document.inspect
|
90
|
+
end
|
91
|
+
|
82
92
|
should "access variables from the outer scope" do
|
83
93
|
$t = self
|
84
94
|
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Tire
|
4
|
+
|
5
|
+
class NestedQueryTest < Test::Unit::TestCase
|
6
|
+
include Test::Integration
|
7
|
+
|
8
|
+
context 'Nested queries' do
|
9
|
+
|
10
|
+
setup do
|
11
|
+
@index = Tire.index('products-test') do
|
12
|
+
delete
|
13
|
+
|
14
|
+
create mappings: {
|
15
|
+
product: {
|
16
|
+
properties: {
|
17
|
+
name: { type: 'string' },
|
18
|
+
variants: { type: 'nested', size: 'string', color: 'string' }
|
19
|
+
}
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
store type: 'product',
|
24
|
+
name: 'Duck Shirt',
|
25
|
+
variants: [{ size: 'M', color: 'yellow'}, { size: 'L', color: 'silver'}]
|
26
|
+
store type: 'product',
|
27
|
+
name: 'Western Shirt',
|
28
|
+
variants: [{ size: 'S', color: 'yellow'}, { size: 'M', color: 'silver'}]
|
29
|
+
|
30
|
+
refresh
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# teardown { @index.delete }
|
35
|
+
|
36
|
+
should "not return a results when properties match for different objects" do
|
37
|
+
s = Tire.search @index.name do
|
38
|
+
query do
|
39
|
+
nested path: 'variants' do
|
40
|
+
query do
|
41
|
+
boolean do
|
42
|
+
# No product matches size "S" and color "silver"
|
43
|
+
must { match 'variants.size', 'S' }
|
44
|
+
must { match 'variants.color', 'silver'}
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
assert_equal 0, s.results.size
|
52
|
+
end
|
53
|
+
|
54
|
+
should "return all matching documents when nested documents meet criteria" do
|
55
|
+
s = Tire.search @index.name do
|
56
|
+
query do
|
57
|
+
nested path: 'variants' do
|
58
|
+
query do
|
59
|
+
match 'variants.size', 'M'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
assert_equal 2, s.results.size
|
66
|
+
end
|
67
|
+
|
68
|
+
should "return matching document when a nested document meets all criteria" do
|
69
|
+
s = Tire.search @index.name do
|
70
|
+
query do
|
71
|
+
nested path: 'variants' do
|
72
|
+
query do
|
73
|
+
boolean do
|
74
|
+
must { match 'variants.size', 'M' }
|
75
|
+
must { match 'variants.color', 'silver'}
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
assert_equal 1, s.results.size
|
83
|
+
assert_equal 'Western Shirt', s.results.first.name
|
84
|
+
end
|
85
|
+
|
86
|
+
should "return matching document when both the query and nested document meet all criteria" do
|
87
|
+
s = Tire.search @index.name do
|
88
|
+
query do
|
89
|
+
boolean do
|
90
|
+
must do
|
91
|
+
match 'name', 'Western'
|
92
|
+
end
|
93
|
+
must do
|
94
|
+
nested path: 'variants' do
|
95
|
+
query do
|
96
|
+
match 'variants.size', 'M'
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
assert_equal 1, s.results.size
|
105
|
+
assert_equal 'Western Shirt', s.results.first.name
|
106
|
+
end
|
107
|
+
|
108
|
+
should "not return results when the query and the nested document contradict" do
|
109
|
+
s = Tire.search @index.name do
|
110
|
+
query do
|
111
|
+
boolean do
|
112
|
+
must do
|
113
|
+
match 'name', 'Duck'
|
114
|
+
end
|
115
|
+
must do
|
116
|
+
nested path: 'variants' do
|
117
|
+
query do
|
118
|
+
boolean do
|
119
|
+
must { match 'variants.size', 'M' }
|
120
|
+
must { match 'variants.color', 'silver'}
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
assert_equal 0, s.results.size
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
@@ -32,8 +32,20 @@ module Tire
|
|
32
32
|
assert_nil s.results.first.published_on
|
33
33
|
end
|
34
34
|
|
35
|
-
|
35
|
+
should "iterate results with hits" do
|
36
|
+
s = Tire.search('articles-test') { query { string 'title:one' } }
|
37
|
+
|
38
|
+
s.results.each_with_hit do |result, hit|
|
39
|
+
assert_instance_of Tire::Results::Item, result
|
40
|
+
assert_instance_of Hash, hit
|
41
|
+
|
42
|
+
assert_equal 'One', result.title
|
43
|
+
assert_equal 'One', hit['_source']['title']
|
44
|
+
assert_not_nil hit['_score']
|
45
|
+
end
|
46
|
+
end
|
36
47
|
|
48
|
+
end
|
37
49
|
end
|
38
50
|
|
39
51
|
end
|
data/test/unit/index_test.rb
CHANGED
@@ -469,7 +469,7 @@ module Tire
|
|
469
469
|
|
470
470
|
context "when updating" do
|
471
471
|
|
472
|
-
should "send payload" do
|
472
|
+
should "send script payload" do
|
473
473
|
Configuration.client.expects(:post).with do |url,payload|
|
474
474
|
payload = MultiJson.decode(payload)
|
475
475
|
# p [url, payload]
|
@@ -484,6 +484,20 @@ module Tire
|
|
484
484
|
assert @index.update('document', '42', {:script => "ctx._source.foo = bar;", :params => { :bar => '21' }})
|
485
485
|
end
|
486
486
|
|
487
|
+
should "send partial doc payload" do
|
488
|
+
Configuration.client.expects(:post).with do |url,payload|
|
489
|
+
payload = MultiJson.decode(payload)
|
490
|
+
# p [url, payload]
|
491
|
+
assert_equal( "#{@index.url}/document/42/_update", url ) &&
|
492
|
+
assert_not_nil( payload['doc'] ) &&
|
493
|
+
assert_equal('bar', payload['doc']['foo'])
|
494
|
+
end.
|
495
|
+
returns(
|
496
|
+
mock_response('{"ok":"true","_index":"dummy","_type":"document","_id":"42","_version":"2"}'))
|
497
|
+
|
498
|
+
assert @index.update('document', '42', {:doc => {:foo => 'bar'}})
|
499
|
+
end
|
500
|
+
|
487
501
|
should "send options" do
|
488
502
|
Configuration.client.expects(:post).with do |url,payload|
|
489
503
|
payload = MultiJson.decode(payload)
|
@@ -501,11 +515,11 @@ module Tire
|
|
501
515
|
assert_raise(ArgumentError) { @index.update(nil, '123', :script => 'foobar') }
|
502
516
|
end
|
503
517
|
|
504
|
-
should "raise an error when no script is passed" do
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
518
|
+
should "raise an error when no script or partial document is passed" do
|
519
|
+
assert_raise ArgumentError do
|
520
|
+
@index.update('article', "42", {:foo => 'bar'})
|
521
|
+
end
|
522
|
+
end
|
509
523
|
|
510
524
|
end
|
511
525
|
|
@@ -198,6 +198,40 @@ module Tire
|
|
198
198
|
|
199
199
|
end
|
200
200
|
|
201
|
+
context "returning results with hits" do
|
202
|
+
should "yield the Item result and the raw hit" do
|
203
|
+
response = { 'hits' => { 'hits' => [ { '_id' => 1, '_score' => 0.5, '_index' => 'testing', '_type' => 'article', '_source' => { :title => 'Test', :body => 'Lorem' } } ] } }
|
204
|
+
|
205
|
+
Results::Collection.new(response).each_with_hit do |result, hit|
|
206
|
+
assert_instance_of Tire::Results::Item, result
|
207
|
+
assert_instance_of Hash, hit
|
208
|
+
assert_equal 'Test', result.title
|
209
|
+
assert_equal 0.5, hit['_score']
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
should "yield the model instance and the raw hit" do
|
214
|
+
response = { 'hits' => { 'hits' => [ {'_id' => 1, '_score' => 0.5, '_type' => 'active_record_article'} ] } }
|
215
|
+
|
216
|
+
ActiveRecord::Base.establish_connection( :adapter => 'sqlite3', :database => ":memory:" )
|
217
|
+
ActiveRecord::Migration.verbose = false
|
218
|
+
ActiveRecord::Schema.define(:version => 1) { create_table(:active_record_articles) { |t| t.string(:title) } }
|
219
|
+
model = ActiveRecordArticle.new(:title => 'Test'); model.id = 1
|
220
|
+
|
221
|
+
ActiveRecordArticle.expects(:find).with([1]).returns([ model] )
|
222
|
+
|
223
|
+
Results::Collection.new(response, :load => true).each_with_hit do |result, hit|
|
224
|
+
assert_instance_of ActiveRecordArticle, result
|
225
|
+
assert_instance_of Hash, hit
|
226
|
+
assert_equal 'Test', result.title
|
227
|
+
assert_equal 0.5, hit['_score']
|
228
|
+
end
|
229
|
+
|
230
|
+
end
|
231
|
+
|
232
|
+
|
233
|
+
end
|
234
|
+
|
201
235
|
context "while paginating results" do
|
202
236
|
|
203
237
|
setup do
|
@@ -374,7 +374,7 @@ module Tire::Search
|
|
374
374
|
|
375
375
|
should "allow searching in multiple fields with multi_match" do
|
376
376
|
assert_equal( { :multi_match => { :query => 'bar', :fields => [:foo, :moo] } },
|
377
|
-
|
377
|
+
Query.new.match([:foo, :moo], 'bar') )
|
378
378
|
end
|
379
379
|
|
380
380
|
should "encode options" do
|
@@ -393,5 +393,27 @@ module Tire::Search
|
|
393
393
|
|
394
394
|
end
|
395
395
|
|
396
|
+
context "NestedQuery" do
|
397
|
+
|
398
|
+
should "not raise an error when no block is given" do
|
399
|
+
assert_nothing_raised { Query.new.nested }
|
400
|
+
end
|
401
|
+
|
402
|
+
should "encode options" do
|
403
|
+
query = Query.new.nested(:path => 'articles', :score_mode => 'score_mode') do
|
404
|
+
query { string 'foo' }
|
405
|
+
end
|
406
|
+
|
407
|
+
assert_equal 'articles', query[:nested][:path]
|
408
|
+
assert_equal 'score_mode', query[:nested][:score_mode]
|
409
|
+
end
|
410
|
+
|
411
|
+
should "wrap single query" do
|
412
|
+
assert_equal( { :nested => {:query => { :query_string => { :query => 'foo' } } }},
|
413
|
+
Query.new.nested { query { string 'foo' } } )
|
414
|
+
end
|
415
|
+
|
416
|
+
end
|
417
|
+
|
396
418
|
end
|
397
419
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tire
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
requirement: &
|
16
|
+
requirement: &70315094856180 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70315094856180
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rest-client
|
27
|
-
requirement: &
|
27
|
+
requirement: &70315094855080 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '1.6'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70315094855080
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: multi_json
|
38
|
-
requirement: &
|
38
|
+
requirement: &70315094853880 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '1.0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70315094853880
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: activemodel
|
49
|
-
requirement: &
|
49
|
+
requirement: &70315094851380 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '3.0'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70315094851380
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: hashr
|
60
|
-
requirement: &
|
60
|
+
requirement: &70315094850020 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: 0.0.19
|
66
66
|
type: :runtime
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70315094850020
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: bundler
|
71
|
-
requirement: &
|
71
|
+
requirement: &70315094863680 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '1.0'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70315094863680
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: yajl-ruby
|
82
|
-
requirement: &
|
82
|
+
requirement: &70315094860660 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ~>
|
@@ -87,10 +87,10 @@ dependencies:
|
|
87
87
|
version: '1.0'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70315094860660
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: shoulda
|
93
|
-
requirement: &
|
93
|
+
requirement: &70315094860020 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
96
|
- - ! '>='
|
@@ -98,10 +98,10 @@ dependencies:
|
|
98
98
|
version: '0'
|
99
99
|
type: :development
|
100
100
|
prerelease: false
|
101
|
-
version_requirements: *
|
101
|
+
version_requirements: *70315094860020
|
102
102
|
- !ruby/object:Gem::Dependency
|
103
103
|
name: mocha
|
104
|
-
requirement: &
|
104
|
+
requirement: &70315094859360 !ruby/object:Gem::Requirement
|
105
105
|
none: false
|
106
106
|
requirements:
|
107
107
|
- - ! '>='
|
@@ -109,10 +109,10 @@ dependencies:
|
|
109
109
|
version: '0'
|
110
110
|
type: :development
|
111
111
|
prerelease: false
|
112
|
-
version_requirements: *
|
112
|
+
version_requirements: *70315094859360
|
113
113
|
- !ruby/object:Gem::Dependency
|
114
114
|
name: minitest
|
115
|
-
requirement: &
|
115
|
+
requirement: &70315094858240 !ruby/object:Gem::Requirement
|
116
116
|
none: false
|
117
117
|
requirements:
|
118
118
|
- - ~>
|
@@ -120,10 +120,10 @@ dependencies:
|
|
120
120
|
version: '2.12'
|
121
121
|
type: :development
|
122
122
|
prerelease: false
|
123
|
-
version_requirements: *
|
123
|
+
version_requirements: *70315094858240
|
124
124
|
- !ruby/object:Gem::Dependency
|
125
125
|
name: activerecord
|
126
|
-
requirement: &
|
126
|
+
requirement: &70315094857060 !ruby/object:Gem::Requirement
|
127
127
|
none: false
|
128
128
|
requirements:
|
129
129
|
- - ! '>='
|
@@ -131,10 +131,10 @@ dependencies:
|
|
131
131
|
version: '3.0'
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
|
-
version_requirements: *
|
134
|
+
version_requirements: *70315094857060
|
135
135
|
- !ruby/object:Gem::Dependency
|
136
136
|
name: sqlite3
|
137
|
-
requirement: &
|
137
|
+
requirement: &70315095012780 !ruby/object:Gem::Requirement
|
138
138
|
none: false
|
139
139
|
requirements:
|
140
140
|
- - ! '>='
|
@@ -142,10 +142,10 @@ dependencies:
|
|
142
142
|
version: '0'
|
143
143
|
type: :development
|
144
144
|
prerelease: false
|
145
|
-
version_requirements: *
|
145
|
+
version_requirements: *70315095012780
|
146
146
|
- !ruby/object:Gem::Dependency
|
147
147
|
name: mongoid
|
148
|
-
requirement: &
|
148
|
+
requirement: &70315095007180 !ruby/object:Gem::Requirement
|
149
149
|
none: false
|
150
150
|
requirements:
|
151
151
|
- - ~>
|
@@ -153,10 +153,10 @@ dependencies:
|
|
153
153
|
version: '2.2'
|
154
154
|
type: :development
|
155
155
|
prerelease: false
|
156
|
-
version_requirements: *
|
156
|
+
version_requirements: *70315095007180
|
157
157
|
- !ruby/object:Gem::Dependency
|
158
158
|
name: bson_ext
|
159
|
-
requirement: &
|
159
|
+
requirement: &70315095095540 !ruby/object:Gem::Requirement
|
160
160
|
none: false
|
161
161
|
requirements:
|
162
162
|
- - ! '>='
|
@@ -164,10 +164,10 @@ dependencies:
|
|
164
164
|
version: '0'
|
165
165
|
type: :development
|
166
166
|
prerelease: false
|
167
|
-
version_requirements: *
|
167
|
+
version_requirements: *70315095095540
|
168
168
|
- !ruby/object:Gem::Dependency
|
169
169
|
name: redis-persistence
|
170
|
-
requirement: &
|
170
|
+
requirement: &70315095094620 !ruby/object:Gem::Requirement
|
171
171
|
none: false
|
172
172
|
requirements:
|
173
173
|
- - ! '>='
|
@@ -175,10 +175,10 @@ dependencies:
|
|
175
175
|
version: '0'
|
176
176
|
type: :development
|
177
177
|
prerelease: false
|
178
|
-
version_requirements: *
|
178
|
+
version_requirements: *70315095094620
|
179
179
|
- !ruby/object:Gem::Dependency
|
180
180
|
name: curb
|
181
|
-
requirement: &
|
181
|
+
requirement: &70315095088820 !ruby/object:Gem::Requirement
|
182
182
|
none: false
|
183
183
|
requirements:
|
184
184
|
- - ! '>='
|
@@ -186,10 +186,10 @@ dependencies:
|
|
186
186
|
version: '0'
|
187
187
|
type: :development
|
188
188
|
prerelease: false
|
189
|
-
version_requirements: *
|
189
|
+
version_requirements: *70315095088820
|
190
190
|
- !ruby/object:Gem::Dependency
|
191
191
|
name: oj
|
192
|
-
requirement: &
|
192
|
+
requirement: &70315095113580 !ruby/object:Gem::Requirement
|
193
193
|
none: false
|
194
194
|
requirements:
|
195
195
|
- - ! '>='
|
@@ -197,10 +197,10 @@ dependencies:
|
|
197
197
|
version: '0'
|
198
198
|
type: :development
|
199
199
|
prerelease: false
|
200
|
-
version_requirements: *
|
200
|
+
version_requirements: *70315095113580
|
201
201
|
- !ruby/object:Gem::Dependency
|
202
202
|
name: turn
|
203
|
-
requirement: &
|
203
|
+
requirement: &70315095112560 !ruby/object:Gem::Requirement
|
204
204
|
none: false
|
205
205
|
requirements:
|
206
206
|
- - ~>
|
@@ -208,7 +208,7 @@ dependencies:
|
|
208
208
|
version: '0.9'
|
209
209
|
type: :development
|
210
210
|
prerelease: false
|
211
|
-
version_requirements: *
|
211
|
+
version_requirements: *70315095112560
|
212
212
|
description: ! " Tire is a Ruby client for the ElasticSearch search engine/database.\n\n
|
213
213
|
\ It provides Ruby-like API for fluent communication with the ElasticSearch server\n
|
214
214
|
\ and blends with ActiveModel class for convenient usage in Rails applications.\n\n
|
@@ -301,6 +301,7 @@ files:
|
|
301
301
|
- test/integration/match_query_test.rb
|
302
302
|
- test/integration/mongoid_searchable_test.rb
|
303
303
|
- test/integration/multi_search_test.rb
|
304
|
+
- test/integration/nested_query_test.rb
|
304
305
|
- test/integration/percolator_test.rb
|
305
306
|
- test/integration/persistent_model_test.rb
|
306
307
|
- test/integration/prefix_query_test.rb
|
@@ -359,10 +360,9 @@ homepage: http://github.com/karmi/tire
|
|
359
360
|
licenses: []
|
360
361
|
post_install_message: ! "================================================================================\n\n
|
361
362
|
\ Please check the documentation at <http://karmi.github.com/tire/>.\n\n--------------------------------------------------------------------------------\n\n
|
362
|
-
\ IMPORTANT CHANGES LATELY:\n\n *
|
363
|
-
\ *
|
364
|
-
|
365
|
-
serialization of Moped::BSON::ObjectId)\n\n See the full changelog at <http://github.com/karmi/tire/commits/v0.5.2>.\n\n--------------------------------------------------------------------------------\n"
|
363
|
+
\ IMPORTANT CHANGES LATELY:\n\n * Added `Tire::Results::Collection#each_with_hit`\n
|
364
|
+
\ * Added support for passing partial document to `Index#update`\n * Added `nested`
|
365
|
+
query support\n\n See the full changelog at <http://github.com/karmi/tire/commits/v0.5.3>.\n\n--------------------------------------------------------------------------------\n"
|
366
366
|
rdoc_options:
|
367
367
|
- --charset=UTF-8
|
368
368
|
require_paths:
|
@@ -414,6 +414,7 @@ test_files:
|
|
414
414
|
- test/integration/match_query_test.rb
|
415
415
|
- test/integration/mongoid_searchable_test.rb
|
416
416
|
- test/integration/multi_search_test.rb
|
417
|
+
- test/integration/nested_query_test.rb
|
417
418
|
- test/integration/percolator_test.rb
|
418
419
|
- test/integration/persistent_model_test.rb
|
419
420
|
- test/integration/prefix_query_test.rb
|