public void ChangeStream_should_return_the_expected_result_when_options_isNull() { ChangeStreamStageOptions options = null; var result = PipelineStageDefinitionBuilder.ChangeStream <BsonDocument>(options); var stage = RenderStage(result); stage.Document.Should().Be("{ $changeStream : { } }"); }
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}") }))); } }
/// <summary> /// Appends a $bucketAuto stage to the pipeline. /// </summary> /// <typeparam name="TResult">The type of the result.</typeparam> /// <typeparam name="TValue">The type of the value.</typeparam> /// <typeparam name="TNewResult">The type of the new result.</typeparam> /// <param name="aggregate">The aggregate.</param> /// <param name="groupBy">The expression providing the value to group by.</param> /// <param name="buckets">The number of buckets.</param> /// <param name="output">The output projection.</param> /// <param name="options">The options (optional).</param> /// <returns>The fluent aggregate interface.</returns> public static IAggregateFluent <TNewResult> BucketAuto <TResult, TValue, TNewResult>( this IAggregateFluent <TResult> aggregate, Expression <Func <TResult, TValue> > groupBy, int buckets, Expression <Func <IGrouping <TValue, TResult>, TNewResult> > output, AggregateBucketAutoOptions options = null) { Ensure.IsNotNull(aggregate, nameof(aggregate)); return(aggregate.AppendStage(PipelineStageDefinitionBuilder.BucketAuto(groupBy, buckets, output, options))); }
/// <summary> /// Appends a $bucket stage to the pipeline. /// </summary> /// <typeparam name="TResult">The type of the result.</typeparam> /// <typeparam name="TValue">The type of the value.</typeparam> /// <typeparam name="TNewResult">The type of the new result.</typeparam> /// <param name="aggregate">The aggregate.</param> /// <param name="groupBy">The expression providing the value to group by.</param> /// <param name="boundaries">The bucket boundaries.</param> /// <param name="output">The output projection.</param> /// <param name="options">The options.</param> /// <returns>The fluent aggregate interface.</returns> public static IAggregateFluent <TNewResult> Bucket <TResult, TValue, TNewResult>( this IAggregateFluent <TResult> aggregate, Expression <Func <TResult, TValue> > groupBy, IEnumerable <TValue> boundaries, Expression <Func <IGrouping <TValue, TResult>, TNewResult> > output, AggregateBucketOptions <TValue> options = null) { Ensure.IsNotNull(aggregate, nameof(aggregate)); return(aggregate.AppendStage(PipelineStageDefinitionBuilder.Bucket(groupBy, boundaries, output, options))); }
public async Task <PaginationData <Post> > GetPostsByTags(IEnumerable <string> tags, Pagination pagination, bool ascending = false) { var filter = Builders <Post> .Filter.AnyIn(a => a.Tags, tags); 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)); }
/// <summary> /// Appends a lookup stage to the pipeline. /// </summary> /// <typeparam name="TResult">The type of the result.</typeparam> /// <typeparam name="TForeignDocument">The type of the foreign collection.</typeparam> /// <typeparam name="TNewResult">The type of the new result.</typeparam> /// <param name="aggregate">The aggregate.</param> /// <param name="foreignCollection">The foreign collection.</param> /// <param name="localField">The local field.</param> /// <param name="foreignField">The foreign field.</param> /// <param name="as">The field in the result to place the foreign matches.</param> /// <param name="options">The options.</param> /// <returns>The fluent aggregate interface.</returns> public static IAggregateFluent <TNewResult> Lookup <TResult, TForeignDocument, TNewResult>( this IAggregateFluent <TResult> aggregate, IMongoCollection <TForeignDocument> foreignCollection, Expression <Func <TResult, object> > localField, Expression <Func <TForeignDocument, object> > foreignField, Expression <Func <TNewResult, object> > @as, AggregateLookupOptions <TForeignDocument, TNewResult> options = null) { Ensure.IsNotNull(aggregate, nameof(aggregate)); return(aggregate.AppendStage(PipelineStageDefinitionBuilder.Lookup(foreignCollection, localField, foreignField, @as, options))); }
/// <summary> /// Appends a $graphLookup stage to the pipeline. /// </summary> /// <typeparam name="TResult">The type of the result.</typeparam> /// <typeparam name="TFrom">The type of the from documents.</typeparam> /// <param name="aggregate">The aggregate.</param> /// <param name="from">The from collection.</param> /// <param name="connectFromField">The connect from field.</param> /// <param name="connectToField">The connect to field.</param> /// <param name="startWith">The start with value.</param> /// <param name="as">The as field.</param> /// <param name="depthField">The depth field.</param> /// <returns>The fluent aggregate interface.</returns> public static IAggregateFluent <BsonDocument> GraphLookup <TResult, TFrom>( this IAggregateFluent <TResult> aggregate, IMongoCollection <TFrom> from, FieldDefinition <TFrom, BsonValue> connectFromField, FieldDefinition <TFrom, BsonValue> connectToField, AggregateExpressionDefinition <TResult, BsonValue> startWith, FieldDefinition <BsonDocument, IEnumerable <BsonDocument> > @as, FieldDefinition <BsonDocument, int> depthField = null) { Ensure.IsNotNull(aggregate, nameof(aggregate)); return(aggregate.AppendStage(PipelineStageDefinitionBuilder.GraphLookup(from, connectFromField, connectToField, startWith, @as, depthField))); }
public void PipelineStageDefinitionBuilder_Group_with_expressions_should_work_with_LINQ2() { var stageDefinition = PipelineStageDefinitionBuilder.Group((BsonDocument x) => 1, x => new { Count = x.Count() }); var stage = Linq3TestHelpers.Render(stageDefinition, BsonDocumentSerializer.Instance, LinqProvider.V2); var expectedStages = new[] { "{ $group : { _id : 1, Count : { $sum : 1 } } }" }; Linq3TestHelpers.AssertStages(new[] { stage }, expectedStages); }
public void PipelineStageDefinitionBuilder_Group_with_projection_to_TOutput_should_work( [Values(LinqProvider.V2, LinqProvider.V3)] LinqProvider linqProvider) { var stageDefinition = PipelineStageDefinitionBuilder.Group <BsonDocument, BsonDocument>("{ _id : 1, Count : { $sum : 1 } }"); var stage = Linq3TestHelpers.Render(stageDefinition, BsonDocumentSerializer.Instance, linqProvider); var expectedStages = new[] { "{ $group : { _id : 1, Count : { $sum : 1 } } }" }; Linq3TestHelpers.AssertStages(new[] { stage }, expectedStages); }
public void Merge_with_default_options_should_return_the_expected_result(string outputDatabaseName, string outputCollectionName, string expectedStage) { var client = DriverTestConfiguration.Client; var outputDatabase = client.GetDatabase(outputDatabaseName); var outputCollection = outputDatabase.GetCollection <BsonDocument>(outputCollectionName); var mergeOptions = new MergeStageOptions <BsonDocument>(); var result = PipelineStageDefinitionBuilder.Merge <BsonDocument, BsonDocument>(outputCollection, mergeOptions); var stage = RenderStage(result); stage.Document.Should().Be(expectedStage); }
/// <summary> /// Appends a $graphLookup stage to the pipeline. /// </summary> /// <typeparam name="TResult">The type of the result.</typeparam> /// <typeparam name="TNewResult">The type of the new result (must be same as TResult with an additional as field).</typeparam> /// <typeparam name="TFrom">The type of the from documents.</typeparam> /// <typeparam name="TConnectFrom">The type of the connect from field (must be either TConnectTo or a type that implements IEnumerable{TConnectTo}).</typeparam> /// <typeparam name="TConnectTo">The type of the connect to field.</typeparam> /// <typeparam name="TStartWith">The type of the start with expression (must be either TConnectTo or a type that implements IEnumerable{TConnectTo}).</typeparam> /// <typeparam name="TAs">The type of the as field.</typeparam> /// <param name="aggregate">The aggregate.</param> /// <param name="from">The from collection.</param> /// <param name="connectFromField">The connect from field.</param> /// <param name="connectToField">The connect to field.</param> /// <param name="startWith">The start with value.</param> /// <param name="as">The as field.</param> /// <param name="options">The options.</param> /// <returns>The fluent aggregate interface.</returns> public static IAggregateFluent <TNewResult> GraphLookup <TResult, TFrom, TConnectFrom, TConnectTo, TStartWith, TAs, TNewResult>( this IAggregateFluent <TResult> aggregate, IMongoCollection <TFrom> from, Expression <Func <TFrom, TConnectFrom> > connectFromField, Expression <Func <TFrom, TConnectTo> > connectToField, Expression <Func <TResult, TStartWith> > startWith, Expression <Func <TNewResult, TAs> > @as, AggregateGraphLookupOptions <TFrom, TFrom, TNewResult> options = null) where TAs : IEnumerable <TFrom> { Ensure.IsNotNull(aggregate, nameof(aggregate)); return(aggregate.AppendStage(PipelineStageDefinitionBuilder.GraphLookup(from, connectFromField, connectToField, startWith, @as, options, aggregate.Options?.TranslationOptions))); }
public void ChangeStream_with_allChangesForCluster_should_return_the_expected_result(bool?allChangesForCluster, string expectedStage) { var options = new ChangeStreamStageOptions { AllChangesForCluster = allChangesForCluster }; var result = PipelineStageDefinitionBuilder.ChangeStream <BsonDocument>(options); var stage = RenderStage(result); stage.Document.Should().Be(expectedStage); }
/// <summary> /// Appends a group stage to the pipeline. /// </summary> /// <typeparam name="TResult">The type of the result.</typeparam> /// <typeparam name="TKey">The type of the key.</typeparam> /// <typeparam name="TNewResult">The type of the new result.</typeparam> /// <param name="aggregate">The aggregate.</param> /// <param name="id">The id.</param> /// <param name="group">The group projection.</param> /// <returns> /// The fluent aggregate interface. /// </returns> public static IAggregateFluent <TNewResult> Group <TResult, TKey, TNewResult>(this IAggregateFluent <TResult> aggregate, Expression <Func <TResult, TKey> > id, Expression <Func <IGrouping <TKey, TResult>, TNewResult> > group) { Ensure.IsNotNull(aggregate, nameof(aggregate)); if (aggregate.Database.Client.Settings.LinqProvider == LinqProvider.V2) { return(aggregate.AppendStage(PipelineStageDefinitionBuilder.Group(id, group))); } else { var(groupStage, projectStage) = PipelineStageDefinitionBuilder.GroupForLinq3(id, group); return(aggregate.AppendStage(groupStage).AppendStage(projectStage)); } }
public void ChangeStream_with_fullDocument_should_return_the_expected_result(ChangeStreamFullDocumentOption fullDocument, string expectedStage) { var options = new ChangeStreamStageOptions { FullDocument = fullDocument }; var result = PipelineStageDefinitionBuilder.ChangeStream <BsonDocument>(options); var stage = RenderStage(result); stage.Document.Should().Be(expectedStage); }
/// <summary> /// Appends a lookup stage to the pipeline. /// </summary> /// <typeparam name="TResult">The type of the result.</typeparam> /// <param name="aggregate">The aggregate.</param> /// <param name="foreignCollectionName">Name of the foreign collection.</param> /// <param name="localField">The local field.</param> /// <param name="foreignField">The foreign field.</param> /// <param name="as">The field in the result to place the foreign matches.</param> /// <returns>The fluent aggregate interface.</returns> public static IAggregateFluent <BsonDocument> Lookup <TResult>( this IAggregateFluent <TResult> aggregate, string foreignCollectionName, FieldDefinition <TResult> localField, FieldDefinition <BsonDocument> foreignField, FieldDefinition <BsonDocument> @as) { Ensure.IsNotNull(aggregate, nameof(aggregate)); Ensure.IsNotNull(foreignCollectionName, nameof(foreignCollectionName)); var foreignCollection = aggregate.Database.GetCollection <BsonDocument>(foreignCollectionName); return(aggregate.AppendStage(PipelineStageDefinitionBuilder.Lookup(foreignCollection, localField, foreignField, @as))); }
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); }
public void ChangeStream_with_startAtOperationTime_should_return_the_expected_result(int?t, int?i, string expectedStage) { var startAtOperationTime = t.HasValue ? new BsonTimestamp(t.Value, i.Value) : null; var options = new ChangeStreamStageOptions { StartAtOperationTime = startAtOperationTime }; var result = PipelineStageDefinitionBuilder.ChangeStream <BsonDocument>(options); var stage = RenderStage(result); stage.Document.Should().Be(expectedStage); }
public void ChangeStream_with_resumeAfter_should_return_the_expected_result(string resumeAfterJson, string expectedStage) { var resumeAfter = resumeAfterJson == null ? null : BsonDocument.Parse(resumeAfterJson); var options = new ChangeStreamStageOptions { ResumeAfter = resumeAfter }; var result = PipelineStageDefinitionBuilder.ChangeStream <BsonDocument>(options); var stage = RenderStage(result); stage.Document.Should().Be(expectedStage); }
public ETTask <List <ComponentWithId> > GetJson(string collectionName, string json, long skip, long limit) { ETTaskCompletionSource <List <ComponentWithId> > tcs = new ETTaskCompletionSource <List <ComponentWithId> >(); PipelineStageDefinition <ComponentWithId, ComponentWithId> _match = PipelineStageDefinitionBuilder.Match <ComponentWithId>(json); PipelineStageDefinition <ComponentWithId, ComponentWithId> _skip = PipelineStageDefinitionBuilder.Skip <ComponentWithId>((int)skip); PipelineStageDefinition <ComponentWithId, ComponentWithId> _limit = PipelineStageDefinitionBuilder.Limit <ComponentWithId>((int)limit); PipelineDefinition <ComponentWithId, ComponentWithId> pipeline = new PipelineStagePipelineDefinition <ComponentWithId, ComponentWithId>( new PipelineStageDefinition <ComponentWithId, ComponentWithId>[] { _match, _skip, _limit }); DBQueryPipelineTask dbQueryPipelineTask = ComponentFactory.Create <DBQueryPipelineTask, string, PipelineDefinition <ComponentWithId, ComponentWithId>, ETTaskCompletionSource <List <ComponentWithId> > > (collectionName, pipeline, tcs); this.tasks[(int)((ulong)dbQueryPipelineTask.Id % taskCount)].Add(dbQueryPipelineTask); return(tcs.Task); }
/// <inheritdoc /> /// <summary> /// Переопределение цепочки для подсчёта стоимости всех заказов и их количества для hf,jnybrf /// </summary> /// <param name="includeDeleted"></param> /// <param name="filter"></param> /// <returns></returns> protected override IAggregateFluent <Employee> GetAggregationFluent(bool includeDeleted = false, FilterDefinition <Employee> filter = null) { //Вложенный pipeline для pipeline-let lookup-а заказов в аналитике филиалов var pipeline = PipelineDefinition <Order, Order> .Create(new[] { PipelineStageDefinitionBuilder.Match <Order>(new BsonDocument("$expr", new BsonDocument("$or", new BsonArray { new BsonDocument("$eq", new BsonArray { "$InCourier", "$$kindid" }), new BsonDocument("$eq", new BsonArray { "$Obtainer", "$$kindid" }), new BsonDocument("$eq", new BsonArray { "$WasherCourier", "$$kindid" }), new BsonDocument("$eq", new BsonArray { "$Distributor", "$$kindid" }), new BsonDocument("$eq", new BsonArray { "$OutCourier", "$$kindid" }) }))) } ); return(base.GetAggregationFluent(includeDeleted, filter) .Lookup <Order, Order, List <Order>, Employee>( this.Collection.Database.GetCollection <Order>("orders"), new BsonDocument("kindid", "$_id"), pipeline, "Orders") .Project <Employee>(ProjectDefinition)); }
public void PipelineStageDefinitionBuilderGroupForLinq3_with_expressions_should_work_with_LINQ3() { var(groupStageDefinition, projectStageDefinition) = PipelineStageDefinitionBuilder.GroupForLinq3((BsonDocument x) => 1, x => new { Count = x.Count() }); var groupStage = Linq3TestHelpers.Render(groupStageDefinition, BsonDocumentSerializer.Instance, LinqProvider.V3); var groupingSerializer = new IGroupingSerializer <int, BsonDocument>(new Int32Serializer(), BsonDocumentSerializer.Instance); var projectStage = Linq3TestHelpers.Render(projectStageDefinition, groupingSerializer, LinqProvider.V3); var expectedStages = new[] { "{ $group : { _id : 1, __agg0 : { $sum : 1 } } }", "{ $project : { Count : '$__agg0', _id : 0 } }" }; Linq3TestHelpers.AssertStages(new[] { groupStage, projectStage }, expectedStages); }
public void ChangeStream_with_startAfter_should_return_the_expected_result(string content, string expectedStage) { var startAfter = content != null?BsonDocument.Parse(content) : null; var options = new ChangeStreamStageOptions { StartAfter = startAfter }; var result = PipelineStageDefinitionBuilder.ChangeStream <BsonDocument>(options); var stage = RenderStage(result); stage.Document.Should().Be(expectedStage); }
public void Merge_with_OnFieldNames_should_return_the_expected_result(string fieldNames, string expectedStage) { var client = DriverTestConfiguration.Client; var outputDatabase = client.GetDatabase("database"); var outputCollection = outputDatabase.GetCollection <BsonDocument>("collection"); var mergeOptions = new MergeStageOptions <BsonDocument> { OnFieldNames = fieldNames.Split(',') }; var result = PipelineStageDefinitionBuilder.Merge <BsonDocument, BsonDocument>(outputCollection, mergeOptions); var stage = RenderStage(result); stage.Document.Should().Be(expectedStage); }
/// <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 override IOrderedAggregateFluent <TResult> ThenBy(SortDefinition <TResult> newSort) { Ensure.IsNotNull(newSort, nameof(newSort)); var stages = _pipeline.Stages.ToList(); var oldSortStage = (SortPipelineStageDefinition <TResult>)stages[stages.Count - 1]; var oldSort = oldSortStage.Sort; var combinedSort = Builders <TResult> .Sort.Combine(oldSort, newSort); var combinedSortStage = PipelineStageDefinitionBuilder.Sort(combinedSort); stages[stages.Count - 1] = combinedSortStage; var newPipeline = new PipelineStagePipelineDefinition <TDocument, TResult>(stages); return((IOrderedAggregateFluent <TResult>)WithPipeline(newPipeline)); }
public void Merge_with_WhenNotMatched_should_return_the_expected_result(MergeStageWhenNotMatched whenNotMatched, string expectedStage) { var client = DriverTestConfiguration.Client; var outputDatabase = client.GetDatabase("database"); var outputCollection = outputDatabase.GetCollection <BsonDocument>("collection"); var mergeOptions = new MergeStageOptions <BsonDocument> { WhenNotMatched = whenNotMatched }; var result = PipelineStageDefinitionBuilder.Merge <BsonDocument, BsonDocument>(outputCollection, mergeOptions); var stage = RenderStage(result); stage.Document.Should().Be(expectedStage); }
/// <summary> /// Appends a lookup stage to the pipeline. /// </summary> /// <typeparam name="TResult">The type of the result.</typeparam> /// <param name="aggregate">The aggregate.</param> /// <param name="foreignCollection">The foreign collection.</param> /// <param name="let">The "let" definition.</param> /// <param name="lookupPipeline">The lookup pipeline.</param> /// <param name="as">The as field in the result in which to place the results of the lookup pipeline.</param> /// <returns>The fluent aggregate interface.</returns> public static IAggregateFluent <BsonDocument> Lookup <TResult>( this IAggregateFluent <TResult> aggregate, IMongoCollection <BsonDocument> foreignCollection, BsonDocument let, PipelineDefinition <BsonDocument, BsonDocument> lookupPipeline, FieldDefinition <BsonDocument, IEnumerable <BsonDocument> > @as) { Ensure.IsNotNull(aggregate, nameof(aggregate)); Ensure.IsNotNull(foreignCollection, nameof(foreignCollection)); return(aggregate.AppendStage(PipelineStageDefinitionBuilder.Lookup <TResult, BsonDocument, BsonDocument, IEnumerable <BsonDocument>, BsonDocument>( foreignCollection, let, lookupPipeline, @as))); }
/// <summary> /// Appends a lookup stage to the pipeline. /// </summary> /// <typeparam name="TResult">The type of the result.</typeparam> /// <typeparam name="TForeignDocument">The type of the foreign collection documents.</typeparam> /// <typeparam name="TAsElement">The type of the as field elements.</typeparam> /// <typeparam name="TAs">The type of the as field.</typeparam> /// <typeparam name="TNewResult">The type of the new result.</typeparam> /// <param name="aggregate">The aggregate.</param> /// <param name="foreignCollection">The foreign collection.</param> /// <param name="let">The "let" definition.</param> /// <param name="lookupPipeline">The lookup pipeline.</param> /// <param name="as">The as field in <typeparamref name="TNewResult" /> in which to place the results of the lookup pipeline.</param> /// <param name="options">The options.</param> /// <returns>The fluent aggregate interface.</returns> public static IAggregateFluent <TNewResult> Lookup <TResult, TForeignDocument, TAsElement, TAs, TNewResult>( this IAggregateFluent <TResult> aggregate, IMongoCollection <TForeignDocument> foreignCollection, BsonDocument let, PipelineDefinition <TForeignDocument, TAsElement> lookupPipeline, Expression <Func <TNewResult, TAs> > @as, AggregateLookupOptions <TForeignDocument, TNewResult> options = null) where TAs : IEnumerable <TAsElement> { Ensure.IsNotNull(aggregate, nameof(aggregate)); return(aggregate.AppendStage(PipelineStageDefinitionBuilder.Lookup <TResult, TForeignDocument, TAsElement, TAs, TNewResult>( foreignCollection, let, lookupPipeline, @as, options))); }
private static IEnumerable <PipelineStageDefinition <TDocument, TDocument> > GetPipelineDefinitions <TDocument>( FilterDefinition <TDocument> filterQuery, SortDefinition <TDocument> sortQuery, int pageIndex, int pageSize) { yield return(PipelineStageDefinitionBuilder.Match(filterQuery)); if (sortQuery != null) { yield return(PipelineStageDefinitionBuilder.Sort(sortQuery)); } yield return(PipelineStageDefinitionBuilder.Skip <TDocument>((pageIndex - 1) * pageSize)); yield return(PipelineStageDefinitionBuilder.Limit <TDocument>(pageSize)); }
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); } }