Ejemplo n.º 1
0
        public override IAsyncCursor <TResult> Aggregate <TResult>(IClientSessionHandle session, PipelineDefinition <NoPipelineInput, TResult> pipeline, AggregateOptions options, CancellationToken cancellationToken = default(CancellationToken))
        {
            Ensure.IsNotNull(session, nameof(session));
            var renderedPipeline = Ensure.IsNotNull(pipeline, nameof(pipeline)).Render(NoPipelineInputSerializer.Instance, _settings.SerializerRegistry, _linqProvider);

            options = options ?? new AggregateOptions();

            var lastStage     = renderedPipeline.Documents.LastOrDefault();
            var lastStageName = lastStage?.GetElement(0).Name;

            if (lastStage != null && (lastStageName == "$out" || lastStageName == "$merge"))
            {
                var aggregateOperation = CreateAggregateToCollectionOperation(renderedPipeline, options);
                ExecuteWriteOperation(session, aggregateOperation, cancellationToken);

                // we want to delay execution of the find because the user may
                // not want to iterate the results at all...
                var findOperation  = CreateAggregateToCollectionFindOperation(lastStage, renderedPipeline.OutputSerializer, options);
                var forkedSession  = session.Fork();
                var deferredCursor = new DeferredAsyncCursor <TResult>(
                    () => forkedSession.Dispose(),
                    ct => ExecuteReadOperation(forkedSession, findOperation, ReadPreference.Primary, ct),
                    ct => ExecuteReadOperationAsync(forkedSession, findOperation, ReadPreference.Primary, ct));
                return(deferredCursor);
            }
            else
            {
                var aggregateOperation = CreateAggregateOperation(renderedPipeline, options);
                return(ExecuteReadOperation(session, aggregateOperation, cancellationToken));
            }
        }
Ejemplo n.º 2
0
        public override async Task <IAsyncCursor <TResult> > MapReduceAsync <TResult>(BsonJavaScript map, BsonJavaScript reduce, MapReduceOptions <TDocument, TResult> options = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            Ensure.IsNotNull(map, nameof(map));
            Ensure.IsNotNull(reduce, nameof(reduce));
            options = options ?? new MapReduceOptions <TDocument, TResult>();

            var outputOptions    = options.OutputOptions ?? MapReduceOutputOptions.Inline;
            var resultSerializer = ResolveResultSerializer <TResult>(options.ResultSerializer);

            if (outputOptions == MapReduceOutputOptions.Inline)
            {
                var operation = CreateMapReduceOperation(map, reduce, options, resultSerializer);
                return(await ExecuteReadOperationAsync(operation, cancellationToken).ConfigureAwait(false));
            }
            else
            {
                var mapReduceOperation = CreateMapReduceOutputToCollectionOperation(map, reduce, options, outputOptions);
                await ExecuteWriteOperationAsync(mapReduceOperation, cancellationToken).ConfigureAwait(false);

                var findOperation = CreateMapReduceOutputToCollectionFindOperation <TResult>(options, mapReduceOperation.OutputCollectionNamespace, resultSerializer);

                // we want to delay execution of the find because the user may
                // not want to iterate the results at all...
                var deferredCursor = new DeferredAsyncCursor <TResult>(
                    ct => ExecuteReadOperation(findOperation, ReadPreference.Primary, ct),
                    ct => ExecuteReadOperationAsync(findOperation, ReadPreference.Primary, ct));
                return(await Task.FromResult(deferredCursor).ConfigureAwait(false));
            }
        }
Ejemplo n.º 3
0
        // public methods
        public override IAsyncCursor <TResult> Aggregate <TResult>(PipelineDefinition <TDocument, TResult> pipeline, AggregateOptions options, CancellationToken cancellationToken)
        {
            var renderedPipeline = Ensure.IsNotNull(pipeline, nameof(pipeline)).Render(_documentSerializer, _settings.SerializerRegistry);

            options = options ?? new AggregateOptions();

            var last = renderedPipeline.Documents.LastOrDefault();

            if (last != null && last.GetElement(0).Name == "$out")
            {
                var aggregateOperation = CreateAggregateToCollectionOperation(renderedPipeline, options);
                ExecuteWriteOperation(aggregateOperation, cancellationToken);

                // we want to delay execution of the find because the user may
                // not want to iterate the results at all...
                var findOperation  = CreateAggregateToCollectionFindOperation(last, renderedPipeline.OutputSerializer, options);
                var deferredCursor = new DeferredAsyncCursor <TResult>(
                    ct => ExecuteReadOperation(findOperation, ReadPreference.Primary, ct),
                    ct => ExecuteReadOperationAsync(findOperation, ReadPreference.Primary, ct));
                return(deferredCursor);
            }
            else
            {
                var aggregateOperation = CreateAggregateOperation(renderedPipeline, options);
                return(ExecuteReadOperation(aggregateOperation, cancellationToken));
            }
        }
