Creado apartir del commit b888de6c92056de294456f581a56e25e734d4ab7 de develop
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
using System.Diagnostics;
|
||||
using adas_core.Application.Repositories.Interfaces;
|
||||
using adas_core.Domain.Models;
|
||||
using adas_core.Domain.Models.AppSettings;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Driver;
|
||||
using Serilog;
|
||||
|
||||
namespace adas_core.Infrastructure.Repositories;
|
||||
|
||||
public class ObservationArchiveRepository : MongoRepository<PatientObservation>, IObservationArchiveRepository
|
||||
{
|
||||
private readonly ApiSettings _apiSettings;
|
||||
|
||||
public ObservationArchiveRepository(IOptions<ApiSettings> apiSettings, IMongoDatabase database) : base(database)
|
||||
{
|
||||
if (apiSettings == null) throw new ArgumentNullException(nameof(apiSettings));
|
||||
_apiSettings = apiSettings.Value;
|
||||
} //For testing
|
||||
|
||||
|
||||
|
||||
|
||||
public async Task<List<PatientObservation>> AggregatedPatientLastObservations(ObjectId patientId, int num,
|
||||
DateTime lastDate, List<string>? filterObservations = null)
|
||||
{
|
||||
filterObservations = await AggregatePatientObservations(patientId, filterObservations);
|
||||
var results = new List<PatientObservation>();
|
||||
|
||||
foreach (var obs in filterObservations)
|
||||
{
|
||||
var filter = Builders<PatientObservation>.Filter.And(
|
||||
Builders<PatientObservation>.Filter.Eq(o => o.PatientId, patientId),
|
||||
Builders<PatientObservation>.Filter.Eq(o => o.Name, obs),
|
||||
Builders<PatientObservation>.Filter.Lte(o => o.Time, lastDate)
|
||||
);
|
||||
|
||||
var sort = Builders<PatientObservation>.Sort.Descending(o => o.Time);
|
||||
|
||||
results.AddRange(Collection.Find(filter).Sort(sort).Limit(num).ToEnumerable());
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public override string GetCollectionName()
|
||||
{
|
||||
return _apiSettings.ArchivePatientsObservations ?? "archive_patients_observations";
|
||||
}
|
||||
|
||||
public new async Task InsertOneAsync(PatientObservation patientObservation)
|
||||
{
|
||||
const int maxRetries = 2; // Número máximo de reintentos
|
||||
var retryCount = 0;
|
||||
|
||||
while (true)
|
||||
try
|
||||
{
|
||||
await Collection.InsertOneAsync(patientObservation);
|
||||
return;
|
||||
}
|
||||
catch (MongoWriteException ex) when (ex.WriteError.Category == ServerErrorCategory.DuplicateKey)
|
||||
{
|
||||
retryCount++;
|
||||
|
||||
Log.Warning(
|
||||
"Duplicate key error encountered. Retrying with new ObjectId. Attempt {attempt} of {maxRetries}",
|
||||
retryCount, maxRetries);
|
||||
|
||||
patientObservation.Id = new ObjectId();
|
||||
Log.Information("Generated ObjectId: {objectId}", patientObservation.Id);
|
||||
|
||||
if (retryCount >= maxRetries)
|
||||
{
|
||||
Log.Error("Maximum retry attempts reached. Could not insert document due to duplicate key error.");
|
||||
throw; // Re-lanzar la excepción después de alcanzar el número máximo de reintentos
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("Error inserting patient observation: {exMessage}", ex.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DeleteBeforeDate(DateTime date)
|
||||
{
|
||||
var filter = Builders<PatientObservation>.Filter.Lt(po => po.Time, date);
|
||||
await Collection.DeleteManyAsync(filter);
|
||||
}
|
||||
|
||||
public async Task<long> InsertBatch(IEnumerable<PatientObservation> observations)
|
||||
{
|
||||
var writes = new List<WriteModel<PatientObservation>>();
|
||||
writes.AddRange(observations.Select(d => new InsertOneModel<PatientObservation>(d)));
|
||||
|
||||
var bulkInsert = await Collection.BulkWriteAsync(writes);
|
||||
|
||||
return bulkInsert.InsertedCount;
|
||||
}
|
||||
|
||||
public async Task<List<PatientObservation>> FindAllFromPatient(ObjectId patientId)
|
||||
{
|
||||
var filter = Builders<PatientObservation>.Filter.Eq(p => p.PatientId, patientId);
|
||||
var result = await Collection.FindAsync(filter);
|
||||
|
||||
return await result.ToListAsync();
|
||||
}
|
||||
|
||||
private async Task<List<string>> AggregatePatientObservations(ObjectId patientId,
|
||||
List<string>? filterObservations = null)
|
||||
{
|
||||
var matchPatient = new BsonDocument
|
||||
{
|
||||
{ "patientid", patientId },
|
||||
{ "name", new BsonDocument { { "$ne", BsonNull.Value } } }
|
||||
};
|
||||
|
||||
if (filterObservations == null || !filterObservations.Any())
|
||||
{
|
||||
// GET DISTINCT OBSERVATIONS
|
||||
var distinctObs = new BsonDocument
|
||||
{
|
||||
{
|
||||
"$group", new BsonDocument
|
||||
{
|
||||
{ "_id", "1" },
|
||||
{
|
||||
"obs", new BsonDocument
|
||||
{
|
||||
{ "$addToSet", "$name" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
var distinctPipeline = new[]
|
||||
{
|
||||
new()
|
||||
{
|
||||
{
|
||||
"$match", matchPatient
|
||||
}
|
||||
},
|
||||
distinctObs
|
||||
};
|
||||
Debug.WriteLine("AggregatedArchivedPatientLastObservations distinct obs: \n" + distinctPipeline.ToJson());
|
||||
var resultList =
|
||||
await Collection.AggregateAsync<BsonDocument>(distinctPipeline,
|
||||
new AggregateOptions { AllowDiskUse = true });
|
||||
var result = resultList.ToList().FirstOrDefault();
|
||||
|
||||
if (result != null && result.Any())
|
||||
filterObservations = result.GetValue("obs").AsBsonArray.Select(it => it.AsString).ToList();
|
||||
}
|
||||
|
||||
return filterObservations ?? [];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user