0

My overall goal is to run a query that shows all the collections with the amount of data / counts and so on.

I found the following command/query and try to run it like this:

MongoClient client = new MongoClient(server);
var db = client.GetDatabase(database);
 
const string mongoQueryA = "var collectionNames = db.getCollectionNames(), stats = []; " +
"collectionNames.forEach(function(n) { stats.push(db[n].stats()); }); " +
"stats = stats.sort(function(a, b) { return b['size'] - a['size']; }); ";
var command = new JsonCommand<BsonDocument>(mongoQueryA);
var test = db.RunCommand<BsonDocument>(command);

And the code fails here. Exceptions:

JSON reader was expecting a value but found 'var'.

My understanding is that this shoul be run as command?

Running the query in Robot T works as expected. Bonus the plan was to return the data in the following format ( Based on Json from running query manualy in Robot T)

 class MongoCollectionInfo
    {
        public string ns { get; set; }

        public long size { get; set; }

        public long count { get; set; }

        public long avgObjSize { get; set; }

        public long storageSize { get; set; }

        public long nindexes { get; set; }

        public long totalIndexSize { get; set; }
    }
6
  • 1
    var collectionNames... is not JSON. Commented Aug 10, 2020 at 7:51
  • Im aware, the question is how do i run this command / Query with the offical MongoDB C# driver. Im clearly lacking some MongoDB knowlage, so im hoping to figure out where i went wrong. Commented Aug 10, 2020 at 7:55
  • As it seems, you only need to get collections via C# driver (look around mongodb.github.io/mongo-csharp-driver/2.10/apidocs/html/…) and do anything else in C#. As for the deserialization to MongoCollectionInfo use nuget.org/packages/Newtonsoft.Json Commented Aug 10, 2020 at 8:12
  • Im sure i could do: IMongoDatabase.ListCollectionsAsync and then run stats on eatch collection. But that would generate 80 queries instead of 1, im hoping to avoid that. Commented Aug 10, 2020 at 8:30
  • You might use db.Eval - however I would do it from C# as it is more maintainable. Do you expect real performance hits? How often do you need it be called? Commented Aug 10, 2020 at 9:42

1 Answer 1

1

What you're trying to achieve can be done purely in C# as it looks like what you've attempted to do is send javascript to the server to be executed which is not how commands work.

To start off with we'll need to get a list of all the collections within a database inside the MongoDB instance.

var client = new MongoClient();

var db = client.GetDatabase("test");

var collectionNames = await (await db.ListCollectionNamesAsync()).ToListAsync();

once we've got the collection names (collectionNames) we can then go ask the database for the stats on that collection by issue a command.

var allCollStats = new List<BsonDocument>(collectionNames.Count);
foreach (var name in collectionNames)
{
    var collStatsResult = await db.RunCommandAsync(new BsonDocumentCommand<BsonDocument>(new BsonDocument("collStats", name)));

    allCollStats.Add(collStatsResult);
}

The allCollStats then will hold all the stats for the collections and we can then use it as we see fit

foreach (var collStats in allCollStats)
{
    Console.WriteLine($"ns: {collStats["ns"]}, size: {collStats["size"]}");
}

// ns: test.test, size: 117
// ns: test.people, size: 5092

Also, if you wanted to use a typed result instead of a BsonDocument you can pass this in as the generic agrument to the command.

var collStatsResult = await db.RunCommandAsync(new BsonDocumentCommand<MongoCollectionInfo>(new BsonDocument("collStats", name)));

Console.WriteLine($"ns: {collStatsResult .ns}, size: {collStatsResult .size}");
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.