elastictastic 0.10.9 → 0.11.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.
@@ -6,28 +6,54 @@ module Elastictastic
|
|
6
6
|
|
7
7
|
module ClassMethods
|
8
8
|
|
9
|
-
def create_or_update(
|
9
|
+
def create_or_update(*ids, &block)
|
10
10
|
scope = current_scope
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
11
|
+
ids.each do |id|
|
12
|
+
begin
|
13
|
+
new.tap do |instance|
|
14
|
+
instance.id = id
|
15
|
+
yield instance
|
16
|
+
end.create do |e|
|
17
|
+
case e
|
18
|
+
when nil # chill
|
19
|
+
when Elastictastic::ServerError::DocumentAlreadyExistsEngineException,
|
20
|
+
Elastictastic::ServerError::DocumentAlreadyExistsException # 0.19+
|
21
|
+
scope.update(id, &block)
|
22
|
+
else
|
23
|
+
raise e
|
24
|
+
end
|
25
|
+
end
|
26
|
+
rescue Elastictastic::CancelSave
|
27
|
+
# Do Nothing
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def update(*ids, &block)
|
33
|
+
[].tap do |found|
|
34
|
+
case ids.length
|
35
|
+
when 0 then return
|
36
|
+
when 1
|
37
|
+
id = ids.first
|
38
|
+
instance = scoped({}).find_one(id, :preference => '_primary_first')
|
39
|
+
return unless instance
|
40
|
+
found << id
|
41
|
+
instances = [instance]
|
20
42
|
else
|
21
|
-
|
43
|
+
instances = scoped({}).
|
44
|
+
find_many(ids, :preference => '_primary_first')
|
45
|
+
found.concat(instances.map { |instance| instance.id })
|
46
|
+
end
|
47
|
+
instances.each do |instance|
|
48
|
+
instance.try_update(current_scope, &block)
|
22
49
|
end
|
23
50
|
end
|
24
|
-
rescue Elastictastic::CancelSave
|
25
|
-
# Do Nothing
|
26
51
|
end
|
27
52
|
|
28
|
-
def
|
29
|
-
|
30
|
-
|
53
|
+
def update_or_create(*ids, &block)
|
54
|
+
updated_ids = update(*ids, &block)
|
55
|
+
create_ids = ids - updated_ids
|
56
|
+
create_or_update(*create_ids, &block) if create_ids.any?
|
31
57
|
end
|
32
58
|
|
33
59
|
def update_each(&block)
|
data/lib/elastictastic/scope.rb
CHANGED
@@ -282,6 +282,19 @@ module Elastictastic
|
|
282
282
|
end
|
283
283
|
end
|
284
284
|
|
285
|
+
#
|
286
|
+
# @private
|
287
|
+
#
|
288
|
+
def find_many(ids, params = {})
|
289
|
+
docspec = ids.map do |id|
|
290
|
+
{ '_id' => id }.merge!(params_for_find_many).
|
291
|
+
merge!(params.stringify_keys)
|
292
|
+
end
|
293
|
+
materialize_hits(
|
294
|
+
::Elastictastic.client.mget(docspec, index, type)['docs']
|
295
|
+
).map { |result, hit| result }
|
296
|
+
end
|
297
|
+
|
285
298
|
def multi_get_params
|
286
299
|
{
|
287
300
|
'_type' => type,
|
@@ -380,16 +393,6 @@ module Elastictastic
|
|
380
393
|
self.counts = search(params)
|
381
394
|
end
|
382
395
|
|
383
|
-
def find_many(ids, params = {})
|
384
|
-
docspec = ids.map do |id|
|
385
|
-
{ '_id' => id }.merge!(params_for_find_many).
|
386
|
-
merge!(params.stringify_keys)
|
387
|
-
end
|
388
|
-
materialize_hits(
|
389
|
-
::Elastictastic.client.mget(docspec, index, type)['docs']
|
390
|
-
).map { |result, hit| result }
|
391
|
-
end
|
392
|
-
|
393
396
|
def params_for_find_one
|
394
397
|
params_for_find.tap do |params|
|
395
398
|
params['fields'] &&= params['fields'].join(',')
|
@@ -113,6 +113,52 @@ describe Elastictastic::OptimisticLocking do
|
|
113
113
|
end
|
114
114
|
end # describe '::update'
|
115
115
|
|
116
|
+
describe '::update with multiple arguments' do
|
117
|
+
let(:last_update_request) do
|
118
|
+
FakeWeb.requests.reverse.find { |req| req.method == 'PUT' }
|
119
|
+
end
|
120
|
+
|
121
|
+
before do
|
122
|
+
stub_es_mget(
|
123
|
+
index,
|
124
|
+
'post',
|
125
|
+
'1' => {},
|
126
|
+
'2' => {}
|
127
|
+
)
|
128
|
+
stub_es_get(index, 'post', '2', { :title => 'Hey' }, 2)
|
129
|
+
stub_es_update(index, 'post', '1')
|
130
|
+
stub_request_json(
|
131
|
+
:put,
|
132
|
+
match_es_resource(index, 'post', '2'),
|
133
|
+
version_conflict,
|
134
|
+
generate_es_hit('post', :id => '2', :index => index, :version => 3)
|
135
|
+
)
|
136
|
+
scope.update('1', '2') do |post|
|
137
|
+
post.comments_count = 2
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'should retry unsuccessful updates' do
|
142
|
+
FakeWeb.should have(5).requests # mget, update '1', update '2' (fail), get '2', update '2'
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'should re-perform update on failed document' do
|
146
|
+
URI.parse(last_update_request.path).path.should == "/#{index}/post/2"
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'should send data from latest version in persistence' do
|
150
|
+
Elastictastic.json_decode(last_update_request.body)['title'].should == 'Hey'
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'should send data from update block' do
|
154
|
+
Elastictastic.json_decode(last_update_request.body)['comments_count'].should == 2
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'should update with latest version' do
|
158
|
+
URI.parse(last_update_request.path).query.split('&').should include('version=2')
|
159
|
+
end
|
160
|
+
end # describe '::update with multiple requests'
|
161
|
+
|
116
162
|
describe '::update_each' do
|
117
163
|
let(:last_update_request) do
|
118
164
|
FakeWeb.requests.reverse.find { |req| req.method == 'PUT' }
|
@@ -383,6 +429,46 @@ describe Elastictastic::OptimisticLocking do
|
|
383
429
|
last_request_json['title'].should == 'hey'
|
384
430
|
end
|
385
431
|
end
|
432
|
+
|
433
|
+
context "with multiple arguments some of which exist" do
|
434
|
+
before do
|
435
|
+
stub_es_create('my_index', 'post', '1')
|
436
|
+
stub_request_json(
|
437
|
+
:put,
|
438
|
+
match_es_path('/my_index/post/2/_create'),
|
439
|
+
already_exists
|
440
|
+
)
|
441
|
+
stub_es_get('my_index', 'post', '2', :comments_count => 2)
|
442
|
+
stub_es_update('my_index', 'post', '2')
|
443
|
+
Post.in_index('my_index').create_or_update('1', '2') do |post|
|
444
|
+
post.title = "hey #{post.id}"
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
it 'should post to create endpoint for both documents' do
|
449
|
+
FakeWeb.requests.
|
450
|
+
should be_any { |request| request.path == '/my_index/post/1/_create' }
|
451
|
+
FakeWeb.requests.
|
452
|
+
should be_any { |request| request.path == '/my_index/post/2/_create' }
|
453
|
+
end
|
454
|
+
|
455
|
+
it 'should not send update request for successful create' do
|
456
|
+
FakeWeb.requests.
|
457
|
+
should_not be_any { |request| request.path == '/my_index/post/1?version=1' }
|
458
|
+
end
|
459
|
+
|
460
|
+
it 'should re-update existing data with correct version' do
|
461
|
+
last_request.path.should == '/my_index/post/2?version=1'
|
462
|
+
end
|
463
|
+
|
464
|
+
it 'should include data from storage' do
|
465
|
+
last_request_json['comments_count'].should == 2
|
466
|
+
end
|
467
|
+
|
468
|
+
it 'should include updated data from block' do
|
469
|
+
last_request_json['title'].should == 'hey 2'
|
470
|
+
end
|
471
|
+
end
|
386
472
|
end
|
387
473
|
|
388
474
|
context 'with bulk persistence' do
|
@@ -413,4 +499,44 @@ describe Elastictastic::OptimisticLocking do
|
|
413
499
|
end
|
414
500
|
end
|
415
501
|
end
|
502
|
+
|
503
|
+
describe '::update_or_create' do
|
504
|
+
let(:scope) { Post }
|
505
|
+
|
506
|
+
before do
|
507
|
+
stub_es_mget(
|
508
|
+
'default', 'post',
|
509
|
+
'1' => {title: 'Post 1'},
|
510
|
+
'2' => nil
|
511
|
+
)
|
512
|
+
stub_es_update('default', 'post', '1')
|
513
|
+
stub_es_create('default', 'post', '2')
|
514
|
+
scope.update_or_create('1', '2') do |post|
|
515
|
+
post.comments_count = 1
|
516
|
+
end
|
517
|
+
end
|
518
|
+
|
519
|
+
let :create_request do
|
520
|
+
FakeWeb.requests.
|
521
|
+
find { |request| request.path == "/default/post/2/_create" }
|
522
|
+
end
|
523
|
+
|
524
|
+
let :update_request do
|
525
|
+
FakeWeb.requests.
|
526
|
+
find { |request| request.path =~ %r(^/default/post/1\??) }
|
527
|
+
end
|
528
|
+
|
529
|
+
it 'should not send any extraneous requests' do
|
530
|
+
FakeWeb.should have(3).requests # multiget, create, update
|
531
|
+
end
|
532
|
+
|
533
|
+
it 'should send create request for nonexistent document' do
|
534
|
+
create_request.should be
|
535
|
+
end
|
536
|
+
|
537
|
+
it 'should send update request for existent document' do
|
538
|
+
update_request.should be
|
539
|
+
end
|
540
|
+
end
|
541
|
+
|
416
542
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: elastictastic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2013-
|
14
|
+
date: 2013-03-28 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: activesupport
|
@@ -250,7 +250,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
250
250
|
requirements:
|
251
251
|
- ElasticSearch
|
252
252
|
rubyforge_project:
|
253
|
-
rubygems_version: 1.8.
|
253
|
+
rubygems_version: 1.8.25
|
254
254
|
signing_key:
|
255
255
|
specification_version: 3
|
256
256
|
summary: Object-document mapper for ElasticSearch
|