54 lines
2.9 KiB
C#
54 lines
2.9 KiB
C#
using MongoDB.Bson;
|
|
using MongoDB.Driver;
|
|
using QuestionsApi.Models;
|
|
|
|
namespace QuestionsApi.Services;
|
|
|
|
public static class Step3SystemBackfillCommand
|
|
{
|
|
public const string Confirmation = "BACKFILL_STEP3_SYSTEMS";
|
|
|
|
public static async Task<int> RunAsync(IConfiguration configuration, string[] args, TextWriter output)
|
|
{
|
|
var apply = args.Contains("--apply", StringComparer.Ordinal);
|
|
var confirmIndex = Array.IndexOf(args, "--confirm");
|
|
var confirmation = confirmIndex >= 0 && confirmIndex + 1 < args.Length ? args[confirmIndex + 1] : "";
|
|
var database = new MongoDatabaseProvider(configuration).Database;
|
|
var questions = database.GetCollection<Question>("Questions");
|
|
var all = await questions.Find(FilterDefinition<Question>.Empty).ToListAsync();
|
|
var classified = all.Select(question => (Question: question, System: Step3SystemCatalog.Derive(question) ?? "")).ToList();
|
|
var changes = classified.Where(item => item.System.Length > 0 && item.Question.Step3System != item.System).ToList();
|
|
var unmapped = classified.Count(item => item.System.Length == 0);
|
|
await output.WriteLineAsync($"Questions requiring Step3System backfill: {changes.Count}; unmapped: {unmapped}.");
|
|
foreach (var group in classified.Where(item => item.System.Length == 0)
|
|
.GroupBy(item => $"{item.Question.System} | {item.Question.PerformanceCategory} | {item.Question.Discipline}")
|
|
.OrderByDescending(group => group.Count()).ThenBy(group => group.Key, StringComparer.Ordinal))
|
|
await output.WriteLineAsync($"Unmapped ({group.Count()}): {group.Key}; ids: {string.Join(", ", group.Select(item => item.Question.ExternalId).Take(10))}");
|
|
if (!apply)
|
|
{
|
|
await output.WriteLineAsync($"Dry run only. Re-run with --apply --confirm {Confirmation}.");
|
|
return 0;
|
|
}
|
|
if (confirmation != Confirmation)
|
|
{
|
|
await output.WriteLineAsync($"Refusing migration: --confirm {Confirmation} is required.");
|
|
return 2;
|
|
}
|
|
if (changes.Count > 0)
|
|
{
|
|
var writes = changes.Select(item => new UpdateOneModel<Question>(
|
|
Builders<Question>.Filter.Eq(question => question.Id, item.Question.Id),
|
|
Builders<Question>.Update.Set(question => question.Step3System, item.System))).ToList();
|
|
await questions.BulkWriteAsync(writes, new BulkWriteOptions { IsOrdered = false });
|
|
}
|
|
var remaining = await questions.CountDocumentsAsync(new BsonDocumentFilterDefinition<Question>(
|
|
new BsonDocument("$or", new BsonArray
|
|
{
|
|
new BsonDocument(nameof(Question.Step3System), new BsonDocument("$exists", false)),
|
|
new BsonDocument(nameof(Question.Step3System), "")
|
|
})));
|
|
await output.WriteLineAsync($"Backfilled {changes.Count}; unmapped or empty Step3System: {remaining}.");
|
|
return 0;
|
|
}
|
|
}
|