I'm looking to retrieve index usage information from MongoDB via the .NET driver. For the curious it is to prove in an integration test that an index is being used as intended, specifically the number of accesses.
I wandered through the latest API documents and found IndexInfo, which provides index metadata, but not statistics. The closest thing is the CollectionStatsResult, but that doesn't give the access count.
Is there an API and data structure that provide what I am looking for? Is there another lower-level way (e.g. a way to execute the MongoDB asd command via the .NET driver?
I know it is possible. I am using MongoDB Compass and able to see incrementing accesses when I run the test.
Credit to Alex Blex for part of the solution, which is to use Aggregate
with $indexStats.
I ended up with this code, which returns a tuple of the access count and last access time. It traversing the BsonDocument
that represents the return result, looking for the relevant data.
public async Task<(long AccessCount, DateTime LastAccessed)> GetIndexStatisticsAsync(string collectionName, string indexName)
{
var statsPipeline = new[] { new BsonDocument(new BsonElement("$indexStats", new BsonDocument())) };
using (var stats = await Database.GetCollection<BsonDocument>(collectionName).AggregateAsync<BsonDocument>(statsPipeline))
while (await stats.MoveNextAsync())
{
var batch = stats.Current;
var document = batch
.Where(x => x.Elements.Any(y => y.Name.IsOneOf("key", "name") && y.Value == indexName))
.Select(x => (BsonDocument)x.Elements.FirstOrDefault(y => y.Name == "accesses").Value)
.FirstOrDefault();
return document == null
? default
: ((long)document.Elements.ElementAt(0).Value, (DateTime)document.Elements.ElementAt(1).Value);
}
return default;
}