陋室铭
永远也不要停下学习的脚步(大道至简至易)

posts - 2169,comments - 570,views - 413万

c#实现 Mongodb存储【文档局部更新】

如下:

递归更新字段  ,构建UpdateDefinition

 

  1.  
    /// <summary>
  2.  
    /// 构建更新操作定义
  3.  
    /// </summary>
  4.  
    /// <param name="bc">bsondocument文档</param>
  5.  
    /// <returns></returns>
  6.  
    private List<UpdateDefinition<BsonDocument>> BuildUpdateDefinition(BsonDocument bc, string parent )
  7.  
    {
  8.  
    var updates = new List<UpdateDefinition<BsonDocument>>();
  9.  
    foreach (var element in bc.Elements)
  10.  
    {
  11.  
    var key = parent == null ? element.Name : $"{parent}.{element.Name}";
  12.  
    var subUpdates = new List<UpdateDefinition<BsonDocument>>();
  13.  
    //子元素是对象
  14.  
    if (element.Value.IsBsonDocument)
  15.  
    {
  16.  
    updates.AddRange(BuildUpdateDefinition(element.Value.ToBsonDocument(), key));
  17.  
    }
  18.  
    //子元素是对象数组
  19.  
    else if (element.Value.IsBsonArray)
  20.  
    {
  21.  
    var arrayDocs = element.Value.AsBsonArray;
  22.  
    var i = 0;
  23.  
    foreach (var doc in arrayDocs)
  24.  
    {
  25.  
    if (doc.IsBsonDocument)
  26.  
    {
  27.  
    updates.AddRange(BuildUpdateDefinition(doc.ToBsonDocument(), key + $".{i}"));
  28.  
    }
  29.  
    else
  30.  
    {
  31.  
    updates.Add(Builders<BsonDocument>.Update.Set(f => f[key], element.Value));
  32.  
    continue;
  33.  
    }
  34.  
    i++;
  35.  
    }
  36.  
    }
  37.  
    //子元素是其他
  38.  
    else
  39.  
    {
  40.  
    updates.Add(Builders<BsonDocument>.Update.Set(f => f[key], element.Value));
  41.  
    }
  42.  
    }
  43.  
    return updates;
  44.  
    }

注意其中key的构建,针对文档包含的子文档,需要对其key添加到根节点的路径。针对包含文档数组的,需要添加下标,指定到对应的标签进行数据的更新。

 

调用更新操作,更新多份文档操作如下:

 

  1.  
    /// <summary>更新</summary>
  2.  
    public async Task<IEnumerable<string>> UpdateAsync(MetadataCollection metadatas)
  3.  
    {
  4.  
    List<string> result = null;
  5.  
    var kmds = metadatas.Select(e => e.As<Metadata>()).ToList();
  6.  
    var docs = kmds.ConvertAll(DicConvertToBsonDoc);
  7.  
    var updateOptions = new UpdateOptions { IsUpsert = true };
  8.  
    try
  9.  
    {
  10.  
    foreach (var doc in docs)
  11.  
    {
  12.  
    var filter = Builders<BsonDocument>.Filter.Eq(f => f[iiid], doc[iiid]);
  13.  
    var update = Builders<BsonDocument>.Update.Combine(BuildUpdateDefinition(doc,null));
  14.  
    await _access.UpdateAsync(filter, update, updateOptions);
  15.  
    }
  16.  
    result = metadatas.Select(s => s.IIId).ToList();
  17.  
    }
  18.  
    catch (Exception ex)
  19.  
    {
  20.  
    IndexExceptionCodes.UpdatingIndexFailed.ThrowUserFriendly(ex.Message, "更新索引失败");
  21.  
    }
  22.  
    return result;
  23.  
    }

其中,先将给定的模型列表转化为Mongodb的文档对象BsonDocument,然后执行更新操作。指定操作如果key不存在执行插入操作。

 

 

示例如下:

Step1:查看原文档

Step2:执行更新操作

Step3:查看更新之后的结果

 

参考如下:

MongoDB更新包含对象数组的元素: 使用mongodb中数组元素的下标来做更新(update)多维数组 例如有如下数据结构: {   "_id":ObjectId("4b97e62bf1d8c7152c9ccb74"),   ”comments“:[     {     "by":"joe",     "votes":3,     "replies":[                 {"by":"jane",                 "votes":2                }]      }]   }   如果要将"replies"中{“by”:"jane"}的投票数增加1,该如何做呢?
mongodb使用多维数组下标的方式来定位某个元素
先find({"comments.replies.by":"jane"})来获取到整个object, 然后计算相应reply的数组下标, 再使 用update({"comments.0.replies.0.by":"jane"},{"$inc", {"comments.0.replies.0.votes":1}})

posted on   宏宇  阅读(10230)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
历史上的今天:
2012-07-31 C# 禁用本地连接和修改IE设置
2008-07-31 页面动态注册脚本(小技巧)
2008-07-31 动态画table(小技巧)
2008-07-31 Import和Assembly
2008-07-31 Post和Get的区别(兼谈页面间传值的方式)(转)
2008-07-31 ASP.NET十分有用的页面间传值方法(转)
2007-07-31 SOA and Web services 新手入门
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示