Skip to content

Commit eb76c5e

Browse files
authored
GODRIVER-3285 Allow sort option in client bulk write. (#1923)
1 parent a3ad820 commit eb76c5e

12 files changed

+557
-20
lines changed

internal/integration/unified/client_operation_execution.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ func createClientUpdateOneModel(value bson.Raw) (*mongo.ClientBulkWrite, error)
328328
Collation *options.Collation
329329
Hint *bson.RawValue
330330
Upsert *bool
331+
Sort *bson.RawValue
331332
}
332333
err := bson.Unmarshal(value, &v)
333334
if err != nil {
@@ -340,12 +341,17 @@ func createClientUpdateOneModel(value bson.Raw) (*mongo.ClientBulkWrite, error)
340341
return nil, err
341342
}
342343
}
344+
var sort interface{}
345+
if v.Sort != nil {
346+
sort = v.Sort.Document()
347+
}
343348
model := &mongo.ClientUpdateOneModel{
344349
Filter: v.Filter,
345350
Update: v.Update,
346351
Collation: v.Collation,
347352
Hint: hint,
348353
Upsert: v.Upsert,
354+
Sort: sort,
349355
}
350356
if len(v.ArrayFilters) > 0 {
351357
model.ArrayFilters = v.ArrayFilters
@@ -405,6 +411,7 @@ func createClientReplaceOneModel(value bson.Raw) (*mongo.ClientBulkWrite, error)
405411
Collation *options.Collation
406412
Hint *bson.RawValue
407413
Upsert *bool
414+
Sort *bson.RawValue
408415
}
409416
err := bson.Unmarshal(value, &v)
410417
if err != nil {
@@ -417,6 +424,10 @@ func createClientReplaceOneModel(value bson.Raw) (*mongo.ClientBulkWrite, error)
417424
return nil, err
418425
}
419426
}
427+
var sort interface{}
428+
if v.Sort != nil {
429+
sort = v.Sort.Document()
430+
}
420431
ns := strings.SplitN(v.Namespace, ".", 2)
421432
return &mongo.ClientBulkWrite{
422433
Database: ns[0],
@@ -427,6 +438,7 @@ func createClientReplaceOneModel(value bson.Raw) (*mongo.ClientBulkWrite, error)
427438
Collation: v.Collation,
428439
Hint: hint,
429440
Upsert: v.Upsert,
441+
Sort: sort,
430442
},
431443
}, nil
432444
}

mongo/bulk_write_models.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,9 @@ func (rom *ReplaceOneModel) SetUpsert(upsert bool) *ReplaceOneModel {
183183
}
184184

185185
// SetSort specifies which document the operation replaces if the query matches multiple documents. The first document
186-
// matched by the sort order will be replaced. This option is only valid for MongoDB versions >= 8.0. The driver will
187-
// return an error if the sort parameter is a multi-key map. The default value is nil.
186+
// matched by the sort order will be replaced. This option is only valid for MongoDB versions >= 8.0. The sort parameter
187+
// is evaluated sequentially, so the driver will return an error if it is a multi-key map (which is unordeded). The
188+
// default value is nil.
188189
func (rom *ReplaceOneModel) SetSort(sort interface{}) *ReplaceOneModel {
189190
rom.Sort = sort
190191
return rom
@@ -259,8 +260,9 @@ func (uom *UpdateOneModel) SetUpsert(upsert bool) *UpdateOneModel {
259260
}
260261

261262
// SetSort specifies which document the operation updates if the query matches multiple documents. The first document
262-
// matched by the sort order will be updated. This option is only valid for MongoDB versions >= 8.0. The driver will
263-
// return an error if the sort parameter is a multi-key map. The default value is nil.
263+
// matched by the sort order will be updated. This option is only valid for MongoDB versions >= 8.0. The sort parameter
264+
// is evaluated sequentially, so the driver will return an error if it is a multi-key map (which is unordeded). The
265+
// default value is nil.
264266
func (uom *UpdateOneModel) SetSort(sort interface{}) *UpdateOneModel {
265267
uom.Sort = sort
266268
return uom

mongo/client_bulk_write.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ func (mb *modelBatches) appendBatches(fn functionSet, dst []byte, maxCount, tota
315315
arrayFilters: model.ArrayFilters,
316316
collation: model.Collation,
317317
upsert: model.Upsert,
318+
sort: model.Sort,
318319
multi: false,
319320
checkDollarKey: true,
320321
}).marshal(mb.client.bsonOpts, mb.client.registry)
@@ -342,6 +343,7 @@ func (mb *modelBatches) appendBatches(fn functionSet, dst []byte, maxCount, tota
342343
arrayFilters: nil,
343344
collation: model.Collation,
344345
upsert: model.Upsert,
346+
sort: model.Sort,
345347
multi: false,
346348
checkDollarKey: false,
347349
}).marshal(mb.client.bsonOpts, mb.client.registry)
@@ -603,6 +605,7 @@ type clientUpdateDoc struct {
603605
hint interface{}
604606
arrayFilters []interface{}
605607
collation *options.Collation
608+
sort interface{}
606609
upsert *bool
607610
multi bool
608611
checkDollarKey bool
@@ -657,6 +660,17 @@ func (d *clientUpdateDoc) marshal(bsonOpts *options.BSONOptions, registry *bson.
657660
doc = bsoncore.AppendValueElement(doc, "hint", hintVal)
658661
}
659662

663+
if d.sort != nil {
664+
if isUnorderedMap(d.sort) {
665+
return nil, ErrMapForOrderedArgument{"sort"}
666+
}
667+
sortVal, err := marshalValue(d.sort, bsonOpts, registry)
668+
if err != nil {
669+
return nil, err
670+
}
671+
doc = bsoncore.AppendValueElement(doc, "sort", sortVal)
672+
}
673+
660674
return bsoncore.AppendDocumentEnd(doc, uidx)
661675
}
662676

