示例#1
0
        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 : { } }");
        }
示例#2
0
 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}")
         })));
     }
 }
示例#3
0
 /// <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)));
 }
示例#4
0
 /// <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);
        }
示例#10
0
        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);
        }
示例#11
0
 /// <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)));
 }
示例#12
0
        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));
     }
 }
示例#14
0
        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);
        }
示例#15
0
        /// <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)));
        }
示例#16
0
        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);
        }
示例#17
0
        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);
        }
示例#18
0
        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);
        }
示例#20
0
        /// <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);
        }
示例#22
0
        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);
        }
示例#23
0
        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);
        }
示例#24
0
    /// <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));
        }
示例#26
0
        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);
        }
示例#27
0
 /// <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)));
 }
示例#28
0
 /// <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));
    }
示例#30
0
        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);
        }
    }