Skip to content

Commit 99105a1

Browse files
committed
Merge pull request #752 from estolfo/RUBY-1089-upserted-count
RUBY-1089 Fix aggregated counts reported by Bulk Update operation
2 parents 9ae6445 + 37255a1 commit 99105a1

File tree

6 files changed

+683
-786
lines changed

6 files changed

+683
-786
lines changed

lib/mongo/bulk_write/result.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ def upserted_count
166166
#
167167
# @since 2.1.0
168168
def upserted_ids
169-
@results[UPSERTED_IDS]
169+
@results[UPSERTED_IDS] || []
170170
end
171171

172172
# Validates the bulk write result.

lib/mongo/bulk_write/result_combiner.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ def result
7777

7878
def combine_counts!(result)
7979
Result::FIELDS.each do |field|
80-
if result.respond_to?(field)
81-
results.merge!(field => (results[field] || 0) + result.send(field))
80+
if result.respond_to?(field) && value = result.send(field)
81+
results.merge!(field => (results[field] || 0) + value)
8282
end
8383
end
8484
end

lib/mongo/operation/write/bulk/delete/result.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,11 @@ module Aggregatable
3434
def n_removed
3535
return 0 unless acknowledged?
3636
@replies.reduce(0) do |n, reply|
37-
n += reply.documents.first[Result::N]
37+
if reply.documents.first[Result::N]
38+
n += reply.documents.first[Result::N]
39+
else
40+
n
41+
end
3842
end
3943
end
4044
end

lib/mongo/operation/write/bulk/update/result.rb

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ def n_upserted
4646
return 0 unless acknowledged?
4747
@replies.reduce(0) do |n, reply|
4848
if upsert?(reply)
49-
n += 1
49+
n += reply.documents.first[UPSERTED].size
5050
else
51-
n += 0
51+
n
5252
end
5353
end
5454
end
@@ -65,14 +65,22 @@ def n_matched
6565
return 0 unless acknowledged?
6666
@replies.reduce(0) do |n, reply|
6767
if upsert?(reply)
68-
n += 0
68+
reply.documents.first[N] - n_upserted
6969
else
70-
n += reply.documents.first[N]
70+
if reply.documents.first[N]
71+
n += reply.documents.first[N]
72+
else
73+
n
74+
end
7175
end
7276
end
7377
end
7478

7579
# Gets the number of documents modified.
80+
# Not that in a mixed sharded cluster a call to
81+
# update could return nModified (>= 2.6) or not (<= 2.4).
82+
# If any call does not return nModified we can't report
83+
# a valid final count so set the field to nil.
7684
#
7785
# @example Get the modified count.
7886
# result.n_modified
@@ -83,7 +91,11 @@ def n_matched
8391
def n_modified
8492
return 0 unless acknowledged?
8593
@replies.reduce(0) do |n, reply|
86-
n += reply.documents.first[MODIFIED] || 0
94+
if n && reply.documents.first[MODIFIED]
95+
n += reply.documents.first[MODIFIED]
96+
else
97+
nil
98+
end
8799
end
88100
end
89101

@@ -155,12 +167,31 @@ def n_matched
155167
end
156168
end
157169
end
158-
alias :n_modified :n_matched
170+
171+
# Gets the number of documents modified.
172+
#
173+
# @example Get the modified count.
174+
# result.n_modified
175+
#
176+
# @return [ Integer ] The number of documents modified.
177+
#
178+
# @since 2.2.3
179+
def n_modified
180+
return 0 unless acknowledged?
181+
@replies.reduce(0) do |n, reply|
182+
if upsert?(reply)
183+
n
184+
else
185+
updated_existing?(reply) ? n += reply.documents.first[N] : n
186+
end
187+
end
188+
end
159189

160190
private
161191

162192
def upsert?(reply)
163-
!updated_existing?(reply) && reply.documents.first[N] == 1
193+
reply.documents.first[BulkWrite::Result::UPSERTED] ||
194+
(!updated_existing?(reply) && reply.documents.first[N] == 1)
164195
end
165196

166197
def updated_existing?(reply)

0 commit comments

Comments
 (0)