mongo/client_bulk_write_models.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ type ClientUpdateOneModel struct {
5252
Update interface{}
5353
ArrayFilters []interface{}
5454
Hint interface{}
55+
Sort interface{}
5556
}
5657

5758
// NewClientUpdateOneModel creates a new ClientUpdateOneModel.
@@ -105,6 +106,15 @@ func (uom *ClientUpdateOneModel) SetUpsert(upsert bool) *ClientUpdateOneModel {
105106
return uom
106107
}
107108

109+
// SetSort specifies which document the operation updates if the query matches multiple documents. The first document
110+
// matched by the sort order will be updated. This option is only valid for MongoDB versions >= 8.0. The sort parameter
111+
// is evaluated sequentially, so the driver will return an error if it is a multi-key map (which is unordeded). The
112+
// default value is nil.
113+
func (uom *ClientUpdateOneModel) SetSort(sort interface{}) *ClientUpdateOneModel {
114+
uom.Sort = sort
115+
return uom
116+
}
117+
108118
// ClientUpdateManyModel is used to update multiple documents in a client-level BulkWrite operation.
109119
//
110120
// See corresponding setter methods for documentation.
@@ -176,6 +186,7 @@ type ClientReplaceOneModel struct {
176186
Filter interface{}
177187
Replacement interface{}
178188
Hint interface{}
189+
Sort interface{}
179190
}
180191

181192
// NewClientReplaceOneModel creates a new ClientReplaceOneModel.
@@ -222,6 +233,15 @@ func (rom *ClientReplaceOneModel) SetUpsert(upsert bool) *ClientReplaceOneModel
222233
return rom
223234
}
224235

236+
// SetSort specifies which document the operation replaces if the query matches multiple documents. The first document
237+
// matched by the sort order will be replaced. This option is only valid for MongoDB versions >= 8.0. The sort parameter
238+
// is evaluated sequentially, so the driver will return an error if it is a multi-key map (which is unordeded). The
239+
// default value is nil.
240+
func (rom *ClientReplaceOneModel) SetSort(sort interface{}) *ClientReplaceOneModel {
241+
rom.Sort = sort
242+
return rom
243+
}
244+
225245
// ClientDeleteOneModel is used to delete at most one document in a client-level BulkWriteOperation.
226246
//
227247
// See corresponding setter methods for documentation.

mongo/options/findoptions.go

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -258,8 +258,8 @@ func (f *FindOptionsBuilder) SetSkip(i int64) *FindOptionsBuilder {
258258
}
259259

