Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB Aggregate function in C#

I am trying to display/list data after using aggregation function but it isn't happening.

This code works absolutely fine.

        var connectionstring = "mongodb://localhost:27017";
        var client = new MongoClient(connectionstring);
        var db = client.GetDatabase("school");
        var col = db.GetCollection<BsonDocument>("students");
        var filter = new BsonDocument("type", "homework");
        var filter2 = Builders<BsonDocument>.Filter.Eq("scores.type", "homework");

        var myresults = await col.Find(filter2)
            .Limit(2)
            .Project("{name:1,scores:1,_id:0}")
            .Sort("{score:1}")
            .ToListAsync();

        foreach (var result in myresults)
        {
            Console.WriteLine(result);
        }

This code fetches document as it should however when I replace

 var myresults = await col.Find(filter2)
            .Limit(2)
            .Project("{name:1,scores:1,_id:0}")
            .Sort("{score:1}")
            .ToListAsync();

with this

            var myresults = await col.Aggregate()
            .Unwind("{$scores}")
            .Group(new BsonDocument { { "_id", "$_id" }, { "lowscore", new BsonDocument("$min", "$scores.score") } })
            //.Group("{_id:'$_id',lowscore:{$min:'$scores.score'}}")
            .ToListAsync();

No record is being pulled. I do not want to use Pipeline method. I simply want to display the result obtained via aggregate function.

This is my Mongo Query (I want the same result as this in C#)-

db.students.aggregate([{$sort:{_id:-1}},{$unwind:"$scores"},{$group:{_id:"$_id", lowscore:{"$min":"$scores.score"}}}])
like image 799
Pirate X Avatar asked Apr 04 '16 09:04

Pirate X


People also ask

What is MongoDB aggregate function?

What is Aggregation in MongoDB? Aggregation is a way of processing a large number of documents in a collection by means of passing them through different stages. The stages make up what is known as a pipeline. The stages in a pipeline can filter, sort, group, reshape and modify documents that pass through the pipeline.

Is MongoDB good for aggregate?

In MongoDB, aggregation operations process the data records/documents and return computed results. It collects values from various documents and groups them together and then performs different types of operations on that grouped data like sum, average, minimum, maximum, etc to return a computed result.

What does MongoDB aggregate return?

aggregate() method returns a cursor to the documents produced by the final stage of the aggregation pipeline operation, or if you include the explain option, the document that provides details on the processing of the aggregation operation.

What are the differences between using aggregate () and find () in MongoDB?

With aggregate + $match, you get a big monolithic BSON containing all matching documents. With find, you get a cursor to all matching documents. Then you can get each document one by one.


Video Answer


2 Answers

Building aggregation pipeline is bit tricky.

Try:

var pipeline = new BsonDocument[] {
    new BsonDocument{ { "$sort", new BsonDocument("_id", 1) }},
    new BsonDocument{{"$unwind", "$scores"}},
    new BsonDocument{{"$group", new BsonDocument{
                {"_id", "$_id"},
                {"lowscore",new BsonDocument{
                        {"$min","$scores.score"}}
                }}
        }}
};

var result = collection.Aggregate<BsonDocument> (pipeline).ToListAsync();

If you do pipeline.ToJson(), you'll get following JSON equivalent string which is same as of your original and tested MongoShell query.

[
    {
        "$sort": {
            "_id": 1
        }
    },
    {
        "$unwind": "$scores"
    },
    {
        "$group": {
            "_id": "$_id",
            "lowscore": {
                "$min": "$scores.score"
            }
        }
    }
]
like image 172
Saleem Avatar answered Nov 14 '22 23:11

Saleem


This is wrong... {$scores} isn't even valid json. Remove the curly braces and the dollar sign from the $unwind directive.

The parameter name is field, so you need to provide a field name to it.

like image 39
Craig Wilson Avatar answered Nov 14 '22 22:11

Craig Wilson