尝试并发更新(AddToSet)到mongodb中的集合并且它无法正常工作

时间:2017-12-12 09:45:49

标签: c# mongodb asp.net-core .net-core

我有FileAggregateReport类:

 public class FileAggregateReport
{        
    public Guid FileId { get; set; }

    public Guid CorrelationId { get; set; }

    public int NumberOfSupportedEngines { get; set; }

    public int EnginesCompleted { get; set; }

    public string SHA256 { get; set; }

    public DateTime ScanDate { get; set; }

    public List<EngineReport> EngineReports { get; set; }        
}

我正在尝试将列表EngineReports报告添加为更新操作。

我的插入报告功能是:(FileAggregateReportCollectionIMongoCollection<FileAggregateReport>

public void InsertNewEngineReport(Guid CorrelationId, Guid FileId, EngineReport engineReport, string sha256, int numberOfSupportedEngines)
    {           
        var update = Builders<FileAggregateReport>.Update
            .Inc(report => report.EnginesCompleted, 1)
            .Set(report =>  report.CorrelationId, CorrelationId)
            .Set(report => report.FileId, FileId)
            .SetOnInsert(report => report.ScanDate, engineReport.ScanDate)
            .SetOnInsert(report => report.SHA256, sha256)
            .AddToSet( report => report.EngineReports, engineReport)
            .Set(report => report.NumberOfSupportedEngines, numberOfSupportedEngines);            

        UpdateOptions options = new UpdateOptions { IsUpsert = true };

        try
        {                
            _mongoDbHelper.FileAggregateReportCollection.UpdateOne(e => e.FileId == FileId, update, options);                
        }
        catch (Exception e)
        {
            throw new StateRepositoryException(e.Message);
        }
    }               
}

当我正在做这样的测试时:

Guid cor = Guid.NewGuid();
Guid fileID = Guid.NewGuid();
EngineReport report = new EngineReport()
{
   FileId = fileID
};
_fileResultRepository.InsertNewEngineReport(cor, fileID, report, "dfsdfsdf", 15);

Task[] tasks = new Task[5];
for (int i = 0; i < 5; i++)
  {
      Task task = Task.Run(() => 
     _fileResultRepository.InsertNewEngineReport(cor, fileID, new EngineReport()
      {
        FileId = fileID,
        EngineType = EngineType.Clamav,
        MaliciousScore = 70,
        ScanDate = DateTime.Now,
        ShortSummary = "ATD"
      }, "dfsdfsdf", 5));
      tasks[i]=task;
  }                                                       
 Task.WaitAll(tasks);

但是在我的测试结果中,我在EnginesReport只有3个元素而且需要为6。 有时我得到E11000 duplicate key error collection: FileResultAggregationRepository.FileAggregateReport index: _id_ dup key: { : BinData(3, 2A03C999127FDF4AAF293C5C086BEC66)但我无法重现这一点。

1 个答案:

答案 0 :(得分:1)

我从mongodb docs看到AddToSet =&gt;的定义“$ addToSet运算符向数组添加一个值,除非该值已经存在,在这种情况下,$ addToSet对该数组不执行任何操作。”

我为Id添加了新的FileAggregateReport,因为FileId与所有EngineReports相同,之后我在测试中更改了我{6} EngineReports预期。