MongoDB——更新操作(Update)c#实现

时间:2023-03-08 18:01:28

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:查看原文档

MongoDB——更新操作(Update)c#实现

Step2:执行更新操作

MongoDB——更新操作(Update)c#实现

Step3:查看更新之后的结果

MongoDB——更新操作(Update)c#实现

参考如下:

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}})