问题描述
.NET Core项目。我有一个Tenant类,其中包含几个嵌套的集合(位置,员工等),存储在MongoDB中。我正在使用MongoDB C#驱动程序。租户存储在MongoDB的TenantCollection中。
任务:例如,我需要更新一个Employee,该雇员存储在Tenant.Employees列表(附加到Tenant的嵌套数组)中。
顺便说一句-下一个我的问题将是关于“如何将元素插入嵌套数组”,因此请考虑一下,因为以后我将不得不使用相同的机制进行数据插入...
问题是-哪个更好:
- 只需要从数据库中获取整个租户(包含所有嵌套的列表/数组-这里可能有很多数据),更新员工列表中的单个元素,然后使用_mongoDbCollection将其放回数据库中.ReplaceOneAsync(x => x.Id = tenant.Id,tenant)
- 使用某些MongoDB功能并更新嵌套集合中的特定元素吗?
第一点的优点-简单,缺点-可能需要大量数据-因为我必须使用该类+多个内部数组(位置,员工,部门等,但这真的很重要吗?)。 第二点的可能(!!)优点-速度...在这里,我们只更新嵌套数组的一个元素。缺点-由于我没有使用MongoDB的经验,因此无法弄清楚该怎么做...
有什么更好的-您如何看待? 如果您确实喜欢第2点,该怎么做?
非常感谢!
解决方法
使用FindOneAndUpdate将是一个更好的选择,因为您只想更新文档实体的特定部分。您可以通过提供过滤器(通常是一个ID)(即更新本身)来使用它。
,这是我创建的方法:
public async Task UpdateNestedElementAsync<TField>(Expression<Func<T,bool>> filter,Expression<Func<TField,bool>> itemFilter,Expression<Func<T,IEnumerable<TField>>> field,IEnumerable<TField> val)
{
// step 1 (could be skipped if we want just to add the element - pass itemFilter=NULL) - remove the element from the Collection,but it wasn't tested
if (itemFilter != null)
{
await _collection.FindOneAndUpdateAsync(filter,Builders<T>.Update.PullFilter(field,itemFilter));
}
// step 2 - add new or updated element to the Collection (push it there)
await _collection.FindOneAndUpdateAsync(filter,Builders<T>.Update.PushEach(field,val));
}
其中T是根类,TField是嵌套集合。