@@ -1067,6 +1067,77 @@ func TestCollection(t *testing.T) {
10671067 assert .Equal (mt , expectedModel , actualModel , "expected model %v in BulkWriteException, got %v" ,
10681068 expectedModel , actualModel )
10691069 })
1070+ mt .Run ("unordered writeError index" , func (mt * mtest.T ) {
1071+ cappedOpts := bson.D {{"capped" , true }, {"size" , 64 * 1024 }}
1072+ // Use a capped collection to get WriteErrors for delete operations
1073+ capped := mt .CreateCollection (mtest.Collection {
1074+ Name : "deleteOne_capped" ,
1075+ CreateOpts : cappedOpts ,
1076+ }, true )
1077+ models := []mongo.WriteModel {
1078+ mongo .NewInsertOneModel ().SetDocument (bson.D {{"_id" , "id1" }}),
1079+ mongo .NewInsertOneModel ().SetDocument (bson.D {{"_id" , "id3" }}),
1080+ }
1081+ _ , err := capped .BulkWrite (mtest .Background , models , options .BulkWrite ())
1082+ assert .Nil (t , err , "BulkWrite error: %v" , err )
1083+
1084+ // UpdateOne and ReplaceOne models are batched together, so they each appear once
1085+ models = []mongo.WriteModel {
1086+ mongo .NewDeleteOneModel ().SetFilter (bson.D {{"_id" , "id0" }}),
1087+ mongo .NewDeleteManyModel ().SetFilter (bson.D {{"_id" , "id0" }}),
1088+ mongo .NewUpdateOneModel ().SetFilter (bson.D {{"_id" , "id3" }}).SetUpdate (bson.D {{"$set" , bson.D {{"_id" , 3.14159 }}}}),
1089+ mongo .NewInsertOneModel ().SetDocument (bson.D {{"_id" , "id1" }}),
1090+ mongo .NewDeleteManyModel ().SetFilter (bson.D {{"_id" , "id0" }}),
1091+ mongo .NewUpdateManyModel ().SetFilter (bson.D {{"_id" , "id3" }}).SetUpdate (bson.D {{"$set" , bson.D {{"_id" , 3.14159 }}}}),
1092+ mongo .NewDeleteOneModel ().SetFilter (bson.D {{"_id" , "id0" }}),
1093+ mongo .NewInsertOneModel ().SetDocument (bson.D {{"_id" , "id1" }}),
1094+ mongo .NewReplaceOneModel ().SetFilter (bson.D {{"_id" , "id3" }}).SetReplacement (bson.D {{"_id" , 3.14159 }}),
1095+ mongo .NewUpdateManyModel ().SetFilter (bson.D {{"_id" , "id3" }}).SetUpdate (bson.D {{"$set" , bson.D {{"_id" , 3.14159 }}}}),
1096+ }
1097+ _ , err = capped .BulkWrite (mtest .Background , models , options .BulkWrite ().SetOrdered (false ))
1098+ bwException , ok := err .(mongo.BulkWriteException )
1099+ assert .True (mt , ok , "expected error of type %T, got %T" , mongo.BulkWriteException {}, err )
1100+
1101+ assert .Equal (mt , len (bwException .WriteErrors ), 10 , "expected 10 writeErrors, got %v" , len (bwException .WriteErrors ))
1102+ for _ , writeErr := range bwException .WriteErrors {
1103+ switch writeErr .Request .(type ) {
1104+ case * mongo.DeleteOneModel :
1105+ assert .True (mt , writeErr .Index == 0 || writeErr .Index == 6 ,
1106+ "expected index 0 or 6, got %v" , writeErr .Index )
1107+ case * mongo.DeleteManyModel :
1108+ assert .True (mt , writeErr .Index == 1 || writeErr .Index == 4 ,
1109+ "expected index 1 or 4, got %v" , writeErr .Index )
1110+ case * mongo.UpdateManyModel :
1111+ assert .True (mt , writeErr .Index == 5 || writeErr .Index == 9 ,
1112+ "expected index 5 or 9, got %v" , writeErr .Index )
1113+ case * mongo.InsertOneModel :
1114+ assert .True (mt , writeErr .Index == 3 || writeErr .Index == 7 ,
1115+ "expected index 3 or 7, got %v" , writeErr .Index )
1116+ case * mongo.UpdateOneModel :
1117+ assert .Equal (mt , writeErr .Index , 2 , "expected index 2, got %v" , writeErr .Index )
1118+ case * mongo.ReplaceOneModel :
1119+ assert .Equal (mt , writeErr .Index , 8 , "expected index 8, got %v" , writeErr .Index )
1120+ }
1121+
1122+ }
1123+ })
1124+ mt .Run ("unordered upsertID index" , func (mt * mtest.T ) {
1125+ id1 := "id1"
1126+ id3 := "id3"
1127+ models := []mongo.WriteModel {
1128+ mongo .NewDeleteOneModel ().SetFilter (bson.D {{"_id" , "id0" }}),
1129+ mongo .NewReplaceOneModel ().SetFilter (bson.D {{"_id" , id1 }}).SetReplacement (bson.D {{"_id" , id1 }}).SetUpsert (true ),
1130+ mongo .NewDeleteOneModel ().SetFilter (bson.D {{"_id" , "id2" }}),
1131+ mongo .NewReplaceOneModel ().SetFilter (bson.D {{"_id" , id3 }}).SetReplacement (bson.D {{"_id" , id3 }}).SetUpsert (true ),
1132+ mongo .NewDeleteOneModel ().SetFilter (bson.D {{"_id" , "id4" }}),
1133+ }
1134+ res , err := mt .Coll .BulkWrite (mtest .Background , models , options .BulkWrite ().SetOrdered (false ))
1135+ assert .Nil (mt , err , "bulkwrite error: %v" , err )
1136+
1137+ assert .Equal (mt , len (res .UpsertedIDs ), 2 , "expected 2 UpsertedIDs, got %v" , len (res .UpsertedIDs ))
1138+ assert .Equal (mt , res .UpsertedIDs [1 ].(string ), id1 , "expected UpsertedIDs[1] to be %v, got %v" , id1 , res .UpsertedIDs [1 ])
1139+ assert .Equal (mt , res .UpsertedIDs [3 ].(string ), id3 , "expected UpsertedIDs[3] to be %v, got %v" , id3 , res .UpsertedIDs [3 ])
1140+ })
10701141 unackClientOpts := options .Client ().
10711142 SetWriteConcern (writeconcern .New (writeconcern .W (0 )))
10721143 unackMtOpts := mtest .NewOptions ().
0 commit comments