260260
// SetSort sets the value for the Sort field. Sort is a document specifying the order in which
261-
// documents should be returned. The driver will return an error if the sort parameter is a
262-
// multi-key map.
261+
// documents should be returned. The sort parameter is evaluated sequentially, so the driver will
262+
// return an error if it is a multi-key map (which is unordeded). The default value is nil.
263263
func (f *FindOptionsBuilder) SetSort(sort interface{}) *FindOptionsBuilder {
264264
f.Opts = append(f.Opts, func(opts *FindOptions) error {
265265
opts.Sort = sort
@@ -426,8 +426,9 @@ func (f *FindOneOptionsBuilder) SetSkip(i int64) *FindOneOptionsBuilder {
426426
}
427427

428428
// SetSort sets the value for the Sort field. Sets a document specifying the sort order to
429-
// apply to the query. The first document in the sorted order will be returned. The driver
430-
// will return an error if the sort parameter is a multi-key map.
429+
// apply to the query. The first document in the sorted order will be returned. The sort
430+
// parameter is evaluated sequentially, so the driver will return an error if it is a multi-
431+
// key map (which is unordeded). The default value is nil.
431432
func (f *FindOneOptionsBuilder) SetSort(sort interface{}) *FindOneOptionsBuilder {
432433
f.Opts = append(f.Opts, func(opts *FindOneOptions) error {
433434
opts.Sort = sort
@@ -539,8 +540,9 @@ func (f *FindOneAndReplaceOptionsBuilder) SetReturnDocument(rd ReturnDocument) *
539540

540541
// SetSort sets the value for the Sort field. Sets a document specifying which document should
541542
// be replaced if the filter used by the operation matches multiple documents in the collection.
542-
// If set, the first document in the sorted order will be replaced. The driver will return an
543-
// error if the sort parameter is a multi-key map. The default value is nil.
543+
// If set, the first document in the sorted order will be replaced. The sort parameter is evaluated
544+
// sequentially, so the driver will return an error if it is a multi-key map (which is unordeded).
545+
// The default value is nil.
544546
func (f *FindOneAndReplaceOptionsBuilder) SetSort(sort interface{}) *FindOneAndReplaceOptionsBuilder {
545547
f.Opts = append(f.Opts, func(opts *FindOneAndReplaceOptions) error {
546548
opts.Sort = sort
@@ -716,8 +718,9 @@ func (f *FindOneAndUpdateOptionsBuilder) SetReturnDocument(rd ReturnDocument) *F
716718

717719
// SetSort sets the value for the Sort field. Sets a document specifying which document should
718720
// be updated if the filter used by the operation matches multiple documents in the collection.
719-
// If set, the first document in the sorted order will be updated. The driver will return an
720-
// error if the sort parameter is a multi-key map. The default value is nil.
721+
// If set, the first document in the sorted order will be updated. The sort parameter is evaluated
722+
// sequentially, so the driver will return an error if it is a multi-key map (which is unordeded).
723+
// The default value is nil.
721724
func (f *FindOneAndUpdateOptionsBuilder) SetSort(sort interface{}) *FindOneAndUpdateOptionsBuilder {
722725
f.Opts = append(f.Opts, func(opts *FindOneAndUpdateOptions) error {
723726
opts.Sort = sort
@@ -846,8 +849,9 @@ func (f *FindOneAndDeleteOptionsBuilder) SetProjection(projection interface{}) *
846849

847850
// SetSort sets the value for the Sort field. Sets a document specifying which document should
848851
// be replaced if the filter used by the operation matches multiple documents in the collection.
849-
// If set, the first document in the sorted order will be selected for replacement. The driver
850-
// will return an error if the sort parameter is a multi-key map. The default value is nil.
852+
// If set, the first document in the sorted order will be deleted. The sort parameter is evaluated
853+
// sequentially, so the driver will return an error if it is a multi-key map (which is unordeded).
854+
// The default value is nil.
851855
func (f *FindOneAndDeleteOptionsBuilder) SetSort(sort interface{}) *FindOneAndDeleteOptionsBuilder {
852856
f.Opts = append(f.Opts, func(opts *FindOneAndDeleteOptions) error {
853857
opts.Sort = sort

mongo/options/gridfsoptions.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,8 +328,9 @@ func (f *GridFSFindOptionsBuilder) SetSkip(i int32) *GridFSFindOptionsBuilder {
328328
}
329329

330330
// SetSort sets the value for the Sort field. Sets a document specifying the order
331-
// in which documents should be returned. The driver will return an error if the
332-
// sort parameter is a multi-key map.
331+
// in which documents should be returned. The sort parameter is evaluated sequentially,
332+
// so the driver will return an error if it is a multi-key map (which is unordeded).
333+
// The default value is nil.
333334
func (f *GridFSFindOptionsBuilder) SetSort(sort interface{}) *GridFSFindOptionsBuilder {
334335
f.Opts = append(f.Opts, func(opts *GridFSFindOptions) error {
335336
opts.Sort = sort

mongo/options/replaceoptions.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ func (ro *ReplaceOptionsBuilder) SetLet(l interface{}) *ReplaceOptionsBuilder {
127127
// SetSort sets the value for the Sort field. Specifies a document specifying which document should
128128
// be replaced if the filter used by the operation matches multiple documents in the collection. If
129129
// set, the first document in the sorted order will be replaced. This option is only valid for MongoDB
130-
// versions >= 8.0. The driver will return an error if the sort parameter is a multi-key map. The
131-
// default value is nil.
130+
// versions >= 8.0. The sort parameter is evaluated sequentially, so the driver will return an error
131+
// if it is a multi-key map (which is unordeded). The default value is nil.
132132
func (ro *ReplaceOptionsBuilder) SetSort(s interface{}) *ReplaceOptionsBuilder {
133133
ro.Opts = append(ro.Opts, func(opts *ReplaceOptions) error {
134134
opts.Sort = s

mongo/options/updateoptions.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ func (uo *UpdateOneOptionsBuilder) SetLet(l interface{}) *UpdateOneOptionsBuilde
141141
// SetSort sets the value for the Sort field. Specifies a document specifying which document should
142142
// be updated if the filter used by the operation matches multiple documents in the collection. If
143143
// set, the first document in the sorted order will be updated. This option is only valid for MongoDB
144-
// versions >= 8.0. The driver will return an error if the sort parameter is a multi-key map. The
145-
// default value is nil.
144+
// versions >= 8.0. The sort parameter is evaluated sequentially, so the driver will return an error
145+
// if it is a multi-key map (which is unordeded). The default value is nil.
146146
func (uo *UpdateOneOptionsBuilder) SetSort(s interface{}) *UpdateOneOptionsBuilder {
147147
uo.Opts = append(uo.Opts, func(opts *UpdateOneOptions) error {
148148
opts.Sort = s

0 commit comments

Comments
 (0)