我正在为mongoDB和最新的mongoDB服务器使用最新的C#驱动程序。
我有一个名为User的类,每个用户都有ID号和一个指示其当前版本的修订指示符。在我的应用程序中,我正在从队列中接收用户流,我想执行以下操作:
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 });
}
注意:我想通过计数检查用户是否存在会更有效,而不是将整个用户都读到应用程序。
任何想法?