Ejemplo n.º 4
0
        // methods
        public override async Task <IAsyncCursor <TResult> > AggregateAsync <TResult>(PipelineDefinition <TDocument, TResult> pipeline, AggregateOptions options, CancellationToken cancellationToken)
        {
            var renderedPipeline = Ensure.IsNotNull(pipeline, nameof(pipeline)).Render(_documentSerializer, _settings.SerializerRegistry);

            options = options ?? new AggregateOptions();

            var last = renderedPipeline.Documents.LastOrDefault();

            if (last != null && last.GetElement(0).Name == "$out")
            {
                var operation = new AggregateToCollectionOperation(
                    _collectionNamespace,
                    renderedPipeline.Documents,
                    _messageEncoderSettings)
                {
                    AllowDiskUse             = options.AllowDiskUse,
                    BypassDocumentValidation = options.BypassDocumentValidation,
                    MaxTime = options.MaxTime
                };

                await ExecuteWriteOperationAsync(operation, cancellationToken).ConfigureAwait(false);

                var outputCollectionName = last.GetElement(0).Value.AsString;

                var findOperation = new FindOperation <TResult>(
                    new CollectionNamespace(_collectionNamespace.DatabaseNamespace, outputCollectionName),
                    renderedPipeline.OutputSerializer,
                    _messageEncoderSettings)
                {
                    BatchSize = options.BatchSize,
                    MaxTime   = options.MaxTime
                };

                // we want to delay execution of the find because the user may
                // not want to iterate the results at all...
                var deferredCursor = new DeferredAsyncCursor <TResult>(
                    ct => ExecuteReadOperation(findOperation, ReadPreference.Primary, ct),
                    ct => ExecuteReadOperationAsync(findOperation, ReadPreference.Primary, ct));
                return(await Task.FromResult <IAsyncCursor <TResult> >(deferredCursor).ConfigureAwait(false));
            }
            else
            {
                var aggregateOperation = new AggregateOperation <TResult>(
                    _collectionNamespace,
                    renderedPipeline.Documents,
                    renderedPipeline.OutputSerializer,
                    _messageEncoderSettings)
                {
                    AllowDiskUse = options.AllowDiskUse,
                    BatchSize    = options.BatchSize,
                    MaxTime      = options.MaxTime,
                    ReadConcern  = _settings.ReadConcern,
                    UseCursor    = options.UseCursor
                };
                return(await ExecuteReadOperationAsync(aggregateOperation, cancellationToken).ConfigureAwait(false));
            }
        }
        public override async Task <IAsyncCursor <TResult> > MapReduceAsync <TResult>(BsonJavaScript map, BsonJavaScript reduce, MapReduceOptions <TDocument, TResult> options = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            Ensure.IsNotNull(map, "map");
            Ensure.IsNotNull(reduce, "reduce");

            options = options ?? new MapReduceOptions <TDocument, TResult>();
            var outputOptions    = options.OutputOptions ?? MapReduceOutputOptions.Inline;
            var resultSerializer = ResolveResultSerializer <TResult>(options.ResultSerializer);

            if (outputOptions == MapReduceOutputOptions.Inline)
            {
                var operation = new MapReduceOperation <TResult>(
                    _collectionNamespace,
                    map,
                    reduce,
                    resultSerializer,
                    _messageEncoderSettings)
                {
                    Filter           = options.Filter == null ? null : options.Filter.Render(_documentSerializer, _settings.SerializerRegistry),
                    FinalizeFunction = options.Finalize,
                    JavaScriptMode   = options.JavaScriptMode,
                    Limit            = options.Limit,
                    MaxTime          = options.MaxTime,
                    Scope            = options.Scope,
                    Sort             = options.Sort == null ? null : options.Sort.Render(_documentSerializer, _settings.SerializerRegistry),
                    Verbose          = options.Verbose
                };

                return(await ExecuteReadOperation(operation, cancellationToken).ConfigureAwait(false));
            }
            else
            {
                var collectionOutputOptions = (MapReduceOutputOptions.CollectionOutput)outputOptions;
                var databaseNamespace       = collectionOutputOptions.DatabaseName == null ?
                                              _collectionNamespace.DatabaseNamespace :
                                              new DatabaseNamespace(collectionOutputOptions.DatabaseName);
                var outputCollectionNamespace = new CollectionNamespace(databaseNamespace, collectionOutputOptions.CollectionName);

                var operation = new MapReduceOutputToCollectionOperation(
                    _collectionNamespace,
                    outputCollectionNamespace,
                    map,
                    reduce,
                    _messageEncoderSettings)
                {
                    Filter           = options.Filter == null ? null : options.Filter.Render(_documentSerializer, _settings.SerializerRegistry),
                    FinalizeFunction = options.Finalize,
                    JavaScriptMode   = options.JavaScriptMode,
                    Limit            = options.Limit,
                    MaxTime          = options.MaxTime,
                    NonAtomicOutput  = collectionOutputOptions.NonAtomic,
                    Scope            = options.Scope,
                    OutputMode       = collectionOutputOptions.OutputMode,
                    ShardedOutput    = collectionOutputOptions.Sharded,
                    Sort             = options.Sort == null ? null : options.Sort.Render(_documentSerializer, _settings.SerializerRegistry),
                    Verbose          = options.Verbose
                };

                await ExecuteWriteOperation(operation, cancellationToken).ConfigureAwait(false);

                var findOperation = new FindOperation <TResult>(
                    outputCollectionNamespace,
                    resultSerializer,
                    _messageEncoderSettings)
                {
                    MaxTime = options.MaxTime
                };

                // we want to delay execution of the find because the user may
                // not want to iterate the results at all...
                var deferredCursor = new DeferredAsyncCursor <TResult>(ct => ExecuteReadOperation(findOperation, ReadPreference.Primary, ct));
                return(await Task.FromResult(deferredCursor).ConfigureAwait(false));
            }
        }