Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 9ce8f90

Browse files
RUBY-3520 Sort option for updateOne and replaceOne (#2938)
1 parent 0ca7ed8 commit 9ce8f90

File tree

8 files changed

+409
-2
lines changed

8 files changed

+409
-2
lines changed

‎lib/mongo/bulk_write/transformable.rb‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ module Transformable
9999
d['upsert'] = true if doc[:upsert]
100100
d[Operation::COLLATION] = doc[:collation] if doc[:collation]
101101
d['hint'] = doc[:hint] if doc[:hint]
102+
d['sort'] = doc[:sort] if doc[:sort]
102103
end
103104
}
104105

@@ -130,6 +131,7 @@ module Transformable
130131
d[Operation::COLLATION] = doc[:collation] if doc[:collation]
131132
d[Operation::ARRAY_FILTERS] = doc[:array_filters] if doc[:array_filters]
132133
d['hint'] = doc[:hint] if doc[:hint]
134+
d['sort'] = doc[:sort] if doc[:sort]
133135
end
134136
}
135137

‎lib/mongo/collection.rb‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,6 +1049,11 @@ def parallel_scan(cursor_count, options = {})
10491049
# May be specified as a Hash (e.g. { _id: 1 }) or a String (e.g. "_id_").
10501050
# @option options [ Hash ] :let Mapping of variables to use in the command.
10511051
# See the server documentation for details.
1052+
# @option options [ Hash ] :sort Specifies which document the operation
1053+
# replaces if the query matches multiple documents. The first document
1054+
# matched by the sort order will be replaced.
1055+
# This option is only supported by servers >= 8.0. Older servers will
1056+
# report an error for using this option.
10521057
#
10531058
# @return [ Result ] The response from the database.
10541059
#
@@ -1115,6 +1120,11 @@ def update_many(filter, update, options = {})
11151120
# May be specified as a Hash (e.g. { _id: 1 }) or a String (e.g. "_id_").
11161121
# @option options [ Hash ] :let Mapping of variables to use in the command.
11171122
# See the server documentation for details.
1123+
# @option options [ Hash ] :sort Specifies which document the operation
1124+
# updates if the query matches multiple documents. The first document
1125+
# matched by the sort order will be updated.
1126+
# This option is only supported by servers >= 8.0. Older servers will
1127+
# report an error for using this option.
11181128
#
11191129
# @return [ Result ] The response from the database.
11201130
#

‎lib/mongo/collection/view/writable.rb‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,11 @@ def delete_one(opts = {})
389389
# @option opts [ true, false ] :upsert Whether to upsert if the
390390
# document doesn't exist.
391391
# Can be :w => Integer, :fsync => Boolean, :j => Boolean.
392+
# @option opts [ Hash ] :sort Specifies which document the operation
393+
# replaces if the query matches multiple documents. The first document
394+
# matched by the sort order will be replaced.
395+
# This option is only supported by servers >= 8.0. Older servers will
396+
# report an error for using this option.
392397
#
393398
# @return [ Result ] The response from the database.
394399
#
@@ -410,6 +415,7 @@ def replace_one(replacement, opts = {})
410415
Operation::U => replacement,
411416
hint: opts[:hint],
412417
collation: opts[:collation] || opts['collation'] || collation,
418+
sort: opts[:sort] || opts['sort'],
413419
}.compact
414420
if opts[:upsert]
415421
update_doc['upsert'] = true
@@ -549,6 +555,11 @@ def update_many(spec, opts = {})
549555
# document doesn't exist.
550556
# @option opts [ Hash ] :write_concern The write concern options.
551557
# Can be :w => Integer, :fsync => Boolean, :j => Boolean.
558+
# @option opts [ Hash ] :sort Specifies which document the operation
559+
# updates if the query matches multiple documents. The first document
560+
# matched by the sort order will be updated.
561+
# This option is only supported by servers >= 8.0. Older servers will
562+
# report an error for using this option.
552563
#
553564
# @return [ Result ] The response from the database.
554565
#
@@ -570,6 +581,7 @@ def update_one(spec, opts = {})
570581
Operation::U => spec,
571582
hint: opts[:hint],
572583
collation: opts[:collation] || opts['collation'] || collation,
584+
sort: opts[:sort] || opts['sort'],
573585
}.compact
574586
if opts[:upsert]
575587
update_doc['upsert'] = true

