mongo 2.4.1 → 2.4.2
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/README.md +3 -3
- data/lib/mongo/client.rb +16 -7
- data/lib/mongo/cluster.rb +9 -4
- data/lib/mongo/cluster/cursor_reaper.rb +1 -0
- data/lib/mongo/cluster/topology.rb +1 -1
- data/lib/mongo/collection.rb +0 -3
- data/lib/mongo/collection/view.rb +12 -5
- data/lib/mongo/collection/view/builder/find_command.rb +2 -2
- data/lib/mongo/collection/view/readable.rb +4 -4
- data/lib/mongo/collection/view/writable.rb +12 -10
- data/lib/mongo/cursor.rb +1 -0
- data/lib/mongo/error.rb +1 -0
- data/lib/mongo/error/invalid_min_pool_size.rb +35 -0
- data/lib/mongo/error/operation_failure.rb +24 -5
- data/lib/mongo/operation/write/bulk/update/result.rb +1 -10
- data/lib/mongo/operation/write/update/result.rb +26 -7
- data/lib/mongo/retryable.rb +30 -35
- data/lib/mongo/socket.rb +1 -1
- data/lib/mongo/socket/tcp.rb +1 -0
- data/lib/mongo/version.rb +1 -1
- data/spec/mongo/bulk_write_spec.rb +113 -43
- data/spec/mongo/client_spec.rb +253 -0
- data/spec/mongo/cluster/topology_spec.rb +37 -0
- data/spec/mongo/cluster_spec.rb +1 -1
- data/spec/mongo/collection/view/aggregation_spec.rb +2 -2
- data/spec/mongo/collection/view/map_reduce_spec.rb +1 -1
- data/spec/mongo/collection_spec.rb +55 -19
- data/spec/mongo/command_monitoring_spec.rb +1 -1
- data/spec/mongo/database_spec.rb +5 -5
- data/spec/mongo/grid/stream/write_spec.rb +2 -2
- data/spec/mongo/index/view_spec.rb +5 -5
- data/spec/mongo/max_staleness_spec.rb +0 -4
- data/spec/mongo/operation/write/update_spec.rb +15 -3
- data/spec/mongo/retryable_spec.rb +26 -22
- data/spec/mongo/server/connection_spec.rb +26 -0
- data/spec/mongo/shell_examples_spec.rb +981 -0
- data/spec/mongo/socket/ssl_spec.rb +51 -18
- data/spec/spec_helper.rb +26 -16
- data/spec/support/authorization.rb +38 -16
- data/spec/support/connection_string.rb +3 -3
- data/spec/support/crud.rb +38 -10
- data/spec/support/crud/write.rb +6 -3
- data/spec/support/crud_tests/write/findOneAndReplace-upsert.yml +48 -4
- data/spec/support/crud_tests/write/findOneAndReplace-upsert_pre_2.6.yml +88 -0
- data/spec/support/crud_tests/write/findOneAndReplace.yml +0 -29
- data/spec/support/crud_tests/write/findOneAndUpdate.yml +4 -1
- data/spec/support/crud_tests/write/replaceOne-collation.yml +1 -0
- data/spec/support/crud_tests/write/replaceOne-pre_2.6.yml +98 -0
- data/spec/support/crud_tests/write/replaceOne.yml +21 -5
- data/spec/support/crud_tests/write/updateMany-collation.yml +1 -0
- data/spec/support/crud_tests/write/updateMany-pre_2.6.yml +86 -0
- data/spec/support/crud_tests/write/updateMany.yml +5 -0
- data/spec/support/crud_tests/write/updateOne-collation.yml +1 -0
- data/spec/support/crud_tests/write/updateOne-pre_2.6.yml +83 -0
- data/spec/support/crud_tests/write/updateOne.yml +7 -2
- data/spec/support/gridfs.rb +1 -0
- metadata +13 -4
- metadata.gz.sig +2 -1
- data/spec/support/helpers.rb +0 -140
@@ -2,8 +2,13 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Mongo::Socket::SSL, if: running_ssl? do
|
4
4
|
|
5
|
+
let(:family) do
|
6
|
+
resolver = default_address.instance_variable_get(:@resolver)
|
7
|
+
Mongo::Address::FAMILY_MAP.key(resolver.class)
|
8
|
+
end
|
9
|
+
|
5
10
|
let(:socket) do
|
6
|
-
described_class.new(*default_address.to_s.split(":"), default_address.host, 5,
|
11
|
+
described_class.new(*default_address.to_s.split(":"), default_address.host, 5, family, options)
|
7
12
|
end
|
8
13
|
|
9
14
|
let(:options) do
|
@@ -95,7 +100,7 @@ describe Mongo::Socket::SSL, if: running_ssl? do
|
|
95
100
|
end
|
96
101
|
end
|
97
102
|
|
98
|
-
context 'when certificate and an encrypted key are provided as strings' do
|
103
|
+
context 'when certificate and an encrypted key are provided as strings', if: testing_ssl_locally? do
|
99
104
|
|
100
105
|
let(:options) do
|
101
106
|
{
|
@@ -271,21 +276,49 @@ describe Mongo::Socket::SSL, if: running_ssl? do
|
|
271
276
|
end
|
272
277
|
end
|
273
278
|
|
274
|
-
context 'when
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
279
|
+
context 'when ruby version is < 2.4.1', if: RUBY_VERSION < '2.4.1' do
|
280
|
+
|
281
|
+
context 'when a key is passed, but it is not of the right type' do
|
282
|
+
|
283
|
+
let(:options) do
|
284
|
+
key = "This is a string not a key"
|
285
|
+
{
|
286
|
+
:ssl => true,
|
287
|
+
:ssl_key_object => key,
|
288
|
+
:ssl_cert => CLIENT_CERT_PEM,
|
289
|
+
:ssl_verify => false
|
290
|
+
}
|
291
|
+
end
|
292
|
+
|
293
|
+
it 'raises a TypeError' do
|
294
|
+
expect{
|
295
|
+
socket.connect!
|
296
|
+
}.to raise_exception(TypeError)
|
297
|
+
end
|
283
298
|
end
|
299
|
+
end
|
284
300
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
301
|
+
# Note that as of MRI 2.4, Creating a socket with the wrong key type raises
|
302
|
+
# a NoMethodError because #private? is attempted to be called on the key.
|
303
|
+
context 'when ruby version is >= 2.4.1', if: RUBY_VERSION >= '2.4.1' do
|
304
|
+
|
305
|
+
context 'when a key is passed, but it is not of the right type' do
|
306
|
+
|
307
|
+
let(:options) do
|
308
|
+
key = "This is a string not a key"
|
309
|
+
{
|
310
|
+
:ssl => true,
|
311
|
+
:ssl_key_object => key,
|
312
|
+
:ssl_cert => CLIENT_CERT_PEM,
|
313
|
+
:ssl_verify => false
|
314
|
+
}
|
315
|
+
end
|
316
|
+
|
317
|
+
it 'raises a NoMethodError' do
|
318
|
+
expect{
|
319
|
+
socket.connect!
|
320
|
+
}.to raise_exception(NoMethodError)
|
321
|
+
end
|
289
322
|
end
|
290
323
|
end
|
291
324
|
|
@@ -293,14 +326,14 @@ describe Mongo::Socket::SSL, if: running_ssl? do
|
|
293
326
|
|
294
327
|
let(:options) do
|
295
328
|
super().merge(
|
296
|
-
:ssl_key =>
|
329
|
+
:ssl_key => COMMAND_MONITORING_TESTS.first
|
297
330
|
)
|
298
331
|
end
|
299
332
|
|
300
333
|
it 'raises an exception' do
|
301
334
|
expect {
|
302
335
|
socket.connect!
|
303
|
-
}.to raise_exception
|
336
|
+
}.to raise_exception
|
304
337
|
end
|
305
338
|
end
|
306
339
|
|
@@ -324,7 +357,7 @@ describe Mongo::Socket::SSL, if: running_ssl? do
|
|
324
357
|
end
|
325
358
|
end
|
326
359
|
|
327
|
-
context 'as a string
|
360
|
+
context 'as a string containing the PEM-encoded certificate' do
|
328
361
|
|
329
362
|
let (:options) do
|
330
363
|
super().merge(
|
data/spec/spec_helper.rb
CHANGED
@@ -11,20 +11,28 @@ COMMAND_MONITORING_TESTS = Dir.glob("#{CURRENT_PATH}/support/command_monitoring/
|
|
11
11
|
CONNECTION_STRING_TESTS = Dir.glob("#{CURRENT_PATH}/support/connection_string_tests/*.yml")
|
12
12
|
GRIDFS_TESTS = Dir.glob("#{CURRENT_PATH}/support/gridfs_tests/*.yml")
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
CA_PEM =
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
14
|
+
if ENV['DRIVERS_TOOLS']
|
15
|
+
CLIENT_CERT_PEM = ENV['DRIVER_TOOLS_CLIENT_CERT_PEM']
|
16
|
+
CLIENT_KEY_PEM = ENV['DRIVER_TOOLS_CLIENT_KEY_PEM']
|
17
|
+
CA_PEM = ENV['DRIVER_TOOLS_CA_PEM']
|
18
|
+
CLIENT_KEY_ENCRYPTED_PEM = ENV['DRIVER_TOOLS_CLIENT_KEY_ENCRYPTED_PEM']
|
19
|
+
else
|
20
|
+
SSL_CERTS_DIR = "#{CURRENT_PATH}/support/certificates"
|
21
|
+
CLIENT_PEM = "#{SSL_CERTS_DIR}/client.pem"
|
22
|
+
CLIENT_PASSWORD_PEM = "#{SSL_CERTS_DIR}/password_protected.pem"
|
23
|
+
CA_PEM = "#{SSL_CERTS_DIR}/ca.pem"
|
24
|
+
CRL_PEM = "#{SSL_CERTS_DIR}/crl.pem"
|
25
|
+
CLIENT_KEY_PEM = "#{SSL_CERTS_DIR}/client_key.pem"
|
26
|
+
CLIENT_CERT_PEM = "#{SSL_CERTS_DIR}/client_cert.pem"
|
27
|
+
CLIENT_KEY_ENCRYPTED_PEM = "#{SSL_CERTS_DIR}/client_key_encrypted.pem"
|
28
|
+
CLIENT_KEY_PASSPHRASE = "passphrase"
|
29
|
+
end
|
23
30
|
|
24
31
|
require 'mongo'
|
25
32
|
|
26
33
|
Mongo::Logger.logger = Logger.new($stdout)
|
27
34
|
Mongo::Logger.logger.level = Logger::INFO
|
35
|
+
Encoding.default_external = Encoding::UTF_8
|
28
36
|
|
29
37
|
require 'support/travis'
|
30
38
|
require 'support/matchers'
|
@@ -45,7 +53,6 @@ RSpec.configure do |config|
|
|
45
53
|
config.include(Authorization)
|
46
54
|
|
47
55
|
config.before(:suite) do
|
48
|
-
|
49
56
|
begin
|
50
57
|
# Create the root user administrator as the first user to be added to the
|
51
58
|
# database. This user will need to be authenticated in order to add any
|
@@ -191,13 +198,16 @@ end
|
|
191
198
|
#
|
192
199
|
# @since 2.2.0
|
193
200
|
def auth_enabled?
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
201
|
+
if auth = ENV['AUTH']
|
202
|
+
auth == 'auth'
|
203
|
+
else
|
204
|
+
$mongo_client ||= initialize_scanned_client!
|
205
|
+
begin
|
206
|
+
$mongo_client.use(:admin).command(getCmdLineOpts: 1).first["argv"].include?("--auth")
|
207
|
+
rescue => e
|
208
|
+
e.message =~ /(not authorized)|(unauthorized)/
|
209
|
+
end
|
199
210
|
end
|
200
|
-
false
|
201
211
|
end
|
202
212
|
|
203
213
|
# Initializes a basic scanned client to do an ismaster check.
|
@@ -22,28 +22,45 @@ TEST_DB = 'ruby-driver'.freeze
|
|
22
22
|
# @since 2.0.0
|
23
23
|
TEST_COLL = 'test'.freeze
|
24
24
|
|
25
|
-
#
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
# For Evergreen
|
26
|
+
if ENV['MONGODB_URI']
|
27
|
+
MONGODB_URI = Mongo::URI.new(ENV['MONGODB_URI'])
|
28
|
+
URI_OPTIONS = Mongo::Options::Mapper.transform_keys_to_symbols(MONGODB_URI.uri_options)
|
29
|
+
if URI_OPTIONS[:replica_set]
|
30
|
+
ADDRESSES = MONGODB_URI.servers
|
31
|
+
CONNECT = { connect: :replica_set, replica_set: URI_OPTIONS[:replica_set] }
|
32
|
+
elsif ENV['TOPOLOGY'] == 'sharded_cluster'
|
33
|
+
ADDRESSES = [ MONGODB_URI.servers.first ] # See SERVER-16836 for why we can only use one host:port
|
34
|
+
CONNECT = { connect: :sharded }
|
35
|
+
else
|
36
|
+
ADDRESSES = MONGODB_URI.servers
|
37
|
+
CONNECT = { connect: :direct }
|
38
|
+
end
|
39
|
+
else # For Jenkins
|
40
|
+
ADDRESSES = ENV['MONGODB_ADDRESSES'] ? ENV['MONGODB_ADDRESSES'].split(',').freeze : [ '127.0.0.1:27017' ].freeze
|
41
|
+
if ENV['RS_ENABLED']
|
42
|
+
CONNECT = { connect: :replica_set, replica_set: ENV['RS_NAME'] }
|
43
|
+
elsif ENV['SHARDED_ENABLED']
|
44
|
+
CONNECT = { connect: :sharded }
|
45
|
+
else
|
46
|
+
CONNECT = { connect: :direct }
|
47
|
+
end
|
48
|
+
end
|
30
49
|
|
31
|
-
# The
|
50
|
+
# The write concern to use in the tests.
|
32
51
|
#
|
33
52
|
# @since 2.0.0
|
34
|
-
|
35
|
-
ENV['SHARDED_ENABLED'] == 'true' ? { connect: :sharded } :
|
36
|
-
{ connect: :direct }
|
53
|
+
WRITE_CONCERN = CONNECT[:connect] == :replica_set ? { w: 2 } : { w: 1 }
|
37
54
|
|
38
|
-
#
|
55
|
+
# An invalid write concern.
|
39
56
|
#
|
40
|
-
# @since 2.
|
41
|
-
|
57
|
+
# @since 2.4.2
|
58
|
+
INVALID_WRITE_CONCERN = { w: 4 }
|
42
59
|
|
43
60
|
# Whether to use SSL.
|
44
61
|
#
|
45
62
|
# @since 2.0.3
|
46
|
-
SSL = ENV['SSL_ENABLED'] == 'true'
|
63
|
+
SSL = (ENV['SSL'] == 'ssl') || (ENV['SSL_ENABLED'] == 'true')
|
47
64
|
|
48
65
|
# SSL options.
|
49
66
|
#
|
@@ -73,12 +90,17 @@ TEST_OPTIONS = BASE_OPTIONS.merge(CONNECT).merge(SSL_OPTIONS)
|
|
73
90
|
# The root user name.
|
74
91
|
#
|
75
92
|
# @since 2.0.0
|
76
|
-
ROOT_USER_NAME =
|
93
|
+
ROOT_USER_NAME = (defined?(MONGODB_URI) && MONGODB_URI.credentials[:user]) || 'root-user'
|
77
94
|
|
78
95
|
# The root user password.
|
79
96
|
#
|
80
97
|
# @since 2.0.0
|
81
|
-
ROOT_USER_PWD =
|
98
|
+
ROOT_USER_PWD = (defined?(MONGODB_URI) && MONGODB_URI.credentials[:password]) || 'password'
|
99
|
+
|
100
|
+
# The root user auth source.
|
101
|
+
#
|
102
|
+
# @since 2.4.2
|
103
|
+
ROOT_USER_AUTH_SOURCE = (defined?(URI_OPTIONS) && URI_OPTIONS[:auth_source]) || Mongo::Database::ADMIN
|
82
104
|
|
83
105
|
# Gets the root system administrator user.
|
84
106
|
#
|
@@ -161,7 +183,7 @@ ADMIN_AUTHORIZED_TEST_CLIENT = ADMIN_UNAUTHORIZED_CLIENT.with(
|
|
161
183
|
user: ROOT_USER.name,
|
162
184
|
password: ROOT_USER.password,
|
163
185
|
database: TEST_DB,
|
164
|
-
auth_source:
|
186
|
+
auth_source: ROOT_USER_AUTH_SOURCE,
|
165
187
|
monitoring: false
|
166
188
|
)
|
167
189
|
|
@@ -14,7 +14,7 @@
|
|
14
14
|
|
15
15
|
RSpec::Matchers.define :have_hosts do |test|
|
16
16
|
|
17
|
-
match do |
|
17
|
+
match do |cl|
|
18
18
|
|
19
19
|
def find_server(client, host)
|
20
20
|
client.cluster.instance_variable_get(:@servers).detect do |s|
|
@@ -40,7 +40,7 @@ RSpec::Matchers.define :have_hosts do |test|
|
|
40
40
|
end
|
41
41
|
|
42
42
|
test.hosts.all? do |host|
|
43
|
-
server = find_server(
|
43
|
+
server = find_server(cl, host)
|
44
44
|
match_host?(server, host) &&
|
45
45
|
match_port?(server, host) if server #&&
|
46
46
|
#match_address_family?(server, host) if server
|
@@ -49,7 +49,7 @@ RSpec::Matchers.define :have_hosts do |test|
|
|
49
49
|
failure_message do |client|
|
50
50
|
"With URI: #{test.uri_string}\n" +
|
51
51
|
"Expected that test hosts: #{test.hosts} would match " +
|
52
|
-
"client hosts: #{
|
52
|
+
"client hosts: #{cl.cluster.instance_variable_get(:@servers)}"
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
data/spec/support/crud.rb
CHANGED
@@ -83,14 +83,7 @@ module Mongo
|
|
83
83
|
#
|
84
84
|
# @since 2.4.0
|
85
85
|
def server_version_satisfied?(client)
|
86
|
-
|
87
|
-
when '2.6'
|
88
|
-
client.cluster.servers.first.features.write_command_enabled?
|
89
|
-
when '3.4'
|
90
|
-
client.cluster.servers.first.features.collation_enabled?
|
91
|
-
else
|
92
|
-
true
|
93
|
-
end
|
86
|
+
lower_bound_satisfied?(client) && upper_bound_satisfied?(client)
|
94
87
|
end
|
95
88
|
|
96
89
|
# Get a list of CRUDTests for each test definition.
|
@@ -106,6 +99,32 @@ module Mongo
|
|
106
99
|
Mongo::CRUD::CRUDTest.new(@data, test)
|
107
100
|
end
|
108
101
|
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def upper_bound_satisfied?(client)
|
106
|
+
if @max_server_version
|
107
|
+
if @max_server_version < '2.6'
|
108
|
+
!client.cluster.next_primary.features.write_command_enabled?
|
109
|
+
end
|
110
|
+
else
|
111
|
+
true
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def lower_bound_satisfied?(client)
|
116
|
+
if @min_server_version
|
117
|
+
if @min_server_version >= '3.4'
|
118
|
+
client.cluster.next_primary.features.collation_enabled?
|
119
|
+
elsif @min_server_version >= '2.6'
|
120
|
+
client.cluster.next_primary.features.write_command_enabled?
|
121
|
+
else
|
122
|
+
true
|
123
|
+
end
|
124
|
+
else
|
125
|
+
true
|
126
|
+
end
|
127
|
+
end
|
109
128
|
end
|
110
129
|
|
111
130
|
# Represents a single CRUD test.
|
@@ -227,14 +246,23 @@ module Mongo
|
|
227
246
|
when nil
|
228
247
|
actual.nil?
|
229
248
|
when Hash
|
230
|
-
actual.
|
231
|
-
expected[k] == v
|
249
|
+
actual.all? do |k, v|
|
250
|
+
expected[k] == v || handle_upserted_id(k, expected[k], v)
|
232
251
|
end
|
233
252
|
when Integer
|
234
253
|
expected == actual
|
235
254
|
end
|
236
255
|
end
|
237
256
|
|
257
|
+
def handle_upserted_id(field, expected_id, actual_id)
|
258
|
+
return true if expected_id.nil?
|
259
|
+
if field == 'upsertedId'
|
260
|
+
if expected_id.is_a?(Integer)
|
261
|
+
actual_id.is_a?(BSON::ObjectId) || actual_id.nil?
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
238
266
|
def actual_collection_data
|
239
267
|
if @outcome['collection']
|
240
268
|
collection_name = @outcome['collection']['name'] || @collection.name
|
data/spec/support/crud/write.rb
CHANGED
@@ -117,9 +117,12 @@ module Mongo
|
|
117
117
|
end
|
118
118
|
|
119
119
|
def update_return_doc(result)
|
120
|
-
return_doc = {
|
121
|
-
|
122
|
-
|
120
|
+
return_doc = {}
|
121
|
+
return_doc['upsertedId'] = result.upserted_id if upsert
|
122
|
+
return_doc['upsertedCount'] = result.upserted_count
|
123
|
+
return_doc['matchedCount'] = result.matched_count
|
124
|
+
return_doc['modifiedCount'] = result.modified_count if result.modified_count
|
125
|
+
return_doc
|
123
126
|
end
|
124
127
|
|
125
128
|
def replace_one(collection)
|
@@ -3,18 +3,20 @@ data:
|
|
3
3
|
- {_id: 2, x: 22}
|
4
4
|
- {_id: 3, x: 33}
|
5
5
|
minServerVersion: '2.6'
|
6
|
-
# See SERVER-5289 for why the collection data is only checked for server versions >= 2.6
|
7
6
|
|
8
7
|
tests:
|
9
8
|
-
|
10
|
-
description: "FindOneAndReplace when no documents match with upsert returning the document before modification"
|
9
|
+
description: "FindOneAndReplace when no documents match without id specified with upsert returning the document before modification"
|
11
10
|
operation:
|
12
11
|
name: findOneAndReplace
|
13
12
|
arguments:
|
14
13
|
filter: {_id: 4}
|
15
14
|
replacement: {x: 44}
|
16
15
|
projection: {x: 1, _id: 0}
|
17
|
-
sort
|
16
|
+
# Omit the sort option as it has no effect when no documents
|
17
|
+
# match and would only cause an inconsistent return value on
|
18
|
+
# pre-3.0 servers when combined with returnDocument "before"
|
19
|
+
# (see: SERVER-17650).
|
18
20
|
upsert: true
|
19
21
|
|
20
22
|
outcome:
|
@@ -26,7 +28,7 @@ tests:
|
|
26
28
|
- {_id: 3, x: 33}
|
27
29
|
- {_id: 4, x: 44}
|
28
30
|
-
|
29
|
-
description: "FindOneAndReplace when no documents match with upsert returning the document after modification"
|
31
|
+
description: "FindOneAndReplace when no documents match without id specified with upsert returning the document after modification"
|
30
32
|
operation:
|
31
33
|
name: findOneAndReplace
|
32
34
|
arguments:
|
@@ -45,3 +47,45 @@ tests:
|
|
45
47
|
- {_id: 2, x: 22}
|
46
48
|
- {_id: 3, x: 33}
|
47
49
|
- {_id: 4, x: 44}
|
50
|
+
-
|
51
|
+
description: "FindOneAndReplace when no documents match with id specified with upsert returning the document before modification"
|
52
|
+
operation:
|
53
|
+
name: findOneAndReplace
|
54
|
+
arguments:
|
55
|
+
filter: {_id: 4}
|
56
|
+
replacement: {_id: 4, x: 44}
|
57
|
+
projection: {x: 1, _id: 0}
|
58
|
+
# Omit the sort option as it has no effect when no documents
|
59
|
+
# match and would only cause an inconsistent return value on
|
60
|
+
# pre-3.0 servers when combined with returnDocument "before"
|
61
|
+
# (see: SERVER-17650).
|
62
|
+
upsert: true
|
63
|
+
|
64
|
+
outcome:
|
65
|
+
result: null
|
66
|
+
collection:
|
67
|
+
data:
|
68
|
+
- {_id: 1, x: 11}
|
69
|
+
- {_id: 2, x: 22}
|
70
|
+
- {_id: 3, x: 33}
|
71
|
+
- {_id: 4, x: 44}
|
72
|
+
-
|
73
|
+
description: "FindOneAndReplace when no documents match with id specified with upsert returning the document after modification"
|
74
|
+
operation:
|
75
|
+
name: findOneAndReplace
|
76
|
+
arguments:
|
77
|
+
filter: {_id: 4}
|
78
|
+
replacement: {_id: 4, x: 44}
|
79
|
+
projection: {x: 1, _id: 0}
|
80
|
+
returnDocument: After
|
81
|
+
sort: {x: 1}
|
82
|
+
upsert: true
|
83
|
+
|
84
|
+
outcome:
|
85
|
+
result: {x: 44}
|
86
|
+
collection:
|
87
|
+
data:
|
88
|
+
- {_id: 1, x: 11}
|
89
|
+
- {_id: 2, x: 22}
|
90
|
+
- {_id: 3, x: 33}
|
91
|
+
- {_id: 4, x: 44}
|