I am using MongoDB $addToSet
, like this:
.AddToSet(report => report.EngineReports, engineReport);
EngineReport
is class and not a string or int like in the documentation of MongoDB, and its a part of the class FileAggregationReport
:
public class FileAggregateReport
{
public Guid FileId { get; set; }
public Guid CorrelationId { get; set; }
public List<EngineReport> EngineReports { get; set; }
}
Now my problem is that I have duplicates because if I got 2 objects with the same id but some other property different it will add the 2 classes to the set.
Example:
First class:
new EngineReport()
{
EngineType = EngineType.TypeA,
Summary = "test1"
}
Second class:
new EngineReport()
{
EngineType = EngineType.TypeA,
Summary = "test2"
}
So my problem when I using addToSet its adds to EngineReports the 2 classes but I want to add only one, is it possible to do?
How can I check before addToset if this class has the same id from the set?
From $addToSet docs:
If the value is a document, MongoDB determines that the document is a duplicate if an existing document in the array matches the to-be-added document exactly; i.e. the existing document has the exact same fields and values and the fields are in the same order.
So it won't be helpful in your case.
You can take a different approach and change filter part of your update operation. For instance let's say that currently you match by FileId
field. You can add additional check to make sure that there's no EngineType.TypeA
in updated document. This will work for first EngineReport
you'll try to insert but for the second one there won't be any document updated:
var filterBuilder = Builders<FileAggregateReport>.Filter;
var regularFilter = filterBuilder.Eq(x => x.FileId, fileId);
var engineType = Builders<EngineReport>.Filter.Eq(x => x.EngineType, EngineType.TypeA);
var engineTypeFilter = filterBuilder.ElemMatch(f => f.EngineReports, engineType);
var combinedFilter = filterBuilder.And(regularFilter, filterBuilder.Not(engineTypeFilter));
var updateBuilder = Builders<FileAggregateReport>.Update;
var update1 = updateBuilder.Push(x => x.EngineReports, engineReport1);
var update2 = updateBuilder.Push(x => x.EngineReports, engineReport2);
myCollection.UpdateOne(combinedFilter, update1); // 1 document affected
myCollection.UpdateOne(combinedFilter, update2); // 0 documents affected