我遇到了我只能理解为C#驱动程序中的错误。
此gist说明了问题。
如果我跑
collection.UpdateOneAsync(
"{ \"_id\" : ObjectId(\"5656277cd4d37b13b4e7e009\"), \"Addresses.Index\" : 4 },
"{ \"$set\" : { \"Addresses.$\" : { \"_t\" : [\"Address\", \"EmailAddress\"], \"Index\" : 4, \"MailTo\" : \"Never@home.com\" } } }")
我得到了理想的结果。
但是,如果我使用构建器来构建过滤器定义和更新定义,如下所示:
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 = "Never@home.com" });
然后我必须将我的电话更改为
await collection.OfType<Person>().UpdateOneAsync(filter, update);
并且对OfType的调用导致错误的地址被替换。
答案 0 :(得分:1)
这与MongoDB C#驱动程序无关,但在查询中使用该类型时,它似乎是MongoDB本身的一个错误。
您可以看到这会导致相同的问题而不使用OfType
,但明确指定类型字段(即"_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 = "Never@home.com" });
await db.GetCollection<Person>("Objects").UpdateOneAsync(filter, update);
您可以看到这将使用以下代码生成的查询:
Console.WriteLine(db.GetCollection<Person>("Objects").Find(filter));
以下查询完全正确:
{ "_t" : "Person", "_id" : ObjectId("5656356f64c22e5d38aeb92e"), "Addresses.4 }