‎spec/runners/unified/crud_operations.rb‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,8 @@ def update_one(op)
194194
hint: args.use('hint'),
195195
upsert: args.use('upsert'),
196196
timeout_ms: args.use('timeoutMS'),
197-
max_time_ms: args.use('maxTimeMS')
197+
max_time_ms: args.use('maxTimeMS'),
198+
sort: args.use('sort')
198199
}
199200
if session = args.use('session')
200201
opts[:session] = entities.get(:session, session)
@@ -228,7 +229,8 @@ def replace_one(op)
228229
let: args.use('let'),
229230
hint: args.use('hint'),
230231
timeout_ms: args.use('timeoutMS'),
231-
max_time_ms: args.use('maxTimeMS')
232+
max_time_ms: args.use('maxTimeMS'),
233+
sort: args.use('sort'),
232234
)
233235
end
234236
end
@@ -358,6 +360,9 @@ def convert_bulk_write_spec(spec)
358360
else
359361
raise NotImplementedError, "Unknown operation #{op}"
360362
end
363+
if %w[ updateOne replaceOne ].include?(op)
364+
out[:sort] = spec.use('sort') if spec.key?('sort')
365+
end
361366
unless spec.empty?
362367
raise NotImplementedError, "Unhandled keys: #{spec}"
363368
end
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
description: BulkWrite replaceOne-sort
2+
3+
schemaVersion: "1.0"
4+
5+
createEntities:
6+
- client:
7+
id: &client0 client0
8+
observeEvents: [ commandStartedEvent, commandSucceededEvent ]
9+
- database:
10+
id: &database0 database0
11+
client: *client0
12+
databaseName: &database0Name crud-tests
13+
- collection:
14+
id: &collection0 collection0
15+
database: *database0
16+
collectionName: &collection0Name coll0
17+
18+
initialData:
19+
- collectionName: *collection0Name
20+
databaseName: *database0Name
21+
documents:
22+
- { _id: 1, x: 11 }
23+
- { _id: 2, x: 22 }
24+
- { _id: 3, x: 33 }
25+
26+
tests:
27+
- description: BulkWrite replaceOne with sort option
28+
runOnRequirements:
29+
- minServerVersion: "8.0"
30+
operations:
31+
- object: *collection0
32+
name: bulkWrite
33+
arguments:
34+
requests:
35+
- replaceOne:
36+
filter: { _id: { $gt: 1 } }
37+
sort: { _id: -1 }
38+
replacement: { x: 1 }
39+
expectEvents:
40+
- client: *client0
41+
events:
42+
- commandStartedEvent:
43+
command:
44+
update: *collection0Name
45+
updates:
46+
- q: { _id: { $gt: 1 } }
47+
u: { x: 1 }
48+
sort: { _id: -1 }
49+
multi: { $$unsetOrMatches: false }
50+
upsert: { $$unsetOrMatches: false }
51+
- commandSucceededEvent:
52+
reply: { ok: 1, n: 1 }
53+
commandName: update
54+
outcome:
55+
- collectionName: *collection0Name
56+
databaseName: *database0Name
57+
documents:
58+
- { _id: 1, x: 11 }
59+
- { _id: 2, x: 22 }
60+
- { _id: 3, x: 1 }
61+
62+
- description: BulkWrite replaceOne with sort option unsupported (server-side error)
63+
runOnRequirements:
64+
- maxServerVersion: "7.99"
65+
operations:
66+
- object: *collection0
67+
name: bulkWrite
68+
arguments:
69+
requests:
70+
- replaceOne:
71+
filter: { _id: { $gt: 1 } }
72+
sort: { _id: -1 }
73+
replacement: { x: 1 }
74+
expectError:
75+
isClientError: false
76+
expectEvents:
77+
- client: *client0
78+
events:
79+
- commandStartedEvent:
80+
command:
81+
update: *collection0Name
82+
updates:
83+
- q: { _id: { $gt: 1 } }
84+
u: { x: 1 }
85+
sort: { _id: -1 }
86+
multi: { $$unsetOrMatches: false }
87+
upsert: { $$unsetOrMatches: false }
88+
outcome:
89+
- collectionName: *collection0Name
90+
databaseName: *database0Name
91+
documents:
92+
- { _id: 1, x: 11 }
93+
- { _id: 2, x: 22 }
94+
- { _id: 3, x: 33 }
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
description: BulkWrite updateOne-sort
2+
3+
schemaVersion: "1.0"
4+
5+
createEntities:
6+
- client:
7+
id: &client0 client0
8+
observeEvents: [ commandStartedEvent, commandSucceededEvent ]
9+
- database:
10+
id: &database0 database0
11+
client: *client0
12+
databaseName: &database0Name crud-tests
13+
- collection:
14+
id: &collection0 collection0
15+
database: *database0
16+
collectionName: &collection0Name coll0
17+
18+
initialData:
19+
- collectionName: *collection0Name
20+
databaseName: *database0Name
21+
documents:
22+
- { _id: 1, x: 11 }
23+
- { _id: 2, x: 22 }
24+
- { _id: 3, x: 33 }
25+
26+
tests:
27+
- description: BulkWrite updateOne with sort option
28+
runOnRequirements:
29+
- minServerVersion: "8.0"
30+
operations:
31+
- object: *collection0
32+
name: bulkWrite
33+
arguments:
34+
requests:
35+
- updateOne:
36+
filter: { _id: { $gt: 1 } }
37+
sort: { _id: -1 }
38+
update: [ $set: { x: 1 } ]
39+
expectEvents:
40+
- client: *client0
41+
events:
42+
- commandStartedEvent:
43+
command:
44+
update: *collection0Name
45+
updates:
46+
- q: { _id: { $gt: 1 } }
47+
u: [ $set: { x: 1 } ]
48+
sort: { _id: -1 }
49+
multi: { $$unsetOrMatches: false }
50+
upsert: { $$unsetOrMatches: false }
51+
- commandSucceededEvent:
52+
reply: { ok: 1, n: 1 }
53+
commandName: update
54+
outcome:
55+
- collectionName: *collection0Name
56+
databaseName: *database0Name
57+
documents:
58+
- { _id: 1, x: 11 }
59+
- { _id: 2, x: 22 }
60+
- { _id: 3, x: 1 }
61+
62+
- description: BulkWrite updateOne with sort option unsupported (server-side error)
63+
runOnRequirements:
64+
- maxServerVersion: "7.99"
65+
operations:
66+
- object: *collection0
67+
name: bulkWrite
68+
arguments:
69+
requests:
70+
- updateOne:
71+
filter: { _id: { $gt: 1 } }
72+
sort: { _id: -1 }
73+
update: [ $set: { x: 1 } ]
74+
expectError:
75+
isClientError: false
76+
expectEvents:
77+
- client: *client0
78+
events:
79+
- commandStartedEvent:
80+
command:
81+
update: *collection0Name
82+
updates:
83+
- q: { _id: { $gt: 1 } }
84+
u: [ $set: { x: 1 } ]
85+
sort: { _id: -1 }
86+
multi: { $$unsetOrMatches: false }
87+
upsert: { $$unsetOrMatches: false }
88+
outcome:
89+
- collectionName: *collection0Name
90+
databaseName: *database0Name
91+
documents:
92+
- { _id: 1, x: 11 }
93+
- { _id: 2, x: 22 }
94+
- { _id: 3, x: 33 }
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
description: replaceOne-sort
2+
3+
schemaVersion: "1.0"
4+
5+
createEntities:
6+
- client:
7+
id: &client0 client0
8+
observeEvents: [ commandStartedEvent, commandSucceededEvent ]
9+
- database:
10+
id: &database0 database0
11+
client: *client0
12+
databaseName: &database0Name crud-tests
13+
- collection:
14+
id: &collection0 collection0
15+
database: *database0
16+
collectionName: &collection0Name coll0
17+
18+
initialData:
19+
- collectionName: *collection0Name
20+
databaseName: *database0Name
21+
documents:
22+
- { _id: 1, x: 11 }
23+
- { _id: 2, x: 22 }
24+
- { _id: 3, x: 33 }
25+
26+
tests:
27+
- description: ReplaceOne with sort option
28+
runOnRequirements:
29+
- minServerVersion: "8.0"
30+
operations:
31+
- name: replaceOne
32+
object: *collection0
33+
arguments:
34+
filter: { _id: { $gt: 1 } }
35+
sort: { _id: -1 }
36+
replacement: { x: 1 }
37+
expectResult:
38+
matchedCount: 1
39+
modifiedCount: 1
40+
upsertedCount: 0
41+
expectEvents:
42+
- client: *client0
43+
events:
44+
- commandStartedEvent:
45+
command:
46+
update: *collection0Name
47+
updates:
48+
- q: { _id: { $gt: 1 } }
49+
u: { x: 1 }
50+
sort: { _id: -1 }
51+
multi: { $$unsetOrMatches: false }
52+
upsert: { $$unsetOrMatches: false }
53+
- commandSucceededEvent:
54+
reply: { ok: 1, n: 1 }
55+
commandName: update
56+
outcome:
57+
- collectionName: *collection0Name
58+
databaseName: *database0Name
59+
documents:
60+
- { _id: 1, x: 11 }
61+
- { _id: 2, x: 22 }
62+
- { _id: 3, x: 1 }
63+
64+
- description: replaceOne with sort option unsupported (server-side error)
65+
runOnRequirements:
66+
- maxServerVersion: "7.99"
67+
operations:
68+
- name: replaceOne
69+
object: *collection0
70+
arguments:
71+
filter: { _id: { $gt: 1 } }
72+
sort: { _id: -1 }
73+
replacement: { x: 1 }
74+
expectError:
75+
isClientError: false
76+
expectEvents:
77+
- client: *client0
78+
events:
79+
- commandStartedEvent:
80+
command:
81+
update: *collection0Name
82+
updates:
83+
- q: { _id: { $gt: 1 } }
84+
u: { x: 1 }
85+
sort: { _id: -1 }
86+
multi: { $$unsetOrMatches: false }
87+
upsert: { $$unsetOrMatches: false }
88+
outcome:
89+
- collectionName: *collection0Name
90+
databaseName: *database0Name
91+
documents:
92+
- { _id: 1, x: 11 }
93+
- { _id: 2, x: 22 }
94+
- { _id: 3, x: 33 }

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /