Fixing bad location index
Deploy Promiscuity Auth API / deploy (push) Successful in 45s
Deploy Promiscuity Character API / deploy (push) Successful in 57s
Deploy Promiscuity Locations API / deploy (push) Successful in 57s
k8s smoke test / test (push) Successful in 8s

This commit is contained in:
2026-03-13 21:26:36 -05:00
parent 9b646f501c
commit 6ca0f306bb
3 changed files with 170 additions and 63 deletions
@@ -4,28 +4,27 @@ using MongoDB.Driver;
namespace LocationsApi.Services;
public class LocationStore
{
private readonly IMongoCollection<Location> _col;
public LocationStore(IConfiguration cfg)
{
var cs = cfg["MongoDB:ConnectionString"] ?? "mongodb://127.0.0.1:27017";
var dbName = cfg["MongoDB:DatabaseName"] ?? "GameDb";
public class LocationStore
{
private readonly IMongoCollection<Location> _col;
private readonly IMongoCollection<BsonDocument> _rawCol;
private const string CoordIndexName = "coord_x_1_coord_y_1";
public LocationStore(IConfiguration cfg)
{
var cs = cfg["MongoDB:ConnectionString"] ?? "mongodb://127.0.0.1:27017";
var dbName = cfg["MongoDB:DatabaseName"] ?? "GameDb";
var client = new MongoClient(cs);
var db = client.GetDatabase(dbName);
var collectionName = "Locations";
EnsureLocationSchema(db, collectionName);
_col = db.GetCollection<Location>(collectionName);
var coordIndex = Builders<Location>.IndexKeys
.Ascending(l => l.Coord.X)
.Ascending(l => l.Coord.Y);
var coordIndexOptions = new CreateIndexOptions { Unique = true };
_col.Indexes.CreateOne(new CreateIndexModel<Location>(coordIndex, coordIndexOptions));
EnsureOriginLocation();
}
var db = client.GetDatabase(dbName);
var collectionName = "Locations";
EnsureLocationSchema(db, collectionName);
_col = db.GetCollection<Location>(collectionName);
_rawCol = db.GetCollection<BsonDocument>(collectionName);
EnsureCoordIndexes();
EnsureOriginLocation();
}
private static void EnsureLocationSchema(IMongoDatabase db, string collectionName)
{
@@ -95,18 +94,55 @@ public class LocationStore
return result.DeletedCount > 0;
}
public async Task<bool> UpdateNameAsync(string id, string name)
{
var filter = Builders<Location>.Filter.Eq(l => l.Id, id);
var update = Builders<Location>.Update.Set(l => l.Name, name);
var result = await _col.UpdateOneAsync(filter, update);
return result.ModifiedCount > 0;
}
private void EnsureOriginLocation()
{
var filter = Builders<Location>.Filter.And(
Builders<Location>.Filter.Eq(l => l.Coord.X, 0),
public async Task<bool> UpdateNameAsync(string id, string name)
{
var filter = Builders<Location>.Filter.Eq(l => l.Id, id);
var update = Builders<Location>.Update.Set(l => l.Name, name);
var result = await _col.UpdateOneAsync(filter, update);
return result.ModifiedCount > 0;
}
private void EnsureCoordIndexes()
{
var indexes = _rawCol.Indexes.List().ToList();
foreach (var index in indexes)
{
var name = index.GetValue("name", "").AsString;
if (name == "_id_")
continue;
var keyDoc = index.GetValue("key", new BsonDocument()).AsBsonDocument;
if (IsLegacyCoordIndex(keyDoc) || IsUnexpectedCoordIndex(keyDoc))
_rawCol.Indexes.DropOne(name);
}
var coordIndex = new BsonDocument
{
{ "coord.x", 1 },
{ "coord.y", 1 }
};
var coordIndexOptions = new CreateIndexOptions { Unique = true, Name = CoordIndexName };
_rawCol.Indexes.CreateOne(new CreateIndexModel<BsonDocument>(coordIndex, coordIndexOptions));
}
private static bool IsLegacyCoordIndex(BsonDocument keyDoc) =>
keyDoc.ElementCount == 2 &&
keyDoc.TryGetValue("Coord.X", out var xValue) &&
xValue.IsInt32 && xValue.AsInt32 == 1 &&
keyDoc.TryGetValue("Coord.Y", out var yValue) &&
yValue.IsInt32 && yValue.AsInt32 == 1;
private static bool IsUnexpectedCoordIndex(BsonDocument keyDoc)
{
var hasLower = keyDoc.Contains("coord.x") || keyDoc.Contains("coord.y");
var hasUpper = keyDoc.Contains("Coord.X") || keyDoc.Contains("Coord.Y");
return hasUpper || (hasLower && !(keyDoc.Contains("coord.x") && keyDoc.Contains("coord.y")));
}
private void EnsureOriginLocation()
{
var filter = Builders<Location>.Filter.And(
Builders<Location>.Filter.Eq(l => l.Coord.X, 0),
Builders<Location>.Filter.Eq(l => l.Coord.Y, 0)
);
var existing = _col.Find(filter).FirstOrDefault();