[GODRIVER-1823] I need a updateAndReturnResult that is atomic Created: 07/Jan/21  Updated: 27/Oct/23  Resolved: 19/Jan/21

Status: Closed
Project: Go Driver
Component/s: API
Affects Version/s: 1.4.4
Fix Version/s: None

Type: Improvement Priority: Major - P3
Reporter: Andrew Hodel Assignee: Kevin Albertson
Resolution: Works as Designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Linux



 Description   

Currently I am needing to do this:

 

2148                         // start host modification atomicity

2149                         // that is required because the host outsideIp may be updated twice once before the change and once after

2150                         // yet before the read for checking if the IP changed

2151                         

2152                         updateResult, err := collection.UpdateOne(context.TODO(), filter, update)

2153                         if err != nil

{ 2154                                 _ = updateResult 2155                                 fmt.Printf("\n\nerror in wss config request when updating host: %s\n", err) 2156                         }

2157                         

2158                         //fmt.Printf("Matched %v documents and updated %v documents.\n", updateResult.MatchedCount, updateResult.ModifiedCount)

2159                         

2160                         // compare this_host.OutsideIp and the update result.outsideIp to see if a new entry was added

2161                         // if an entry was added, increment the host document's outsideIpChangesPerDay field

2162                         var updated_host Host

2163                         err = collection.FindOne(context.TODO(), filter).Decode(&updated_host)

2164                         

2165                         fmt.Printf("this_host.outsideIp: \t%+v\nupdated_host.outsideIp: \t%v\n\n", this_host.OutsideIp, updated_host.OutsideIp);

2166                         

2167                         if (updated_host.OutsideIp[0] != this_host.OutsideIp[0])

{ 2168                                  2169                                 // increment outsideIpChangesPerDay 2170                          2171                         }

2172                         

2173                         // end host modification atomicity

 

 

If line 2152 (collection.UpdateOne) returned the updated document with regards to not allowing another update before returning (ie atomic) then I would not have to start and end atomicity on the routine...

 

 

Thanks.



 Comments   
Comment by Andrew Hodel [ 20/Jan/21 ]

This is difficult to find in the documentation.

 

Here's how you actually write it:

 

<code>

                         var updated_host Host

                         after := options.After

                         opt := options.FindOneAndUpdateOptions

{                                  ReturnDocument: &after,                          }

                         updateFindErr := collection.FindOneAndUpdate(context.TODO(), filter, update, &opt).Decode(&updated_host)

                         if (updateFindErr != nil)

{                                  fmt.Printf("error with FindOneAndUpdate: %s\n", updateFindErr)                          }

</code>

 

Here are the 5 urls of documentation and examples you have to read to understand it because it is not written out in the documentation for FindOneAndUpdate()

 

https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#Collection.FindOneAndUpdate

https://pkg.go.dev/go.mongodb.org/mongo-driver@v1.4.5/mongo/options#FindOneAndUpdateOptions

https://pkg.go.dev/go.mongodb.org/mongo-driver@v1.4.5/mongo/options#ReturnDocument

https://github.com/mongodb/mongo-go-driver/blob/v1.4.5/mongo/options/mongooptions.go#L83

https://github.com/cgiacomi/go-mongo-examples/blob/master/main.go

 

Comment by Kevin Albertson [ 19/Jan/21 ]

Hello andrewhodel@gmail.com!

If I am understanding correctly, you need an atomic find and update to ensure no changes occur between the UpdateOne and FindOne operations in the example provided. The findOneAndUpdate may suffice. It uses the underlying findAndModify command, which has atomicity guarantees when operating on one document (reference). It can optionally return the document before or after the update based on the ReturnDocument option.

Since this isn't a bug or feature request we're closing the issue. For further assistance please create a post in our community forum here

Sincerely,
Kevin

Generated at Thu Feb 08 08:37:12 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.