C# MongoDb - 如何更新嵌套文档中的一个字段?
C# MongoDb - How to update one field in nested documents?
我想要实现的是向 Finish()
方法提供包含作业的客户端 ID 和 InternalIds 的 List<JobList>
。
然后我想遍历客户端并更新所有匹配 JobInternalIds 的作业并将当前日期时间设置为 FinishedAt 字段。
问题是我完全不知道如何更新嵌套对象。
我试过类似下面的方法但没有成功。
public class Client
{
[BsonId]
public ObjectId Id { get; set;}
public string Name { get; set;}
public List<Job> Jobs { get; set;}
}
public class Job
{
public string InternalId { get; set;}
public string Name { get; set;}
public DateTime? FinishedAt { get; set;}
}
public class JobList
{
public string ClientId { get; set; }
List<string> JobInternalIds { get; set; }
}
public async Task Finish(List<JobList> joblist)
{
var updateDefinition = new UpdateDefinitionBuilder<Client>()
.Set(x => x.Job[0].FinishedAt, DateTime.UtcNow); // don't know how to set datetime to finishedAt for each elements of collection that matches InternalIds
foreach(var item in joblist)
{
await _db.Collection.UpdateManyAsync(item.ClientId, updateDefinition);
}
}
----------EDITED----------
public async Task Finish(List<JobList> joblist)
{
var updateDefinition = Builders<Client>.Update
.Set(x => x.Jobs[-1].FinishedAt, DateTime.UtcNow);
foreach (var item in joblist)
{
var internalIds = item.JobInternalIds.Select(x => x.InternalId).ToList();
var idFilter = Builders<Client>.Filter.Eq(x => x.Id, item.ClientId);
var internalIdsFilter = Builders<Client>.Filter.ElemMatch(x => x.Jobs, y => internalIds.Contains(y.InternalId));
var combinedFilters = Builders<Client>.Filter.And(idFilter, internalIdsFilter);
await _db.Collection.UpdateManyAsync(combinedFilters, updateDefinition);
}
}
您可以使用过滤后的位置运算符来更新数组中与条件匹配的所有元素:
var internalIds = new[] { "1", "2" };
var idFilter = Builders<Client>.Filter.Eq(x => x.Id, objectId);
var updateDefinition = Builders<Client>.Update
.Set("Jobs.$[job].FinishedAt", DateTime.UtcNow);
await collection.UpdateManyAsync(idFilter, updateDefinition,
new UpdateOptions
{
ArrayFilters = new []
{
new BsonDocumentArrayFilterDefinition<BsonDocument>(new BsonDocument("job.groupName", new BsonDocument("$in", new BsonArray(internalIds)))),
}
});
查看此博客 post 以获取一些示例 - https://kevsoft.net/2020/03/23/updating-arrays-in-mongodb-with-csharp.html
我想要实现的是向 Finish()
方法提供包含作业的客户端 ID 和 InternalIds 的 List<JobList>
。
然后我想遍历客户端并更新所有匹配 JobInternalIds 的作业并将当前日期时间设置为 FinishedAt 字段。
问题是我完全不知道如何更新嵌套对象。
我试过类似下面的方法但没有成功。
public class Client
{
[BsonId]
public ObjectId Id { get; set;}
public string Name { get; set;}
public List<Job> Jobs { get; set;}
}
public class Job
{
public string InternalId { get; set;}
public string Name { get; set;}
public DateTime? FinishedAt { get; set;}
}
public class JobList
{
public string ClientId { get; set; }
List<string> JobInternalIds { get; set; }
}
public async Task Finish(List<JobList> joblist)
{
var updateDefinition = new UpdateDefinitionBuilder<Client>()
.Set(x => x.Job[0].FinishedAt, DateTime.UtcNow); // don't know how to set datetime to finishedAt for each elements of collection that matches InternalIds
foreach(var item in joblist)
{
await _db.Collection.UpdateManyAsync(item.ClientId, updateDefinition);
}
}
----------EDITED----------
public async Task Finish(List<JobList> joblist)
{
var updateDefinition = Builders<Client>.Update
.Set(x => x.Jobs[-1].FinishedAt, DateTime.UtcNow);
foreach (var item in joblist)
{
var internalIds = item.JobInternalIds.Select(x => x.InternalId).ToList();
var idFilter = Builders<Client>.Filter.Eq(x => x.Id, item.ClientId);
var internalIdsFilter = Builders<Client>.Filter.ElemMatch(x => x.Jobs, y => internalIds.Contains(y.InternalId));
var combinedFilters = Builders<Client>.Filter.And(idFilter, internalIdsFilter);
await _db.Collection.UpdateManyAsync(combinedFilters, updateDefinition);
}
}
您可以使用过滤后的位置运算符来更新数组中与条件匹配的所有元素:
var internalIds = new[] { "1", "2" };
var idFilter = Builders<Client>.Filter.Eq(x => x.Id, objectId);
var updateDefinition = Builders<Client>.Update
.Set("Jobs.$[job].FinishedAt", DateTime.UtcNow);
await collection.UpdateManyAsync(idFilter, updateDefinition,
new UpdateOptions
{
ArrayFilters = new []
{
new BsonDocumentArrayFilterDefinition<BsonDocument>(new BsonDocument("job.groupName", new BsonDocument("$in", new BsonArray(internalIds)))),
}
});
查看此博客 post 以获取一些示例 - https://kevsoft.net/2020/03/23/updating-arrays-in-mongodb-with-csharp.html