mirror of
https://github.com/NecroticBamboo/DeepTrace.git
synced 2025-12-21 11:21:51 +00:00
DEEP-38 Initial work for configurable Measures
This commit is contained in:
parent
fc98c3b50a
commit
0b26c25620
@ -8,9 +8,9 @@ namespace DeepTrace.Controllers
|
|||||||
[Route("api/[controller]")]
|
[Route("api/[controller]")]
|
||||||
public class DownloadController : Controller
|
public class DownloadController : Controller
|
||||||
{
|
{
|
||||||
private readonly IModelDefinitionService _modelService;
|
private readonly IModelStorageService _modelService;
|
||||||
|
|
||||||
public DownloadController(IModelDefinitionService modelService)
|
public DownloadController(IModelStorageService modelService)
|
||||||
{
|
{
|
||||||
_modelService = modelService;
|
_modelService = modelService;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,14 +29,14 @@ public class ModelDefinition
|
|||||||
{
|
{
|
||||||
columnNames.AddRange(measureNames.Select(x => $"{item.Query}_{x}"));
|
columnNames.AddRange(measureNames.Select(x => $"{item.Query}_{x}"));
|
||||||
}
|
}
|
||||||
|
columnNames.Add("Name");
|
||||||
return columnNames;
|
return columnNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ToCsv()
|
public string ToCsv()
|
||||||
{
|
{
|
||||||
var current = IntervalDefinitionList.First();
|
var current = IntervalDefinitionList.First();
|
||||||
var headers = string.Join(",", GetColumnNames().Select(x=>$"\"{x}\"")) + ",Name";
|
var headers = string.Join(",", GetColumnNames().Select(x=>$"\"{x}\""));
|
||||||
|
|
||||||
|
|
||||||
var writer = new StringBuilder();
|
var writer = new StringBuilder();
|
||||||
|
|||||||
13
DeepTrace/Data/TrainedModelDefinition.cs
Normal file
13
DeepTrace/Data/TrainedModelDefinition.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using MongoDB.Bson.Serialization.Attributes;
|
||||||
|
using MongoDB.Bson;
|
||||||
|
|
||||||
|
namespace DeepTrace.Data
|
||||||
|
{
|
||||||
|
public class TrainedModelDefinition
|
||||||
|
{
|
||||||
|
[BsonId]
|
||||||
|
public ObjectId? Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public byte[] Value { get; set; } //base64
|
||||||
|
}
|
||||||
|
}
|
||||||
11
DeepTrace/ML/IMeasure.cs
Normal file
11
DeepTrace/ML/IMeasure.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
using PrometheusAPI;
|
||||||
|
|
||||||
|
namespace DeepTrace.ML
|
||||||
|
{
|
||||||
|
public interface IMeasure
|
||||||
|
{
|
||||||
|
public string Name { get; }
|
||||||
|
void Reset();
|
||||||
|
float Calculate(IEnumerable<TimeSeries> data);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -34,7 +34,7 @@ public static class MLHelpers
|
|||||||
|
|
||||||
var columnNames = model.GetColumnNames();
|
var columnNames = model.GetColumnNames();
|
||||||
var columns = columnNames
|
var columns = columnNames
|
||||||
.Select((x,i) => new TextLoader.Column(x, DataKind.Double, i))
|
.Select((x,i) => new TextLoader.Column(x, DataKind.String, i))
|
||||||
.ToArray()
|
.ToArray()
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@ -13,12 +13,12 @@ namespace DeepTrace.ML
|
|||||||
private DataViewSchema? _schema;
|
private DataViewSchema? _schema;
|
||||||
private ITransformer? _transformer;
|
private ITransformer? _transformer;
|
||||||
|
|
||||||
private string Name { get; set; }
|
private string Name { get; set; } = "TestModel";
|
||||||
|
|
||||||
public async Task Train(ModelDefinition modelDef)
|
public async Task Train(ModelDefinition modelDef)
|
||||||
{
|
{
|
||||||
var pipeline = _estimatorBuilder.BuildPipeline(_mlContext, modelDef);
|
var pipeline = _estimatorBuilder.BuildPipeline(_mlContext, modelDef);
|
||||||
var (data, filename) = await MLHelpers.Convert(_mlContext,modelDef);
|
var (data, filename) = await MLHelpers.Convert(_mlContext, modelDef);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_schema = data.Schema;
|
_schema = data.Schema;
|
||||||
|
|||||||
89
DeepTrace/ML/Measures.cs
Normal file
89
DeepTrace/ML/Measures.cs
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
using PrometheusAPI;
|
||||||
|
|
||||||
|
namespace DeepTrace.ML
|
||||||
|
{
|
||||||
|
public class MeasureMin : IMeasure
|
||||||
|
{
|
||||||
|
public string Name => "Min";
|
||||||
|
public float Calculate(IEnumerable<TimeSeries> data) =>
|
||||||
|
data
|
||||||
|
.Where(x => x.Value != 0.0f)
|
||||||
|
.Min( x => x.Value )
|
||||||
|
;
|
||||||
|
|
||||||
|
public void Reset() { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MeasureMax : IMeasure
|
||||||
|
{
|
||||||
|
public string Name => "Max";
|
||||||
|
public float Calculate(IEnumerable<TimeSeries> data) => data.Max(x => x.Value);
|
||||||
|
public void Reset() { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MeasureAvg : IMeasure
|
||||||
|
{
|
||||||
|
public string Name => "Avg";
|
||||||
|
public float Calculate(IEnumerable<TimeSeries> data) => data.Average(x => x.Value);
|
||||||
|
public void Reset() { }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// WARNING: Only works with fixed length interval
|
||||||
|
/// </summary>
|
||||||
|
public class MeasureSum : IMeasure
|
||||||
|
{
|
||||||
|
public string Name => "Sum";
|
||||||
|
public float Calculate(IEnumerable<TimeSeries> data) => data.Sum(x => x.Value);
|
||||||
|
public void Reset() { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MeasureMedian : IMeasure
|
||||||
|
{
|
||||||
|
public string Name => "Median";
|
||||||
|
|
||||||
|
public float Calculate(IEnumerable<TimeSeries> data)
|
||||||
|
=> MedianHelper.Median(data, x => x.Value);
|
||||||
|
|
||||||
|
public void Reset() { }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MeasureDiff<T> : IMeasure where T : IMeasure, new()
|
||||||
|
{
|
||||||
|
private T _measure = new();
|
||||||
|
public string Name => "Diff_"+_measure.Name;
|
||||||
|
|
||||||
|
private float _prev = float.NaN;
|
||||||
|
|
||||||
|
public float Calculate(IEnumerable<TimeSeries> data)
|
||||||
|
{
|
||||||
|
var val = _measure.Calculate(data);
|
||||||
|
if (float.IsNaN(_prev))
|
||||||
|
{
|
||||||
|
_prev = val;
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
val = val - _prev;
|
||||||
|
_prev = val;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
_measure.Reset();
|
||||||
|
_prev = float.NaN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MeasureDiffMin : MeasureDiff<MeasureMin> { }
|
||||||
|
public class MeasureDiffMax : MeasureDiff<MeasureMax> { }
|
||||||
|
public class MeasureDiffAvg : MeasureDiff<MeasureAvg> { }
|
||||||
|
/// <summary>
|
||||||
|
/// WARNING: Only works with fixed length interval
|
||||||
|
/// </summary>
|
||||||
|
public class MeasureDiffSum : MeasureDiff<MeasureSum> { }
|
||||||
|
public class MeasureDiffMedian : MeasureDiff<MeasureMedian> { }
|
||||||
|
|
||||||
|
}
|
||||||
80
DeepTrace/ML/MedianHelper.cs
Normal file
80
DeepTrace/ML/MedianHelper.cs
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
namespace DeepTrace.ML;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculate median.
|
||||||
|
/// https://stackoverflow.com/questions/4140719/calculate-median-in-c-sharp
|
||||||
|
/// </summary>
|
||||||
|
public static class MedianHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Partitions the given list around a pivot element such that all elements on left of pivot are <= pivot
|
||||||
|
/// and the ones at thr right are > pivot. This method can be used for sorting, N-order statistics such as
|
||||||
|
/// as median finding algorithms.
|
||||||
|
/// Pivot is selected ranodmly if random number generator is supplied else its selected as last element in the list.
|
||||||
|
/// Reference: Introduction to Algorithms 3rd Edition, Corman et al, pp 171
|
||||||
|
/// </summary>
|
||||||
|
private static int Partition<T>(this IList<T> list, int start, int end, Random rnd = null) where T : IComparable<T>
|
||||||
|
{
|
||||||
|
if (rnd != null)
|
||||||
|
list.Swap(end, rnd.Next(start, end + 1));
|
||||||
|
|
||||||
|
var pivot = list[end];
|
||||||
|
var lastLow = start - 1;
|
||||||
|
for (var i = start; i < end; i++)
|
||||||
|
{
|
||||||
|
if (list[i].CompareTo(pivot) <= 0)
|
||||||
|
list.Swap(i, ++lastLow);
|
||||||
|
}
|
||||||
|
list.Swap(end, ++lastLow);
|
||||||
|
return lastLow;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns Nth smallest element from the list. Here n starts from 0 so that n=0 returns minimum, n=1 returns 2nd smallest element etc.
|
||||||
|
/// Note: specified list would be mutated in the process.
|
||||||
|
/// Reference: Introduction to Algorithms 3rd Edition, Corman et al, pp 216
|
||||||
|
/// </summary>
|
||||||
|
public static T NthOrderStatistic<T>(this IList<T> list, int n, Random rnd = null) where T : IComparable<T>
|
||||||
|
{
|
||||||
|
return NthOrderStatistic(list, n, 0, list.Count - 1, rnd);
|
||||||
|
}
|
||||||
|
private static T NthOrderStatistic<T>(this IList<T> list, int n, int start, int end, Random rnd) where T : IComparable<T>
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
var pivotIndex = list.Partition(start, end, rnd);
|
||||||
|
if (pivotIndex == n)
|
||||||
|
return list[pivotIndex];
|
||||||
|
|
||||||
|
if (n < pivotIndex)
|
||||||
|
end = pivotIndex - 1;
|
||||||
|
else
|
||||||
|
start = pivotIndex + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Swap<T>(this IList<T> list, int i, int j)
|
||||||
|
{
|
||||||
|
if (i == j) //This check is not required but Partition function may make many calls so its for perf reason
|
||||||
|
return;
|
||||||
|
var temp = list[i];
|
||||||
|
list[i] = list[j];
|
||||||
|
list[j] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Note: specified list would be mutated in the process.
|
||||||
|
/// </summary>
|
||||||
|
public static T Median<T>(IList<T> list) where T : IComparable<T>
|
||||||
|
{
|
||||||
|
return list.NthOrderStatistic((list.Count - 1) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TValue Median<T,TValue>(IEnumerable<T> sequence, Func<T, TValue> getValue)
|
||||||
|
where TValue : IComparable<TValue>
|
||||||
|
{
|
||||||
|
var list = sequence.Select(getValue).ToList();
|
||||||
|
var mid = (list.Count - 1) / 2;
|
||||||
|
return list.NthOrderStatistic(mid);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,11 +6,13 @@
|
|||||||
@using DeepTrace.Controls;
|
@using DeepTrace.Controls;
|
||||||
@using Microsoft.ML;
|
@using Microsoft.ML;
|
||||||
@using PrometheusAPI;
|
@using PrometheusAPI;
|
||||||
|
@using System.Text;
|
||||||
|
|
||||||
@inject PrometheusClient Prometheus
|
@inject PrometheusClient Prometheus
|
||||||
@inject IDialogService DialogService
|
@inject IDialogService DialogService
|
||||||
@inject IDataSourceStorageService StorageService
|
@inject IDataSourceStorageService StorageService
|
||||||
@inject IModelDefinitionService ModelService
|
@inject IModelStorageService ModelService
|
||||||
|
@inject ITrainedModelStorageService TrainedModelService
|
||||||
@inject IEstimatorBuilder EstimatorBuilder
|
@inject IEstimatorBuilder EstimatorBuilder
|
||||||
@inject NavigationManager NavManager
|
@inject NavigationManager NavManager
|
||||||
@inject IJSRuntime Js
|
@inject IJSRuntime Js
|
||||||
@ -64,12 +66,24 @@
|
|||||||
<MudCardActions>
|
<MudCardActions>
|
||||||
<MudButton ButtonType="ButtonType.Submit" Variant="Variant.Filled" Color="MudBlazor.Color.Primary" Class="ml-3" OnClick="@HandleAddTableContent" Disabled="@IsAddDisabled">Add</MudButton>
|
<MudButton ButtonType="ButtonType.Submit" Variant="Variant.Filled" Color="MudBlazor.Color.Primary" Class="ml-3" OnClick="@HandleAddTableContent" Disabled="@IsAddDisabled">Add</MudButton>
|
||||||
<MudButton ButtonType="ButtonType.Submit" Variant="Variant.Filled" Color="MudBlazor.Color.Primary" Class="ml-3" OnClick="@HandleRefresh" Disabled="@IsAddDisabled">Refresh</MudButton>
|
<MudButton ButtonType="ButtonType.Submit" Variant="Variant.Filled" Color="MudBlazor.Color.Primary" Class="ml-3" OnClick="@HandleRefresh" Disabled="@IsAddDisabled">Refresh</MudButton>
|
||||||
|
<MudFileUpload T="IBrowserFile" Accept=".csv" FilesChanged="@HandleImport" MaximumFileCount="1" Class="ml-3">
|
||||||
|
<ButtonTemplate>
|
||||||
|
<MudButton HtmlTag="label"
|
||||||
|
Variant="Variant.Filled"
|
||||||
|
Color="MudBlazor.Color.Primary"
|
||||||
|
StartIcon="@Icons.Material.Filled.CloudUpload"
|
||||||
|
for="@context">
|
||||||
|
Import
|
||||||
|
</MudButton>
|
||||||
|
</ButtonTemplate>
|
||||||
|
</MudFileUpload>
|
||||||
<MudButton ButtonType="ButtonType.Submit" Variant="Variant.Filled" Color="MudBlazor.Color.Primary" Class="ml-3" OnClick="@HandleExport" Disabled="@IsAddDisabled">Export</MudButton>
|
<MudButton ButtonType="ButtonType.Submit" Variant="Variant.Filled" Color="MudBlazor.Color.Primary" Class="ml-3" OnClick="@HandleExport" Disabled="@IsAddDisabled">Export</MudButton>
|
||||||
<MudSpacer/>
|
<MudSpacer/>
|
||||||
|
|
||||||
<MudButton ButtonType="ButtonType.Submit" Variant="Variant.Filled" Color="MudBlazor.Color.Primary" Class="ml-3" OnClick="@HandleTrain">Train</MudButton>
|
<MudButton ButtonType="ButtonType.Submit" Variant="Variant.Filled" Color="MudBlazor.Color.Primary" Class="ml-3" OnClick="@HandleTrain">Train</MudButton>
|
||||||
</MudCardActions>
|
</MudCardActions>
|
||||||
|
|
||||||
|
|
||||||
<MudTable
|
<MudTable
|
||||||
Items="@_modelForm!.CurrentModel.IntervalDefinitionList"
|
Items="@_modelForm!.CurrentModel.IntervalDefinitionList"
|
||||||
Hover="true"
|
Hover="true"
|
||||||
@ -233,6 +247,9 @@
|
|||||||
|
|
||||||
var sources = await StorageService.Load();
|
var sources = await StorageService.Load();
|
||||||
var models = await ModelService.Load();
|
var models = await ModelService.Load();
|
||||||
|
var trainedModels = await TrainedModelService.Load();
|
||||||
|
IList<IBrowserFile> files = new List<IBrowserFile>();
|
||||||
|
|
||||||
if (sources.Count > 0)
|
if (sources.Count > 0)
|
||||||
_dataSources = sources;
|
_dataSources = sources;
|
||||||
if (models.Count > 0)
|
if (models.Count > 0)
|
||||||
@ -398,6 +415,18 @@
|
|||||||
// await InvokeAsync(StateHasChanged);
|
// await InvokeAsync(StateHasChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Doesn't work
|
||||||
|
private async Task HandleImport(IBrowserFile file)
|
||||||
|
{
|
||||||
|
var result = new StringBuilder();
|
||||||
|
var reader = new StreamReader(file.OpenReadStream(file.Size));
|
||||||
|
|
||||||
|
while (reader.Peek() >= 0)
|
||||||
|
result.AppendLine(await reader.ReadLineAsync());
|
||||||
|
|
||||||
|
result.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
private async Task HandleExport()
|
private async Task HandleExport()
|
||||||
{
|
{
|
||||||
await Js.InvokeVoidAsync("open", $"{NavManager.BaseUri}api/download/mldata/{Uri.EscapeDataString(_modelForm.CurrentModel.Name)}", "_blank");
|
await Js.InvokeVoidAsync("open", $"{NavManager.BaseUri}api/download/mldata/{Uri.EscapeDataString(_modelForm.CurrentModel.Name)}", "_blank");
|
||||||
@ -430,6 +459,12 @@
|
|||||||
var bytes = mlProcessor.Export();
|
var bytes = mlProcessor.Export();
|
||||||
|
|
||||||
//save to Mongo
|
//save to Mongo
|
||||||
|
var trainedModel = new TrainedModelDefinition
|
||||||
|
{
|
||||||
|
Name = "TrainedModel",
|
||||||
|
Value = bytes
|
||||||
|
};
|
||||||
|
await TrainedModelService.Store(trainedModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,8 @@ builder.Services.AddHttpClient<PrometheusClient>(c => c.BaseAddress = new UriBui
|
|||||||
builder.Services
|
builder.Services
|
||||||
.AddSingleton<IMongoClient>( s => new MongoClient(builder.Configuration.GetValue<string>("Connections:MongoDb") ))
|
.AddSingleton<IMongoClient>( s => new MongoClient(builder.Configuration.GetValue<string>("Connections:MongoDb") ))
|
||||||
.AddSingleton<IDataSourceStorageService, DataSourceStorageService>()
|
.AddSingleton<IDataSourceStorageService, DataSourceStorageService>()
|
||||||
.AddSingleton<IModelDefinitionService, ModelDefinitionService>()
|
.AddSingleton<IModelStorageService, ModelStorageService>()
|
||||||
|
.AddSingleton<ITrainedModelStorageService, TrainedModelStorageService>()
|
||||||
.AddSingleton<IEstimatorBuilder, EstimatorBuilder>()
|
.AddSingleton<IEstimatorBuilder, EstimatorBuilder>()
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ using System.Text;
|
|||||||
namespace DeepTrace.Services
|
namespace DeepTrace.Services
|
||||||
{
|
{
|
||||||
|
|
||||||
public interface IModelDefinitionService
|
public interface IModelStorageService
|
||||||
{
|
{
|
||||||
Task Delete(ModelDefinition source, bool ignoreNotStored = false);
|
Task Delete(ModelDefinition source, bool ignoreNotStored = false);
|
||||||
Task<List<ModelDefinition>> Load();
|
Task<List<ModelDefinition>> Load();
|
||||||
|
|||||||
11
DeepTrace/Services/ITrainedModelStorageService.cs
Normal file
11
DeepTrace/Services/ITrainedModelStorageService.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
using DeepTrace.Data;
|
||||||
|
|
||||||
|
namespace DeepTrace.Services
|
||||||
|
{
|
||||||
|
public interface ITrainedModelStorageService
|
||||||
|
{
|
||||||
|
Task Delete(TrainedModelDefinition source, bool ignoreNotStored = false);
|
||||||
|
Task<List<TrainedModelDefinition>> Load();
|
||||||
|
Task Store(TrainedModelDefinition source);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,7 +4,7 @@ using MongoDB.Driver;
|
|||||||
|
|
||||||
namespace DeepTrace.Services
|
namespace DeepTrace.Services
|
||||||
{
|
{
|
||||||
public class ModelDefinitionService : IModelDefinitionService
|
public class ModelStorageService : IModelStorageService
|
||||||
{
|
{
|
||||||
|
|
||||||
private const string MongoDBDatabaseName = "DeepTrace";
|
private const string MongoDBDatabaseName = "DeepTrace";
|
||||||
@ -12,7 +12,7 @@ namespace DeepTrace.Services
|
|||||||
|
|
||||||
private readonly IMongoClient _client;
|
private readonly IMongoClient _client;
|
||||||
|
|
||||||
public ModelDefinitionService(IMongoClient client)
|
public ModelStorageService(IMongoClient client)
|
||||||
{
|
{
|
||||||
_client = client;
|
_client = client;
|
||||||
}
|
}
|
||||||
@ -51,7 +51,7 @@ namespace DeepTrace.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
var db = _client.GetDatabase(MongoDBDatabaseName);
|
var db = _client.GetDatabase(MongoDBDatabaseName);
|
||||||
var collection = db.GetCollection<DataSourceStorage>(MongoDBCollection);
|
var collection = db.GetCollection<ModelDefinition>(MongoDBCollection);
|
||||||
|
|
||||||
await collection.DeleteOneAsync(filter: new BsonDocument("_id", source.Id));
|
await collection.DeleteOneAsync(filter: new BsonDocument("_id", source.Id));
|
||||||
}
|
}
|
||||||
|
|||||||
58
DeepTrace/Services/TrainedModelStorageService.cs
Normal file
58
DeepTrace/Services/TrainedModelStorageService.cs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
using DeepTrace.Data;
|
||||||
|
using MongoDB.Bson;
|
||||||
|
using MongoDB.Driver;
|
||||||
|
|
||||||
|
namespace DeepTrace.Services
|
||||||
|
{
|
||||||
|
public class TrainedModelStorageService: ITrainedModelStorageService
|
||||||
|
{
|
||||||
|
private const string MongoDBDatabaseName = "DeepTrace";
|
||||||
|
private const string MongoDBCollection = "TrainedModels";
|
||||||
|
|
||||||
|
private readonly IMongoClient _client;
|
||||||
|
|
||||||
|
public TrainedModelStorageService(IMongoClient client)
|
||||||
|
{
|
||||||
|
_client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<TrainedModelDefinition>> Load()
|
||||||
|
{
|
||||||
|
var db = _client.GetDatabase(MongoDBDatabaseName);
|
||||||
|
var collection = db.GetCollection<TrainedModelDefinition>(MongoDBCollection);
|
||||||
|
|
||||||
|
var res = await (await collection.FindAsync("{}")).ToListAsync();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
public async Task Store(TrainedModelDefinition source)
|
||||||
|
{
|
||||||
|
var db = _client.GetDatabase(MongoDBDatabaseName);
|
||||||
|
var collection = db.GetCollection<TrainedModelDefinition>(MongoDBCollection);
|
||||||
|
|
||||||
|
if (source.Id == null)
|
||||||
|
source.Id = ObjectId.GenerateNewId();
|
||||||
|
|
||||||
|
// use upsert (insert or update) to automatically handle subsequent updates
|
||||||
|
await collection.ReplaceOneAsync(
|
||||||
|
filter: new BsonDocument("_id", source.Id),
|
||||||
|
options: new ReplaceOptions { IsUpsert = true },
|
||||||
|
replacement: source
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Delete(TrainedModelDefinition source, bool ignoreNotStored = false)
|
||||||
|
{
|
||||||
|
if (source.Id == null)
|
||||||
|
{
|
||||||
|
if (!ignoreNotStored)
|
||||||
|
throw new InvalidDataException("Source was not stored yet. There is nothing to delete");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var db = _client.GetDatabase(MongoDBDatabaseName);
|
||||||
|
var collection = db.GetCollection<TrainedModelDefinition>(MongoDBCollection);
|
||||||
|
|
||||||
|
await collection.DeleteOneAsync(filter: new BsonDocument("_id", source.Id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user