With the following document structure
public class Disclaimer
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public ObjectId Id { get; set; }
public List<Override> Overrides { get; set; }
}
public class Override
{
public int CategoryId { get; set; }
public DateTime EffectiveDate { get; set; }
public DateTime? ExpiryDate { get; set; }
public string Message { get; set; }
}
And the query
var idFilter = Builders<Models.Database.Disclaimer>.Filter.Where(x => x.Id == ObjectId.Parse(id) && x.Overrides.Any(y => y.CategoryId == createOverrideDto.CategoryId)));
var overrideCancellations = Builders<Models.Database.Disclaimer>.Update.Set(x => x.Overrides[-1].ExpiryDate, DateTime.Now);
var update = overrideCancellations.Push(x => x.Overrides, new Models.Database.Override()
{
CategoryId = createOverrideDto.CategoryId,
EffectiveDate = DateTime.Now,
Message = createOverrideDto.Message
});
result = _repository.Get().UpdateOne(filter, update);
I would like to update existing Override elements with an expiry date when a new one is added in the same category, and add the new element. If there are existing elements not in the same category, these should be left alone, just the new element should be appended.
My current code works fine if there is one or more existing Override elements with the chosen category. However, when there are not, i.e if the array is empty or all existing are not in the category, the filter clause does not match, and no update runs.
I have tried to amend my filter to match when there are no overrides in this category. However, then any existing elements not in the selected category are also updated i.e. have an expiry date added.
I could change my document structure so that Overrides is an object with category id field and then separate arrays, but I may still have the upsert problem?