Reputation: 21108
I've run into what I can only understand to be a bug in the C# driver.
This gist illustrates the problem.
If I run
collection.UpdateOneAsync(
"{ \"_id\" : ObjectId(\"5656277cd4d37b13b4e7e009\"), \"Addresses.Index\" : 4 },
"{ \"$set\" : { \"Addresses.$\" : { \"_t\" : [\"Address\", \"EmailAddress\"], \"Index\" : 4, \"MailTo\" : \"[email protected]\" } } }")
I get the desired result.
If however I use the Builders to build the filter definition and update definition like so:
var filter = Builders<Person>
.Filter
.And(Builders<Person>.Filter.Eq(p => p.Id, person.Id),
Builders<Person>.Filter.Eq("Addresses.Index", 4));
var update = Builders<Person>.Update.Set("Addresses.$", new EmailAddress { Index = 4, MailTo = "[email protected]" });
then I must change my call to update to be
await collection.OfType<Person>().UpdateOneAsync(filter, update);
and the call to OfType results in the wrong address being replaced.
Upvotes: 0
Views: 669
Reputation: 116606
This is unrelated to the MongoDB C# driver, but it seems to be a bug in MongoDB itself when the type is used in the query.
You can see that this causes the same issue without using OfType
, but specifying the type field explicitly (i.e. "_t"
):
var filter = Builders<Person>.Filter.And(
new BsonDocument("_t", "Person"),
Builders<Person>.Filter.Eq(p => p.Id, person.Id),
Builders<Person>.Filter.Eq("Addresses.Index", 4));
var update = Builders<Person>.Update.Set(
"Addresses.$",
new EmailAddress { Index = 4, MailTo = "[email protected]" });
await db.GetCollection<Person>("Objects").UpdateOneAsync(filter, update);
You can see the query this will generate with this piece of code:
Console.WriteLine(db.GetCollection<Person>("Objects").Find(filter));
And the query is the following which is perfectly correct:
{ "_t" : "Person", "_id" : ObjectId("5656356f64c22e5d38aeb92e"), "Addresses.4 }
Upvotes: 1