2017-01-13 27 views
0

使用MongoDB时,当我执行与任何文档不匹配的更新时,更新返回它没有更新任何文档,但文档被创建Mongo C# - 更新行为,在不匹配时创建虚拟记录

下面的代码:

public class MyObject 
    { 
     [BsonIgnoreIfDefault] 
     public string _id { get; set; } 
     public int X { get; set; } 
    } 

    static void Main(string[] args) 
    { 
     var Client  = new MongoClient("mongodb://localhost"); 
     var Database = Client.GetDatabase("testdatabase"); 
     var Driver  = Database.GetCollection<MyObject>("testcollection"); 
     Driver.Indexes.CreateOne(Builders<MyObject>.IndexKeys.Ascending(_ => _._id)); 

     var C1 = Driver.Count(_ => true); 
     // c1 == 0 since the db is empty 

     var A1 = Driver.UpdateMany(_ => false, Builders<MyObject>.Update.Set(_ => _.X, 1), new UpdateOptions {IsUpsert = true}); 
     //A1.MatchedCount == 0 
     //A1.ModifiedCount == 0; 
     //A1.Upsertdld = (some id) 

     var C2 = Driver.Count(_ => true); 
     // c2 == 1 because a dummy document was created due to the upsert flag 

     var A2 = Driver.UpdateMany(_ => true, Builders<MyObject>.Update.Set(_ => _.X, 3), new UpdateOptions {IsUpsert = true}); 
     //A2.MatchedCount == 1 
     //A2.ModifiedCount == 1; 
     //A2.Upsertdld = null; 

     var C3 = Driver.Count(_ => true); 
     // c3 == 1 since no new dummy documents were created as there was a match 

    } 

它看起来像的Upsert标志是罪魁祸首,但我不明白为什么它会创建一个文件凭空的,因为没有什么更新。 (在第二个电话,它有一个匹配,并不会创建一个虚拟的)。

+1

插入行为是在不匹配时插入文档并在匹配时更新文档。似乎就是这样发生的事情。你还期待别的什么吗? https://docs.mongodb.com/manual/reference/method/db.collection.update/ – Veeram

+0

我期望它的行为有点不同:我有字符串作为_id(它们本质上是微软格式化的GUID),它是MyObject类型。但是当update更新插入一个空文档时,它将创建一个ObjectId作为_id类型的记录;那么后面的所有调用都将失败,因为记录不能被反序列化为我创建的类型。 – Thomas

+0

会不会有一种方法来强制创建_id基本上是默认的记录(typeof(_id))?在这种情况下默认(字符串)? – Thomas

回答

0

当您使用IsUpsert = true调用MongoDB的C#驱动找到至少一个文档进行更新或插入一个新的文档。
当你的集合为空时,插入命令将会执行;像这样:

//var A1 = Driver.UpdateMany(_ => false, Builders<MyObject>.Update.Set(_ => _.X, 1), new UpdateOptions {IsUpsert = true}); 

var A1 = Driver.InsertOne(new MyObject { X = 1 }); 

因此,作为记载:

如果文件没有指定_id字段,然后MongoDB的将添加_id场和插入之前指定的文档的唯一ObjectId。大多数驱动程序创建一个ObjectId并插入_id字段,但如果驱动程序或应用程序没有,则mongod将创建并填充_id

而且在可以使用Builders<MyObject>.Filter.Empty代替_ => true推荐C#的MongoDB驱动程序的新版本。