Search in sources :

Example 1 with AggregationOptions

use of org.springframework.data.mongodb.core.aggregation.AggregationOptions in project spring-data-mongodb by spring-projects.

the class ReactiveMongoTemplate method aggregate.

/**
 * @param aggregation must not be {@literal null}.
 * @param collectionName must not be {@literal null}.
 * @param outputType must not be {@literal null}.
 * @param context can be {@literal null} and will be defaulted to {@link Aggregation#DEFAULT_CONTEXT}.
 * @return never {@literal null}.
 */
protected <O> Flux<O> aggregate(Aggregation aggregation, String collectionName, Class<O> outputType, @Nullable AggregationOperationContext context) {
    Assert.notNull(aggregation, "Aggregation pipeline must not be null!");
    Assert.hasText(collectionName, "Collection name must not be null or empty!");
    Assert.notNull(outputType, "Output type must not be null!");
    AggregationOperationContext rootContext = context == null ? Aggregation.DEFAULT_CONTEXT : context;
    AggregationOptions options = aggregation.getOptions();
    List<Document> pipeline = aggregation.toPipeline(rootContext);
    Assert.isTrue(!options.isExplain(), "Cannot use explain option with streaming!");
    Assert.isNull(options.getCursorBatchSize(), "Cannot use batchSize cursor option with streaming!");
    if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("Streaming aggregation: {} in collection {}", serializeToJsonSafely(pipeline), collectionName);
    }
    ReadDocumentCallback<O> readCallback = new ReadDocumentCallback<>(mongoConverter, outputType, collectionName);
    return execute(collectionName, collection -> aggregateAndMap(collection, pipeline, options, readCallback));
}
Also used : AggregationOptions(org.springframework.data.mongodb.core.aggregation.AggregationOptions) AggregationOperationContext(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) PrefixingDelegatingAggregationOperationContext(org.springframework.data.mongodb.core.aggregation.PrefixingDelegatingAggregationOperationContext) TypeBasedAggregationOperationContext(org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext) Document(org.bson.Document) FullDocument(com.mongodb.client.model.changestream.FullDocument) ReturnDocument(com.mongodb.client.model.ReturnDocument)

Example 2 with AggregationOptions

use of org.springframework.data.mongodb.core.aggregation.AggregationOptions in project spring-data-mongodb by spring-projects.

the class MongoTemplate method doAggregate.

@SuppressWarnings("ConstantConditions")
protected <O> AggregationResults<O> doAggregate(Aggregation aggregation, String collectionName, Class<O> outputType, AggregationOperationContext context) {
    ReadDocumentCallback<O> callback = new ReadDocumentCallback<>(mongoConverter, outputType, collectionName);
    AggregationOptions options = aggregation.getOptions();
    AggregationUtil aggregationUtil = new AggregationUtil(queryMapper, mappingContext);
    if (options.isExplain()) {
        Document command = aggregationUtil.createCommand(collectionName, aggregation, context);
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug(String.format("Executing aggregation: %s", serializeToJsonSafely(command)));
        }
        Document commandResult = executeCommand(command);
        return new AggregationResults<>(commandResult.get("results", new ArrayList<Document>(0)).stream().map(callback::doWith).collect(Collectors.toList()), commandResult);
    }
    List<Document> pipeline = aggregationUtil.createPipeline(aggregation, context);
    if (LOGGER.isDebugEnabled()) {
        LOGGER.debug(String.format("Executing aggregation: %s in collection %s", serializeToJsonSafely(pipeline), collectionName));
    }
    return execute(collectionName, collection -> {
        List<Document> rawResult = new ArrayList<>();
        Class<?> domainType = aggregation instanceof TypedAggregation ? ((TypedAggregation<?>) aggregation).getInputType() : null;
        Optional<Collation> collation = Optionals.firstNonEmpty(options::getCollation, () -> // 
        operations.forType(domainType).getCollation());
        AggregateIterable<Document> aggregateIterable = // 
        collection.aggregate(pipeline, Document.class).collation(// 
        collation.map(Collation::toMongoCollation).orElse(null)).allowDiskUse(options.isAllowDiskUse());
        if (options.getCursorBatchSize() != null) {
            aggregateIterable = aggregateIterable.batchSize(options.getCursorBatchSize());
        }
        options.getComment().ifPresent(aggregateIterable::comment);
        options.getHint().ifPresent(aggregateIterable::hint);
        if (options.hasExecutionTimeLimit()) {
            aggregateIterable = aggregateIterable.maxTime(options.getMaxTime().toMillis(), TimeUnit.MILLISECONDS);
        }
        if (options.isSkipResults()) {
            // toCollection only allowed for $out and $merge if those are the last stages
            if (aggregation.getPipeline().isOutOrMerge()) {
                aggregateIterable.toCollection();
            } else {
                aggregateIterable.first();
            }
            return new AggregationResults<>(Collections.emptyList(), new Document());
        }
        MongoIterable<O> iterable = aggregateIterable.map(val -> {
            rawResult.add(val);
            return callback.doWith(val);
        });
        return new AggregationResults<>(iterable.into(new ArrayList<>()), new Document("results", rawResult).append("ok", 1.0D));
    });
}
Also used : AggregationOptions(org.springframework.data.mongodb.core.aggregation.AggregationOptions) Document(org.bson.Document) Collation(org.springframework.data.mongodb.core.query.Collation) AggregationResults(org.springframework.data.mongodb.core.aggregation.AggregationResults) TypedAggregation(org.springframework.data.mongodb.core.aggregation.TypedAggregation)

