Using Facets in the Aggregation Framework C#

不羁的心 提交于 2019-12-03 21:37:37

I would personally not use $facet here since you've only got one pipeline which kind of defeats the purpose of $facet in the first place...

The following is simpler and scales better ($facet will create one single potentially massive document).

db.collection.aggregate([
{
    $match: {
        "Name" : "My First Book"
    }
}, {
    $project: {
        "Tags": {
            $objectToArray: "$Tags"
        }
    }
}, {
    $unwind: "$Tags"
}, {
    $sortByCount: "$Tags"
}, {
    $group: { // not really needed unless you need to have all results in one single document
        "_id": null,
        "categorizedByTags": {
            $push: "$$ROOT"
        }
    }
}, {
    $project: { // not really needed, either: remove _id field
        "_id": 0
    }
}])

This could be written using the C# driver as follows:

var collection = new MongoClient().GetDatabase("test").GetCollection<Book>("test");

var pipeline = collection.Aggregate()
    .Match(b => b.Name == "My First Book")
    .Project("{Tags: { $objectToArray: \"$Tags\" }}")
    .Unwind("Tags")
    .SortByCount<BsonDocument>("$Tags");

var output = pipeline.ToList().ToJson(new JsonWriterSettings {Indent = true});

Console.WriteLine(output);

Here's the version using a facet:

var collection = new MongoClient().GetDatabase("test").GetCollection<Book>("test");

var project = PipelineStageDefinitionBuilder.Project<Book, BsonDocument>("{Tags: { $objectToArray: \"$Tags\" }}");
var unwind = PipelineStageDefinitionBuilder.Unwind<BsonDocument, BsonDocument>("Tags");
var sortByCount = PipelineStageDefinitionBuilder.SortByCount<BsonDocument, BsonDocument>("$Tags");

var pipeline = PipelineDefinition<Book, AggregateSortByCountResult<BsonDocument>>.Create(new IPipelineStageDefinition[] { project, unwind, sortByCount });

// string based alternative version
//var pipeline = PipelineDefinition<Book, BsonDocument>.Create(
//    "{ $project :{ Tags: { $objectToArray: \"$Tags\" } } }",
//    "{ $unwind : \"$Tags\" }",
//    "{ $sortByCount : \"$Tags\" }");

var facetPipeline = AggregateFacet.Create("categorizedByTags", pipeline);

var aggregation = collection.Aggregate().Match(b => b.Name == "My First Book").Facet(facetPipeline);

var output = aggregation.Single().Facets.ToJson(new JsonWriterSettings { Indent = true });

Console.WriteLine(output);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!