Skip to content

Commit

Permalink
优化
Browse files Browse the repository at this point in the history
  • Loading branch information
lin committed Nov 10, 2022
1 parent c422d6f commit bb9d236
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 25 deletions.
58 changes: 34 additions & 24 deletions MongoIncUpdate.Base/IncUpdate.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;

namespace MongoIncUpdate.Base;

public static class IncUpdateExt
{
static readonly ReplaceOptions ReplaceOptions = new() { IsUpsert = true };
static readonly UpdateOptions UpdateOptions = new() { IsUpsert = true };

public static object? GetBsonId<T>(this T self) where T : class
{
var find = typeof(BsonIdAttribute);
Expand All @@ -16,36 +20,42 @@ public static class IncUpdateExt
return null;
}

public static async Task<UpdateResult> IncUpdate<T>(this IMongoCollection<T> collection, T item) where T : class
public static async Task<UpdateResult> IncUpdate<T>(this IMongoCollection<T> collection, T item,
bool forceReplace = false) where T : class
{
//获取bsonId。这种方式性能较低,但比较通用。
var id = item.GetBsonId();
if (id == null) throw new Exception("BsonId not exist");

var diffUpdateable = item as IDiffUpdateable;
var defs = new List<UpdateDefinition<T>>();
diffUpdateable?.BuildUpdate(defs, "");
//无数据更新直接跳过
if (defs.Count == 0) return new UpdateResult.Acknowledged(0, 0, 0);
//更新
var setter = Builders<T>.Update.Combine(defs);
var filter = Builders<T>.Filter.Eq("_id", id);
Console.WriteLine($"update data count:{defs.Count}");
return await collection.UpdateOneAsync(filter, setter, new UpdateOptions { IsUpsert = true });
return await collection.IncUpdate(item, id, forceReplace);
}

public static async Task<UpdateResult> IncUpdate<T, TK>(this IMongoCollection<T> collection, T item, TK id)
where T : class
public static async Task<UpdateResult> IncUpdate<T, TK>(this IMongoCollection<T> collection, T item, TK id,
bool forceReplace = false)
where T : class where TK : notnull
{
var diffUpdateable = item as IDiffUpdateable;
var defs = new List<UpdateDefinition<T>>();
diffUpdateable?.BuildUpdate(defs, "");
//无数据更新直接跳过
if (defs.Count == 0) return new UpdateResult.Acknowledged(0, 0, 0);
//更新
var setter = Builders<T>.Update.Combine(defs);
var filter = Builders<T>.Filter.Eq("_id", id);
Console.WriteLine($"update data count:{defs.Count}");
return await collection.UpdateOneAsync(filter, setter, new UpdateOptions { IsUpsert = true });
if (forceReplace) //强制全量替换
{
var result = await collection.ReplaceOneAsync(filter, item, ReplaceOptions);
return new UpdateResult.Acknowledged(result.MatchedCount, result.ModifiedCount, result.UpsertedId);
}

try //优先增量更新
{
var diffUpdateable = item as IDiffUpdateable;
var defs = new List<UpdateDefinition<T>>();
diffUpdateable?.BuildUpdate(defs, "");
//无数据更新直接跳过
if (defs.Count == 0) return new UpdateResult.Acknowledged(1, 0, null);
//更新
var setter = Builders<T>.Update.Combine(defs);
// Console.WriteLine($"update data count:{defs.Count}");
return await collection.UpdateOneAsync(filter, setter, UpdateOptions);
}
catch (Exception) //增量更新失败则退化为全量替换(逻辑上没上用,增量异常了全量替换也大概率一场--仅仅是为了保证逻辑完整--)
{
var result = await collection.ReplaceOneAsync(filter, item, ReplaceOptions);
return new UpdateResult.Acknowledged(result.MatchedCount, result.ModifiedCount, result.ToBson());
}
}
}
2 changes: 1 addition & 1 deletion MongoIncUpdate.Fody.Test/IncUpdateTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public async Task TestSampleInt()
_output.WriteLine("全量写入");
var cc = _db.GetCollection<ItemInt>(nameof(ItemInt));
var a = new ItemInt { Id = 1, I = 2 };
_ = await cc.IncUpdate(a, 1);
_ = await cc.IncUpdate(a, 1, true);
_output.WriteLine("全量写入检查");
var filer = Builders<ItemInt>.Filter.Eq(x => x.Id, a.Id);
var result = (await cc.FindAsync(filer)).First();
Expand Down

0 comments on commit bb9d236

Please sign in to comment.