Example 3 with AggregationOptions

use of org.springframework.data.mongodb.core.aggregation.AggregationOptions in project spring-data-mongodb by spring-projects.

the class ReactiveMongoTemplate method doAggregate.

protected <O> Flux<O> doAggregate(Aggregation aggregation, String collectionName, @Nullable Class<?> inputType, Class<O> outputType) {
    Assert.notNull(aggregation, "Aggregation pipeline must not be null!");
    Assert.hasText(collectionName, "Collection name must not be null or empty!");
    Assert.notNull(outputType, "Output type must not be null!");
    AggregationOptions options = aggregation.getOptions();
    Assert.isTrue(!options.isExplain(), "Cannot use explain option with streaming!");
    AggregationDefinition ctx = queryOperations.createAggregation(aggregation, inputType);
    if (LOGGER.isDebugEnabled()) {
        LOGGER.debug(String.format("Streaming aggregation: %s in collection %s", serializeToJsonSafely(ctx.getAggregationPipeline()), collectionName));
    }
    ReadDocumentCallback<O> readCallback = new ReadDocumentCallback<>(mongoConverter, outputType, collectionName);
    return execute(collectionName, collection -> aggregateAndMap(collection, ctx.getAggregationPipeline(), ctx.isOutOrMerge(), options, readCallback, ctx.getInputType()));
}
Also used : AggregationOptions(org.springframework.data.mongodb.core.aggregation.AggregationOptions) AggregationDefinition(org.springframework.data.mongodb.core.QueryOperations.AggregationDefinition)

Example 4 with AggregationOptions

use of org.springframework.data.mongodb.core.aggregation.AggregationOptions in project spring-data-mongodb by spring-projects.

the class ReactiveStringBasedAggregation method doExecute.

/*
	 * (non-Javascript)
	 * @see org.springframework.data.mongodb.repository.query.AbstractReactiveMongoQuery#doExecute(org.springframework.data.mongodb.repository.query.ReactiveMongoQueryMethod, org.springframework.data.repository.query.ResultProcessor, org.springframework.data.mongodb.repository.query.ConvertingParameterAccessor, java.lang.Class)
	 */
