public void Facets() { var collection = new MongoClient("mongodb://localhost:27017/admin").GetDatabase("firstdb").GetCollection <Book>("book"); var car1 = new Book() { Name = "b1", Tags = new System.Collections.Generic.Dictionary <string, string>() { { "Edition", "Blah" }, { "Published", "2018" } } }; collection.InsertOne(car1); var pipelinex = collection.Aggregate() .Match(b => b.Name == "b1") .Project("{Tags: { $objectToArray: \"$Tags\" }}") .Unwind("Tags") .SortByCount <BsonDocument>("$Tags"); var outputx = pipelinex.ToList(); var json = outputx.ToJson(new JsonWriterSettings { Indent = true }); 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 == "b1").Facet(facetPipeline); var listx = aggregation.ToList(); // var outputxy = listx.Facets.ToJson(new JsonWriterSettings { Indent = true }); var output = aggregation.Single().Facets.ToJson(new JsonWriterSettings { Indent = true }); Console.WriteLine(output); }
/// <summary> /// Returns the nested list in the entity according to <paramref name="entityId"/>. /// /// <remarks> /// <para><b>Remarks ;</b></para> /// /// <para> We specify the nested list with <paramref name="unwindExpression"/>. </para> /// <para> You can send the filter value to the Nested list. See <paramref name="filterExpressionForTEmbedded"/>. </para> /// <para> You can get the specific properties. See <paramref name="projectExpression"/>. </para> /// </remarks> /// </summary> /// <typeparam name="TEmbedded"></typeparam> /// <param name="entityId"></param> /// <param name="unwindExpression"></param> /// <param name="filterExpressionForTEmbedded"></param> /// <param name="projectExpression"></param> /// <returns></returns> public async Task <List <TEmbedded> > GetNestedArrayByEntityIdAsync <TEmbedded>(ObjectId entityId, Expression <Func <TEntity, object> > unwindExpression, Expression <Func <TEmbedded, bool> > filterExpressionForTEmbedded = null, List <Expression <Func <TEmbedded, object> > > projectExpression = null) { var filter = filterExpressionForTEmbedded ?? Builders <TEmbedded> .Filter.Empty; var projectQuery = GetProjectionQuery(unwindExpression, projectExpression); var dataFacet = AggregateFacet.Create("matchingDatas", PipelineDefinition <TEmbedded, TEmbedded> .Create(new[] { PipelineStageDefinitionBuilder.Project <TEmbedded, TEmbedded>(BsonDocument.Parse("{" + projectQuery + "}")), PipelineStageDefinitionBuilder.Match(filter) })); var aggregateFacetResult = await _collection.Aggregate().Match(p => p.Id == entityId).Unwind <TEntity, TEmbedded>(unwindExpression).Facet(dataFacet).ToListAsync().ConfigureAwait(false); return(aggregateFacetResult.First().Facets.First(x => x.Name == "matchingDatas").Output <TEmbedded>().ToList()); }
/// <summary> /// /// You can bring up the page number you want with the number of data count you want. /// /// <para> You can sort when listing data. </para> /// <para> You can send the filter value to the Nested list. See <paramref name="filterDefinition"/>. </para> /// <para> You can get the specific properties. See <paramref name="projectExpression"/>. </para> /// /// </summary> /// <param name="pageIndex"></param> /// <param name="requestedItemCount"></param> /// <param name="orderByProps"></param> /// <param name="filterDefinition"></param> /// <param name="projectExpression"></param> /// <returns></returns> public async Task <(List <TEntity> entities, int pageCount, int totalDataCount)> GetAsPaginatedAsync(int pageIndex, int requestedItemCount, List <OrderByProp> orderByProps, FilterDefinition <TEntity> filterDefinition = null, Expression <Func <TEntity, TEntity> > projectExpression = null) { ValidatePaginationParameters(pageIndex, requestedItemCount); var stages = GetSortDefinitions <TEntity>(orderByProps).ToList(); var filter = filterDefinition ?? Builders <TEntity> .Filter.Empty; var projectionDefinition = Builders <TEntity> .Projection.Expression(projectExpression ?? (entity => entity)); var countFacat = AggregateFacet.Create("count", PipelineDefinition <TEntity, AggregateCountResult> .Create(new[] { PipelineStageDefinitionBuilder.Count <TEntity>() })); AggregateFacet <TEntity, TEntity> dataFacet = null; stages.Add(PipelineStageDefinitionBuilder.Skip <TEntity>((pageIndex - 1) * requestedItemCount)); stages.Add(PipelineStageDefinitionBuilder.Limit <TEntity>(requestedItemCount)); stages.Add(PipelineStageDefinitionBuilder.Project(projectionDefinition)); dataFacet = AggregateFacet.Create("data", PipelineDefinition <TEntity, TEntity> .Create(stages)); var aggregateFacetResults = await _collection.Aggregate().Match(filter).Facet(countFacat, dataFacet).ToListAsync().ConfigureAwait(false); var count = aggregateFacetResults.First().Facets.First(x => x.Name == "count").Output <AggregateCountResult>()?.FirstOrDefault()?.Count ?? 0; var totalPages = (int)Math.Ceiling((double)count / requestedItemCount); var data = aggregateFacetResults.First().Facets.First(x => x.Name == "data").Output <TEntity>().ToList(); return(data, totalPages, (int)count); }
/// <summary> /// Appends a project stage to the pipeline. /// </summary> /// <typeparam name="TResult">The type of the result.</typeparam> /// <typeparam name="TNewResult">The type of the new result.</typeparam> /// <param name="aggregate">The aggregate.</param> /// <param name="projection">The projection.</param> /// <returns> /// The fluent aggregate interface. /// </returns> public static IAggregateFluent <TNewResult> Project <TResult, TNewResult>(this IAggregateFluent <TResult> aggregate, Expression <Func <TResult, TNewResult> > projection) { Ensure.IsNotNull(aggregate, nameof(aggregate)); return(aggregate.AppendStage(PipelineStageDefinitionBuilder.Project(projection))); }
/// <summary> /// Appends a project stage to the pipeline. /// </summary> /// <typeparam name="TResult">The type of the result.</typeparam> /// <param name="aggregate">The aggregate.</param> /// <param name="projection">The projection.</param> /// <returns> /// The fluent aggregate interface. /// </returns> public static IAggregateFluent <BsonDocument> Project <TResult>(this IAggregateFluent <TResult> aggregate, ProjectionDefinition <TResult, BsonDocument> projection) { Ensure.IsNotNull(aggregate, nameof(aggregate)); return(aggregate.AppendStage(PipelineStageDefinitionBuilder.Project(projection))); }
private IAggregateFluent <ClothKind> GetAggregationFluentForAggregation(bool includeDeleted = false, FilterDefinition <ClothKind> filter = null, FilterDefinition <Order> filterOrder = null) { var instancesProjectDef = @"{ ClothKind : '$Instances.ClothKind', Amount: '$Instances.Amount' }"; PipelineDefinition <Order, BsonDocument> innerpipeline = PipelineDefinition <Order, BsonDocument> .Create(new IPipelineStageDefinition[] { PipelineStageDefinitionBuilder.Match(filterOrder ?? Builders <Order> .Filter.Empty), PipelineStageDefinitionBuilder.Unwind <Order>("Instances"), PipelineStageDefinitionBuilder.Project <BsonDocument>(instancesProjectDef), PipelineStageDefinitionBuilder.Match <BsonDocument>(new BsonDocument("$expr", new BsonDocument("$eq", new BsonArray { "$ClothKind", "$$kindid" }))), }); var groupDef = @"{ _id: ""$_id"", Name :{ $first: ""$Name""}, MeasureKind: { $first:""$MeasureKind""}, Price :{ $first: ""$Price""}, Parent:{$first:""$Parent""}, Count: { $sum:""$ClothInstances.Amount"" }, SumPrice:{ $sum: {$multiply : [""$Price"", ""$ClothInstances.Amount""]} } }"; var projectDef = @"{ Name: '$Name', MeasureKind: '$MeasureKind', Price : '$Price', Parent : '$Parent', Count : '$Count', SumPrice: '$SumPrice', ChildrenCount : {$size: '$Children'} }"; var aggregateUnwindOptions = new AggregateUnwindOptions <BsonDocument> { PreserveNullAndEmptyArrays = true }; return(base.GetAggregationFluent(includeDeleted, filter) .Lookup <Order, BsonDocument, IList <BsonDocument>, ClothKind>( this.Collection.Database.GetCollection <Order>("orders"), new BsonDocument("kindid", "$_id"), innerpipeline, "ClothInstances") .Unwind("ClothInstances", aggregateUnwindOptions) .Group(groupDef) .Lookup("clothkinds", "_id", "Parent", "Children") .Project(projectDef) .As <ClothKind>() .SortBy(x => x.Id)); }