仅替换文档如果满足条件 - 文档的原子修订

时间:2016-07-01 21:00:02

标签: c# mongodb

我正在为mongoDB和最新的mongoDB服务器使用最新的C#驱动程序。

我有一个名为User的类,每个用户都有ID号和一个指示其当前版本的修订指示符。在我的应用程序中,我正在从队列中接收用户流,我想执行以下操作:

  1. 如果用户不存在ID - 插入它。
  2. 如果用户存在于其ID中 - 仅当用户修订版比DB中保存的用户修订版更大时才替换它。
  3. A)我还需要所有这些原子 - 这样它就可以在许多线程将用户升级到Mongo DB的环境中工作。

    B)我确信这会减慢对DB的写入速度,但我希望它不会完全破坏DB写入性能。

    C)最后一项要求 - 它也适用于我的数据库是mongo节点集群而不仅仅是单个数据库实例的情况。

    我正在考虑使用upsert == true的FindOneAndReplace,但问题是如果过滤器在修订条件下失败,我不希望它执行upsert。

    替代方案是在写之前读取(警告 - 下面丑陋的东西):

    var savedUser = usersCollection.Find(p => p.UserId == userToSave.UserId).FirstOrDefault();
    if (savedUser == null)
    {                
           try
           {                    
               usersCollection.InsertOne(userToSave);
           }
           catch (MongoWriteException ex)
           {
              if (ex.WriteError.Category == ServerErrorCategory.DuplicateKey)
              {
                //Conditional Replace
                usersCollection.FindOneAndReplace<User>(p => p.UserId == userToSave.UserId 
               && p.Revision< userToSave.Revision, userToSave, 
               new FindOneAndReplaceOptions<User, User>() { IsUpsert = false });
              }
              else
              {
                 throw;
              }
           }
     }
     else
     {
        //Conditional Replace
        if (savedUser.Revision < userToSave.Revision)
            usersCollection.FindOneAndReplace<User>(p => 
              p.UserId == userToSave.UserId && p.Revision < userToSave.Revision, 
              userToSave, 
              new FindOneAndReplaceOptions<User, User>() { IsUpsert = false });
     }
    

    注意:我想通过计数检查用户是否存在会更有效,而不是将整个用户都读到应用程序。

    任何想法?

0 个答案:

没有答案