@Override
protected Publisher<Object> doExecute(ReactiveMongoQueryMethod method, ResultProcessor processor, ConvertingParameterAccessor accessor, Class<?> typeToRead) {
    return computePipeline(accessor).flatMapMany(it -> {
        Class<?> sourceType = method.getDomainClass();
        Class<?> targetType = typeToRead;
        List<AggregationOperation> pipeline = it;
        AggregationUtils.appendSortIfPresent(pipeline, accessor, typeToRead);
        AggregationUtils.appendLimitAndOffsetIfPresent(pipeline, accessor);
        boolean isSimpleReturnType = isSimpleReturnType(typeToRead);
        boolean isRawReturnType = ClassUtils.isAssignable(org.bson.Document.class, typeToRead);
        if (isSimpleReturnType || isRawReturnType) {
            targetType = Document.class;
        }
        AggregationOptions options = computeOptions(method, accessor);
        TypedAggregation<?> aggregation = new TypedAggregation<>(sourceType, pipeline, options);
        Flux<?> flux = reactiveMongoOperations.aggregate(aggregation, targetType);
        if (isSimpleReturnType && !isRawReturnType) {
            flux = flux.handle((item, sink) -> {
                Object result = AggregationUtils.extractSimpleTypeResult((Document) item, typeToRead, mongoConverter);
                if (result != null) {
                    sink.next(result);
                }
            });
        }
        return method.isCollectionQuery() ? flux : flux.next();
    });
}
Also used : Document(org.bson.Document) ResultProcessor(org.springframework.data.repository.query.ResultProcessor) ClassUtils(org.springframework.util.ClassUtils) AggregationOptions(org.springframework.data.mongodb.core.aggregation.AggregationOptions) Publisher(org.reactivestreams.Publisher) TypedAggregation(org.springframework.data.mongodb.core.aggregation.TypedAggregation) Mono(reactor.core.publisher.Mono) AggregationOperation(org.springframework.data.mongodb.core.aggregation.AggregationOperation) MongoConverter(org.springframework.data.mongodb.core.convert.MongoConverter) Aggregation(org.springframework.data.mongodb.core.aggregation.Aggregation) Query(org.springframework.data.mongodb.core.query.Query) ExpressionParser(org.springframework.expression.ExpressionParser) Flux(reactor.core.publisher.Flux) List(java.util.List) ReactiveMongoOperations(org.springframework.data.mongodb.core.ReactiveMongoOperations) MongoSimpleTypes(org.springframework.data.mongodb.core.mapping.MongoSimpleTypes) ReactiveQueryMethodEvaluationContextProvider(org.springframework.data.repository.query.ReactiveQueryMethodEvaluationContextProvider) AggregationOptions(org.springframework.data.mongodb.core.aggregation.AggregationOptions) TypedAggregation(org.springframework.data.mongodb.core.aggregation.TypedAggregation) Document(org.bson.Document) AggregationOperation(org.springframework.data.mongodb.core.aggregation.AggregationOperation)

Example 5 with AggregationOptions

use of org.springframework.data.mongodb.core.aggregation.AggregationOptions in project spring-data-mongodb by spring-projects.

the class ReactiveStringBasedAggregationUnitTests method plainStringAggregationWithSortParameter.

// DATAMONGO-2153
@Test
public void plainStringAggregationWithSortParameter() {
    AggregationInvocation invocation = executeAggregation("plainStringAggregation", Sort.by(Direction.DESC, "lastname"));
    assertThat(inputTypeOf(invocation)).isEqualTo(Person.class);
    assertThat(targetTypeOf(invocation)).isEqualTo(PersonAggregate.class);
    assertThat(pipelineOf(invocation)).containsExactly(GROUP_BY_LASTNAME, SORT);
    AggregationOptions options = invocation.aggregation.getOptions();
    assertThat(options.getComment()).isEmpty();
    assertThat(options.getCursorBatchSize()).isNull();
}
Also used : AggregationOptions(org.springframework.data.mongodb.core.aggregation.AggregationOptions) Test(org.junit.jupiter.api.Test)

Aggregations

AggregationOptions (org.springframework.data.mongodb.core.aggregation.AggregationOptions)12 Document (org.bson.Document)7 Test (org.junit.jupiter.api.Test)6 TypedAggregation (org.springframework.data.mongodb.core.aggregation.TypedAggregation)4 AggregationResults (org.springframework.data.mongodb.core.aggregation.AggregationResults)3 AutogenerateableId (org.springframework.data.mongodb.core.MongoTemplateUnitTests.AutogenerateableId)2 ClientSessionOptions (com.mongodb.ClientSessionOptions)1 MongoException (com.mongodb.MongoException)1 ReadPreference (com.mongodb.ReadPreference)1 WriteConcern (com.mongodb.WriteConcern)1 AggregateIterable (com.mongodb.client.AggregateIterable)1 ClientSession (com.mongodb.client.ClientSession)1 DistinctIterable (com.mongodb.client.DistinctIterable)1 FindIterable (com.mongodb.client.FindIterable)1 MapReduceIterable (com.mongodb.client.MapReduceIterable)1 MongoClient (com.mongodb.client.MongoClient)1 MongoCollection (com.mongodb.client.MongoCollection)1 MongoCursor (com.mongodb.client.MongoCursor)1 MongoDatabase (com.mongodb.client.MongoDatabase)1 MongoIterable (com.mongodb.client.MongoIterable)1