public void Facet_with_1_facet_should_return_expected_result() { RequireServer.Check(); EnsureTestData(); var collection = __database.GetCollection <BsonDocument>(__collectionNamespace.CollectionName); var subject = collection.Aggregate(); var name1 = "categorizedByTags"; var pipeline1 = PipelineDefinition <BsonDocument, BsonDocument> .Create( "{ $unwind : \"$tags\" }", "{ $sortByCount : \"$tags\" }"); var facet1 = AggregateFacet.Create(name1, pipeline1); var result = subject.Facet(facet1).Single(); result.Facets.Select(f => f.Name).Should().Equal("categorizedByTags"); result.Facets[0].Output <BsonDocument>().Should().BeEquivalentTo( BsonDocument.Parse("{ _id: 'Expressionism', count: 2 }"), BsonDocument.Parse("{ _id: 'painting', count: 2 }"), BsonDocument.Parse("{ _id: 'ukiyo-e', count: 1 }"), BsonDocument.Parse("{ _id: 'woodblock', count: 1 }"), BsonDocument.Parse("{ _id: 'Surrealism', count: 1 }"), BsonDocument.Parse("{ _id: 'woodcut', count: 1 }"), BsonDocument.Parse("{ _id: 'oil', count: 1 }"), BsonDocument.Parse("{ _id: 'satire', count: 1 }"), BsonDocument.Parse("{ _id: 'caricature', count: 1 }")); }
/// <summary> /// Get page of category settings /// </summary> /// <param name="pageIndex">0-based page index</param> /// <param name="pageSize"></param> /// <param name="descending"></param> /// <returns></returns> public virtual async Task <TotalResult <List <TCategory> > > Find( int pageIndex, int pageSize, bool descending) { //select categories var pipeline = new EmptyPipelineDefinition <TDeliveryType>(); var pipeline2 = pipeline.Unwind(x => x.SubscriberCategorySettings) .As <TDeliveryType, BsonDocument, TDeliveryType>(); var pipeline3 = pipeline2.ReplaceRoot(x => x.SubscriberCategorySettings) .As <TDeliveryType, List <TCategory>, TCategory>(); //count total categories var countPipeline = new EmptyPipelineDefinition <TCategory>().Count(); var countFacetStage = AggregateFacet.Create("count", countPipeline); //limit page of categories var limitPipeline = new EmptyPipelineDefinition <TCategory>() .As <TCategory, TCategory, TCategory>(); var sort = Builders <TCategory> .Sort.Combine(); sort = descending ? sort.Descending(x => x.SubscriberCategorySettingsId) : sort.Ascending(x => x.SubscriberCategorySettingsId); limitPipeline = limitPipeline.Sort(sort); int skip = MongoDbPageNumbers.ToSkipNumber(pageIndex, pageSize); limitPipeline = limitPipeline.Skip(skip); limitPipeline = limitPipeline.Limit(pageSize); var dataFacetStage = AggregateFacet.Create("data", limitPipeline); //combine facets var pipeline4 = pipeline3.Facet(new AggregateFacet <TCategory>[] { countFacetStage, dataFacetStage }); //query IAsyncCursor <AggregateFacetResults> categorySettings = await _collectionFactory .GetCollection <TDeliveryType>() .AggregateAsync(pipeline4, new AggregateOptions()) .ConfigureAwait(false); List <AggregateFacetResults> aggregateFacetResults = await categorySettings .ToListAsync() .ConfigureAwait(false); AggregateFacetResult countFacetResult = aggregateFacetResults[0].Facets .First(x => x.Name == "count"); AggregateFacetResult dataFacetResult = aggregateFacetResults[0].Facets .First(x => x.Name == "data"); var count = countFacetResult.Output <AggregateCountResult>(); var categories = dataFacetResult.Output <TCategory>(); return(new TotalResult <List <TCategory> >( categories.ToList(), count.Count)); }
public void Facet_with_1_facet_should_add_the_expected_stage() { var collection = __database.GetCollection <BsonDocument>(__collectionNamespace.CollectionName); var subject = collection.Aggregate(); var name1 = "categorizedByTags"; var pipeline1 = PipelineDefinition <BsonDocument, BsonDocument> .Create( "{ $unwind : \"$tags\" }", "{ $sortByCount : \"$tags\" }"); var facet1 = AggregateFacet.Create(name1, pipeline1); var result = subject.Facet(facet1); var stage = result.Stages.Single(); var renderedStage = stage.Render(BsonDocumentSerializer.Instance, BsonSerializer.SerializerRegistry); renderedStage.Document.Should().Be( @"{ $facet : { categorizedByTags : [ { $unwind : '$tags' }, { $sortByCount : '$tags' } ] } }"); }
public async Task <PaginationData <Post> > GetPostsByBlogIdAndPaginationAsync( string blogId, Pagination pagination, bool ascending = false) { var filter = Builders <Post> .Filter.Eq(a => a.BlogId, blogId); var aggregateFluent = Collection.Aggregate(); var totalFacet = AggregateFacet.Create("total", PipelineDefinition <Post, AggregateCountResult> .Create(new[] { PipelineStageDefinitionBuilder.Count <Post>() })); AggregateFacet <Post, Post> dataFacet; if (ascending) { dataFacet = AggregateFacet.Create("data", PipelineDefinition <Post, Post> .Create(new[] { PipelineStageDefinitionBuilder.Sort(Builders <Post> .Sort.Ascending(x => x.CreatedDate)), PipelineStageDefinitionBuilder.Skip <Post>(pagination.NumberPerPage * (pagination.CurrentPage - 1)), PipelineStageDefinitionBuilder.Limit <Post>(pagination.NumberPerPage), })); } else { dataFacet = AggregateFacet.Create("data", PipelineDefinition <Post, Post> .Create(new[] { PipelineStageDefinitionBuilder.Sort(Builders <Post> .Sort.Descending(x => x.CreatedDate)), PipelineStageDefinitionBuilder.Skip <Post>(pagination.NumberPerPage * (pagination.CurrentPage - 1)), PipelineStageDefinitionBuilder.Limit <Post>(pagination.NumberPerPage), })); } var aggregation = await aggregateFluent .Match(filter) .Facet(totalFacet, dataFacet) .ToListAsync(); var total = aggregation .First() .Facets.First(a => a.Name == "total") .Output <AggregateCountResult>() .First() .Count; var data = aggregation .First() .Facets.First(a => a.Name == "data") .Output <Post>(); return(new PaginationData <Post>(data, total, pagination.CurrentPage, pagination.NumberPerPage, pagination.MaximumPage)); }
public void Facet_typed_with_2_facets_should_return_expected_result() { RequireServer.Check(); EnsureTestData(); var collection = __database.GetCollection <Exhibit>(__collectionNamespace.CollectionName); var subject = collection.Aggregate(); var name1 = "categorizedByTags"; var pipeline1 = PipelineDefinition <Exhibit, CategorizedByTag> .Create( "{ $unwind : \"$tags\" }", "{ $sortByCount : \"$tags\" }"); var facet1 = AggregateFacet.Create(name1, pipeline1); var name2 = "categorizedByYears"; var pipeline2 = PipelineDefinition <Exhibit, CategorizedByYear> .Create( "{ $match : { year : { $exists : 1 } } }", "{ $bucket : { groupBy : \"$year\", boundaries: [ 1900, 1920, 1950 ] } }"); var facet2 = AggregateFacet.Create(name2, pipeline2); var result = subject.Facet <Exhibit, CategorizedByTagsAndYearsResults>(facet1, facet2).Single(); result.CategorizedByTags.WithComparer(new CategorizedByTagComparer()).Should().BeEquivalentTo( new CategorizedByTag { Id = "Expressionism", Count = 2 }, new CategorizedByTag { Id = "painting", Count = 2 }, new CategorizedByTag { Id = "ukiyo-e", Count = 1 }, new CategorizedByTag { Id = "woodblock", Count = 1 }, new CategorizedByTag { Id = "Surrealism", Count = 1 }, new CategorizedByTag { Id = "woodcut", Count = 1 }, new CategorizedByTag { Id = "oil", Count = 1 }, new CategorizedByTag { Id = "satire", Count = 1 }, new CategorizedByTag { Id = "caricature", Count = 1 }); result.CategorizedByYears.WithComparer(new CategorizedByYearComparer()).Should().BeEquivalentTo( new CategorizedByYear { Id = 1900, Count = 1 }, new CategorizedByYear { Id = 1920, Count = 2 }); }
private IEnumerable <AggregateFacet <Recipe, AggregateSortByCountResult <string> > > CreateFacet() { foreach (var facet in _facets) { yield return(AggregateFacet.Create(facet.Replace(".", "_"), PipelineDefinition <Recipe, AggregateSortByCountResult <string> > .Create(new[] { PipelineStageDefinitionBuilder.SortByCount <Recipe, string>($"${facet}") }))); } }
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 entity count. /// </summary> /// <returns></returns> public async Task <int> GetCountAsync(Expression <Func <TEntity, bool> > filterExpression = null) { var filter = filterExpression ?? Builders <TEntity> .Filter.Empty; var countFacet = AggregateFacet.Create("totalDataCount", PipelineDefinition <TEntity, AggregateCountResult> .Create(new[] { PipelineStageDefinitionBuilder.Count <TEntity>() })); var aggregateFacetResult = await _collection.Aggregate().Match(filter).Facet(countFacet).ToListAsync().ConfigureAwait(false); var count = aggregateFacetResult.First().Facets.First(x => x.Name == "totalDataCount").Output <AggregateCountResult>()?.FirstOrDefault()?.Count ?? 0; return((int)count); }
public void Facet_typed_with_3_facets_should_add_the_expected_stage() { var collection = __database.GetCollection <Exhibit>(__collectionNamespace.CollectionName); var subject = collection.Aggregate(); var name1 = "categorizedByTags"; var pipeline1 = PipelineDefinition <Exhibit, CategorizedByTag> .Create( "{ $unwind : \"$tags\" }", "{ $sortByCount : \"$tags\" }"); var facet1 = AggregateFacet.Create(name1, pipeline1); var name2 = "categorizedByYears"; var pipeline2 = PipelineDefinition <Exhibit, CategorizedByYear> .Create( "{ $match : { year : { $exists : 1 } } }", "{ $bucket : { groupBy : \"$year\", boundaries: [ 1900, 1920, 1950 ] } }"); var facet2 = AggregateFacet.Create(name2, pipeline2); var name3 = "categorizedByYears(Auto)"; var pipeline3 = PipelineDefinition <Exhibit, CategorizedByYearAuto> .Create( "{ $bucketAuto : { groupBy: '$year', buckets: 4 } }"); var facet3 = AggregateFacet.Create(name3, pipeline3); var result = subject.Facet <Exhibit, CategorizedByTagsAndYearsAndYearsAutoResults>(facet1, facet2, facet3); var stage = result.Stages.Single(); var serializerRegistry = BsonSerializer.SerializerRegistry; var inputSerializer = serializerRegistry.GetSerializer <Exhibit>(); var renderedStage = stage.Render(inputSerializer, serializerRegistry); renderedStage.Document.Should().Be( @"{ $facet : { categorizedByTags : [ { $unwind : '$tags' }, { $sortByCount : '$tags' } ], categorizedByYears: [ { $match : { year : { $exists : 1 } } }, { $bucket : { groupBy : '$year', boundaries: [ 1900, 1920, 1950 ] } } ], 'categorizedByYears(Auto)': [ { $bucketAuto : { groupBy: '$year', buckets: 4 } } ] } }"); }
public void Facet_with_3_facets_should_return_expected_result() { RequireServer.Check(); EnsureTestData(); var collection = __database.GetCollection <BsonDocument>(__collectionNamespace.CollectionName); var subject = collection.Aggregate(); var name1 = "categorizedByTags"; var pipeline1 = PipelineDefinition <BsonDocument, BsonDocument> .Create( "{ $unwind : \"$tags\" }", "{ $sortByCount : \"$tags\" }"); var name2 = "categorizedByYears"; var pipeline2 = PipelineDefinition <BsonDocument, BsonDocument> .Create( "{ $match : { year : { $exists : 1 } } }", "{ $bucket : { groupBy : \"$year\", boundaries: [ 1900, 1920, 1950 ] } }"); var name3 = "categorizedByYears(Auto)"; var pipeline3 = PipelineDefinition <BsonDocument, BsonDocument> .Create( "{ $bucketAuto : { groupBy: '$year', buckets: 4 } }"); var facet1 = AggregateFacet.Create(name1, pipeline1); var facet2 = AggregateFacet.Create(name2, pipeline2); var facet3 = AggregateFacet.Create(name3, pipeline3); var result = subject.Facet(facet1, facet2, facet3).Single(); result.Facets.Select(f => f.Name).Should().Equal("categorizedByTags", "categorizedByYears", "categorizedByYears(Auto)"); result.Facets[0].Output <BsonDocument>().Should().BeEquivalentTo( BsonDocument.Parse("{ _id: 'Expressionism', count: 2 }"), BsonDocument.Parse("{ _id: 'painting', count: 2 }"), BsonDocument.Parse("{ _id: 'ukiyo-e', count: 1 }"), BsonDocument.Parse("{ _id: 'woodblock', count: 1 }"), BsonDocument.Parse("{ _id: 'Surrealism', count: 1 }"), BsonDocument.Parse("{ _id: 'woodcut', count: 1 }"), BsonDocument.Parse("{ _id: 'oil', count: 1 }"), BsonDocument.Parse("{ _id: 'satire', count: 1 }"), BsonDocument.Parse("{ _id: 'caricature', count: 1 }")); result.Facets[1].Output <BsonDocument>().Should().BeEquivalentTo( BsonDocument.Parse("{ _id: 1900, count: 1 }"), BsonDocument.Parse("{ _id: 1920, count: 2 }")); result.Facets[2].Output <BsonDocument>().Should().BeEquivalentTo( BsonDocument.Parse("{ _id: { min: null, max: 1902 }, count: 1 }"), BsonDocument.Parse("{ _id: { min: 1902, max: 1925 }, count: 1 }"), BsonDocument.Parse("{ _id: { min: 1925, max: 1926 }, count: 1 }"), BsonDocument.Parse("{ _id: { min: 1926, max: 1926 }, count: 1 }")); }
public async Task <Envelope <T> > GetEnvelopeAsync <T>(IMongoCollection <T> collection, FilterDefinition <T> filter, PageParameters pageParams) { var countFacet = AggregateFacet.Create("count", PipelineDefinition <T, AggregateCountResult> .Create(new[] { PipelineStageDefinitionBuilder.Count <T> () })); var dataFacet = AggregateFacet.Create("data", PipelineDefinition <T, T> .Create(new[] { (pageParams.IsAscend) ? PipelineStageDefinitionBuilder.Sort(Builders <T> .Sort.Ascending(pageParams.SortBy)): PipelineStageDefinitionBuilder.Sort(Builders <T> .Sort.Descending(pageParams.SortBy)), PipelineStageDefinitionBuilder.Skip <T> ((pageParams.PageNumber - 1) * pageParams.PageSize), PipelineStageDefinitionBuilder.Limit <T> (pageParams.PageSize) })); var aggregation = await collection.Aggregate() .Match(filter) .Facet(countFacet, dataFacet) .ToListAsync(); var count = (aggregation.FirstOrDefault() .Facets.FirstOrDefault(x => x.Name == "count") .Output <AggregateCountResult>() .FirstOrDefault() ?? new AggregateCountResult(0)).Count; var data = aggregation.FirstOrDefault() .Facets.FirstOrDefault(x => x.Name == "data") .Output <T>() .ToList(); var totalPages = (int)Match.Ceiling(count / (double)pageParams.PageSize); var hasPreviousPage = pageParams.PageNumber > 1; var hasNextPage = pageParams.PageNumber < totalPages; var envelope = new Envelope <T>() { Items = data, TotalSize = count TotalPages = totalPages HasPreviousPage = HasPreviousPage HasNextPage = hasNextPage }; return(envelope); } }
public void Facet_typed_with_1_facet_should_return_expected_result() { RequireServer.Check(); EnsureTestData(); var collection = __database.GetCollection <Exhibit>(__collectionNamespace.CollectionName); var subject = collection.Aggregate(); var name1 = "categorizedByTags"; var pipeline1 = PipelineDefinition <Exhibit, CategorizedByTag> .Create( "{ $unwind : \"$tags\" }", "{ $sortByCount : \"$tags\" }"); var facet1 = AggregateFacet.Create(name1, pipeline1); var result = subject.Facet <Exhibit, CategorizedByTagsResults>(facet1).Single(); result.CategorizedByTags.WithComparer(new CategorizedByTagComparer()).Should().BeEquivalentTo( new CategorizedByTag { Id = "Expressionism", Count = 2 }, new CategorizedByTag { Id = "painting", Count = 2 }, new CategorizedByTag { Id = "ukiyo-e", Count = 1 }, new CategorizedByTag { Id = "woodblock", Count = 1 }, new CategorizedByTag { Id = "Surrealism", Count = 1 }, new CategorizedByTag { Id = "woodcut", Count = 1 }, new CategorizedByTag { Id = "oil", Count = 1 }, new CategorizedByTag { Id = "satire", Count = 1 }, new CategorizedByTag { Id = "caricature", Count = 1 }); }
public async Task <Page <TemplateKind> > GetTemplateKindsPage(int page, int pageSize, CancellationToken cancellationToken = default) { var countFacetName = "count"; var entitiesFacetName = "entities"; var countFacet = AggregateFacet.Create(countFacetName, PipelineDefinition <TemplateKind, AggregateCountResult> .Create(new[] { PipelineStageDefinitionBuilder.Count <TemplateKind>(), })); var sortDefinition = Builders <TemplateKind> .Sort.Ascending(x => x.TemplateKindKey); var entitiesFacet = AggregateFacet.Create(entitiesFacetName, PipelineDefinition <TemplateKind, TemplateKind> .Create(new[] { PipelineStageDefinitionBuilder.Sort(sortDefinition), PipelineStageDefinitionBuilder.Skip <TemplateKind>((page - 1) * pageSize), PipelineStageDefinitionBuilder.Limit <TemplateKind>(pageSize), })); var aggregation = await _collection.Aggregate() .Facet(countFacet, entitiesFacet) .ToListAsync(cancellationToken); var data = aggregation.First() .Facets.First(x => x.Name == entitiesFacetName) .Output <TemplateKind>(); var countOutput = aggregation.First() .Facets.First(x => x.Name == countFacetName) .Output <AggregateCountResult>(); long count = 0; if (countOutput.Any()) { count = countOutput.First() .Count; } return(new Page <TemplateKind>(count, data)); }
/// <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()); }
public static async Task <PagedCollection <T> > ApplyOData <T>(this IMongoCollection <T> collection, IODataQuery query) { var page = 1; var skip = query.Skip.Normalize(0); var limit = query.Limit.Normalize(10, 1000); var countFacet = AggregateFacet.Create("count", PipelineDefinition <T, AggregateCountResult> .Create(new[] { PipelineStageDefinitionBuilder.Count <T>() })); var sort = CreateODataSort <T>(query, false); var filter = CreateODataFilter <T>(query, false); var dataFacet = AggregateFacet.Create("data", PipelineDefinition <T, T> .Create(new [] { PipelineStageDefinitionBuilder.Sort(sort), PipelineStageDefinitionBuilder.Skip <T>(skip), PipelineStageDefinitionBuilder.Limit <T>(limit), })); var aggregation = await collection.Aggregate() .Match(filter) .Facet(countFacet, dataFacet) .ToListAsync(); var count = aggregation.First() .Facets.First(x => x.Name == "count") .Output <AggregateCountResult>() .First() .Count; int totalPages = (int)(count / limit); var data = aggregation.First() .Facets.First(x => x.Name == "data") .Output <T>(); return(PagedCollection <T> .Create(data, page, limit, totalPages, count)); }
public static async Task <IReadOnlyList <TDocument> > AggregateByPage <TDocument>( this IMongoCollection <TDocument> collection, FilterDefinition <TDocument> filterDefinition, SortDefinition <TDocument> sortDefinition, int page, int pageSize) { var countFacet = AggregateFacet.Create("count", PipelineDefinition <TDocument, AggregateCountResult> .Create(new[] { PipelineStageDefinitionBuilder.Count <TDocument>() })); var dataFacet = AggregateFacet.Create("data", PipelineDefinition <TDocument, TDocument> .Create(new[] { PipelineStageDefinitionBuilder.Sort(sortDefinition), PipelineStageDefinitionBuilder.Skip <TDocument>((page - 1) * pageSize), PipelineStageDefinitionBuilder.Limit <TDocument>(pageSize), })); var aggregation = await collection.Aggregate() .Match(filterDefinition) .Facet(countFacet, dataFacet) .ToListAsync(); var count = aggregation.First() .Facets.First(x => x.Name == "count") .Output <AggregateCountResult>() .First() .Count; var totalPages = (int)Math.Ceiling((double)count / pageSize); var data = aggregation.First() .Facets.First(x => x.Name == "data") .Output <TDocument>(); return(data); }
public async Task <ServiceResult <SongPagination> > RetreiveSongOfArtist(string artistName, int pageSize, int page) { var filter = Builders <Song> .Filter.Eq(s => s.ArtistName, artistName); var countFacet = AggregateFacet.Create("count", PipelineDefinition <Song, AggregateCountResult> .Create(new[] { PipelineStageDefinitionBuilder.Count <Song>() })); var paginationFacet = AggregateFacet.Create("pagination", PipelineDefinition <Song, Song> .Create(new[] { PipelineStageDefinitionBuilder.Sort(Builders <Song> .Sort.Ascending(x => x.Title)), PipelineStageDefinitionBuilder.Skip <Song>(pageSize * (page - 1)), PipelineStageDefinitionBuilder.Limit <Song>(pageSize) })); var aggregation = await this.songCollection.Aggregate() .Match(filter) .Facet(countFacet, paginationFacet) .ToListAsync(); long count = aggregation.First() .Facets.First(x => x.Name == "count") .Output <AggregateCountResult>() .First() .Count; var totalPages = Math.Ceiling((decimal)(count / pageSize)); IEnumerable <Song> items = aggregation.First() .Facets.First(f => f.Name == "pagination") .Output <Song>() .ToList(); return(ServiceResult.Succes(new SongPagination { ToTalPages = totalPages, Songs = items })); }
/// <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); }
public void Facet_with_2_facets_should_add_the_expected_stage() { var collection = __database.GetCollection <BsonDocument>(__collectionNamespace.CollectionName); var subject = collection.Aggregate(); var name1 = "categorizedByTags"; var pipeline1 = PipelineDefinition <BsonDocument, BsonDocument> .Create( "{ $unwind : \"$tags\" }", "{ $sortByCount : \"$tags\" }"); var name2 = "categorizedByYears"; var pipeline2 = PipelineDefinition <BsonDocument, BsonDocument> .Create( "{ $match : { year : { $exists : 1 } } }", "{ $bucket : { groupBy : \"$year\", boundaries: [ 1900, 1920, 1950 ] } }"); var facet1 = AggregateFacet.Create(name1, pipeline1); var facet2 = AggregateFacet.Create(name2, pipeline2); var result = subject.Facet(facet1, facet2); var stage = result.Stages.Single(); var renderedStage = stage.Render(BsonDocumentSerializer.Instance, BsonSerializer.SerializerRegistry); renderedStage.Document.Should().Be( @"{ $facet : { categorizedByTags : [ { $unwind : '$tags' }, { $sortByCount : '$tags' } ], categorizedByYears: [ { $match : { year : { $exists : 1 } } }, { $bucket : { groupBy : '$year', boundaries: [ 1900, 1920, 1950 ] } } ] } }"); }
public void Facet_typed_with_3_facets_should_return_expected_result() { RequireServer.Check().Supports(Feature.AggregateFacetStage); EnsureTestData(); var collection = __database.GetCollection <Exhibit>(__collectionNamespace.CollectionName); var subject = collection.Aggregate(); var name1 = "categorizedByTags"; var pipeline1 = PipelineDefinition <Exhibit, CategorizedByTag> .Create( "{ $unwind : \"$tags\" }", "{ $sortByCount : \"$tags\" }"); var facet1 = AggregateFacet.Create(name1, pipeline1); var name2 = "categorizedByYears"; var pipeline2 = PipelineDefinition <Exhibit, CategorizedByYear> .Create( "{ $match : { year : { $exists : 1 } } }", "{ $bucket : { groupBy : \"$year\", boundaries: [ 1900, 1920, 1950 ] } }"); var facet2 = AggregateFacet.Create(name2, pipeline2); var name3 = "categorizedByYears(Auto)"; var pipeline3 = PipelineDefinition <Exhibit, CategorizedByYearAuto> .Create( "{ $bucketAuto : { groupBy: '$year', buckets: 4 } }"); var facet3 = AggregateFacet.Create(name3, pipeline3); var result = subject.Facet <Exhibit, CategorizedByTagsAndYearsAndYearsAutoResults>(facet1, facet2, facet3).Single(); result.CategorizedByTags.WithComparer(new CategorizedByTagComparer()).Should().Equal( new CategorizedByTag { Id = "Expressionism", Count = 2 }, new CategorizedByTag { Id = "painting", Count = 2 }, new CategorizedByTag { Id = "ukiyo-e", Count = 1 }, new CategorizedByTag { Id = "woodblock", Count = 1 }, new CategorizedByTag { Id = "Surrealism", Count = 1 }, new CategorizedByTag { Id = "woodcut", Count = 1 }, new CategorizedByTag { Id = "oil", Count = 1 }, new CategorizedByTag { Id = "satire", Count = 1 }, new CategorizedByTag { Id = "caricature", Count = 1 }); result.CategorizedByYears.WithComparer(new CategorizedByYearComparer()).Should().Equal( new CategorizedByYear { Id = 1900, Count = 1 }, new CategorizedByYear { Id = 1920, Count = 2 }); result.CategorizedByYearsAuto.WithComparer(new CategorizedByYearAutoComparer()).Should().Equal( new CategorizedByYearAuto { Id = new MinMax { Min = null, Max = 1902 }, Count = 1 }, new CategorizedByYearAuto { Id = new MinMax { Min = 1902, Max = 1925 }, Count = 1 }, new CategorizedByYearAuto { Id = new MinMax { Min = 1925, Max = 1926 }, Count = 1 }, new CategorizedByYearAuto { Id = new MinMax { Min = 1926, Max = 1926 }, Count = 1 }); }