dj-nitehawk / MongoDB.Entities

A data access library for MongoDB with an elegant api, LINQ support and built-in entity relationship management
https://mongodb-entities.com
MIT License
547 stars 70 forks source link

SaveAsync fails to upsert when using sharded MongoDB #230

Open MichaelGlaive opened 1 month ago

MichaelGlaive commented 1 month ago

When running MongoDB with sharding, using SaveAsync to upsert an entity causes an exception with the following text:

MongoDB.Driver.MongoWriteException: A write operation resulted in an error. WriteError: { Category : "Uncategorized", Code : 61, Message : "Failed to target upsert by query :: could not extract exact shard key" }.

The reason for it is that the sharding field have to appear in the u section of the upsert query, but SaveAsync doesn't account for it. Only changing the code to use UpdateAsync and explicitly adding Match with the sharding field results in a working solution. Sharding enabled on MongoDB breaks SaveAsync, and there's no way to overcome it in the existing version of the nuget, other than not using that method at all. My guess would be that any update operation would fail where the fields that participate in sharding are not present.

I'm considering trying to change code to use DbContext with global filters, to see if that could help solve it, but that would be replacing 100s of DB.Something calls to use DbContext... Also it's not going to work with just myEntity.SaveAsync, because it uses the global DB static class as far as I understand.

P.S.: Thank you for your great work on this nuget, it's amazing for all the non-sharded scenarios that I've encountered so far.

UPDATE: Global filters are not going to work, according to the documentation:

only delete, update and retrieval operations will use global filters. the Save*() operations will ignore any registered global filters as they will only match on the ID field.