Search in sources :

Example 1 with TypedAggregation

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

the class AggregationUtil method createAggregationContext.

AggregationOperationContext createAggregationContext(Aggregation aggregation, @Nullable Class<?> inputType) {
    DomainTypeMapping domainTypeMapping = aggregation.getOptions().getDomainTypeMapping();
    if (domainTypeMapping == DomainTypeMapping.NONE) {
        return Aggregation.DEFAULT_CONTEXT;
    }
    if (!(aggregation instanceof TypedAggregation)) {
        if (inputType == null) {
            return untypedMappingContext.get();
        }
        if (domainTypeMapping == DomainTypeMapping.STRICT && !aggregation.getPipeline().containsUnionWith()) {
            return new TypeBasedAggregationOperationContext(inputType, mappingContext, queryMapper);
        }
        return new RelaxedTypeBasedAggregationOperationContext(inputType, mappingContext, queryMapper);
    }
    inputType = ((TypedAggregation<?>) aggregation).getInputType();
    if (domainTypeMapping == DomainTypeMapping.STRICT && !aggregation.getPipeline().containsUnionWith()) {
        return new TypeBasedAggregationOperationContext(inputType, mappingContext, queryMapper);
    }
    return new RelaxedTypeBasedAggregationOperationContext(inputType, mappingContext, queryMapper);
}
Also used : DomainTypeMapping(org.springframework.data.mongodb.core.aggregation.AggregationOptions.DomainTypeMapping) RelaxedTypeBasedAggregationOperationContext(org.springframework.data.mongodb.core.aggregation.RelaxedTypeBasedAggregationOperationContext) TypedAggregation(org.springframework.data.mongodb.core.aggregation.TypedAggregation) RelaxedTypeBasedAggregationOperationContext(org.springframework.data.mongodb.core.aggregation.RelaxedTypeBasedAggregationOperationContext) TypeBasedAggregationOperationContext(org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext)

Example 2 with TypedAggregation

use of org.springframework.data.mongodb.core.aggregation.TypedAggregation 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 TypedAggregation

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

the class ReactiveMongoTemplate method prepareFilter.

List<Document> prepareFilter(ChangeStreamOptions options) {
    Object filter = options.getFilter().orElse(Collections.emptyList());
    if (filter instanceof Aggregation) {
        Aggregation agg = (Aggregation) filter;
        AggregationOperationContext context = agg instanceof TypedAggregation ? new TypeBasedAggregationOperationContext(((TypedAggregation<?>) agg).getInputType(), getConverter().getMappingContext(), queryMapper) : new RelaxedTypeBasedAggregationOperationContext(Object.class, mappingContext, queryMapper);
        return agg.toPipeline(new PrefixingDelegatingAggregationOperationContext(context, "fullDocument", Arrays.asList("operationType", "fullDocument", "documentKey", "updateDescription", "ns")));
    }
    if (filter instanceof List) {
        return (List<Document>) filter;
    }
    throw new IllegalArgumentException("ChangeStreamRequestOptions.filter mut be either an Aggregation or a plain list of Documents");
}
Also used : Aggregation(org.springframework.data.mongodb.core.aggregation.Aggregation) TypedAggregation(org.springframework.data.mongodb.core.aggregation.TypedAggregation) PrefixingDelegatingAggregationOperationContext(org.springframework.data.mongodb.core.aggregation.PrefixingDelegatingAggregationOperationContext) AggregationOperationContext(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) PrefixingDelegatingAggregationOperationContext(org.springframework.data.mongodb.core.aggregation.PrefixingDelegatingAggregationOperationContext) RelaxedTypeBasedAggregationOperationContext(org.springframework.data.mongodb.core.aggregation.RelaxedTypeBasedAggregationOperationContext) TypeBasedAggregationOperationContext(org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext) RelaxedTypeBasedAggregationOperationContext(org.springframework.data.mongodb.core.aggregation.RelaxedTypeBasedAggregationOperationContext) TypedAggregation(org.springframework.data.mongodb.core.aggregation.TypedAggregation) ArrayList(java.util.ArrayList) List(java.util.List) RelaxedTypeBasedAggregationOperationContext(org.springframework.data.mongodb.core.aggregation.RelaxedTypeBasedAggregationOperationContext) TypeBasedAggregationOperationContext(org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext)

Example 4 with TypedAggregation

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

the class ChangeStreamTask method prepareFilter.

@SuppressWarnings("unchecked")
List<Document> prepareFilter(MongoTemplate template, ChangeStreamOptions options) {
    if (!options.getFilter().isPresent()) {
        return Collections.emptyList();
    }
    Object filter = options.getFilter().orElse(null);
    if (filter instanceof Aggregation) {
        Aggregation agg = (Aggregation) filter;
        AggregationOperationContext context = agg instanceof TypedAggregation ? new TypeBasedAggregationOperationContext(((TypedAggregation<?>) agg).getInputType(), template.getConverter().getMappingContext(), queryMapper) : Aggregation.DEFAULT_CONTEXT;
        return agg.toPipeline(new PrefixingDelegatingAggregationOperationContext(context, "fullDocument", denylist));
    }
    if (filter instanceof List) {
        return (List<Document>) filter;
    }
    throw new IllegalArgumentException("ChangeStreamRequestOptions.filter mut be either an Aggregation or a plain list of Documents");
}
Also used : TypedAggregation(org.springframework.data.mongodb.core.aggregation.TypedAggregation) Aggregation(org.springframework.data.mongodb.core.aggregation.Aggregation) PrefixingDelegatingAggregationOperationContext(org.springframework.data.mongodb.core.aggregation.PrefixingDelegatingAggregationOperationContext) PrefixingDelegatingAggregationOperationContext(org.springframework.data.mongodb.core.aggregation.PrefixingDelegatingAggregationOperationContext) AggregationOperationContext(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) TypeBasedAggregationOperationContext(org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext) TypedAggregation(org.springframework.data.mongodb.core.aggregation.TypedAggregation) List(java.util.List) TypeBasedAggregationOperationContext(org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext)

Example 5 with TypedAggregation

use of org.springframework.data.mongodb.core.aggregation.TypedAggregation 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)

Aggregations

TypedAggregation (org.springframework.data.mongodb.core.aggregation.TypedAggregation)9 Document (org.bson.Document)5 TypeBasedAggregationOperationContext (org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext)5 AggregationOperationContext (org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)4 AggregationOptions (org.springframework.data.mongodb.core.aggregation.AggregationOptions)4 List (java.util.List)3 Aggregation (org.springframework.data.mongodb.core.aggregation.Aggregation)3 AggregationResults (org.springframework.data.mongodb.core.aggregation.AggregationResults)3 PrefixingDelegatingAggregationOperationContext (org.springframework.data.mongodb.core.aggregation.PrefixingDelegatingAggregationOperationContext)2 RelaxedTypeBasedAggregationOperationContext (org.springframework.data.mongodb.core.aggregation.RelaxedTypeBasedAggregationOperationContext)2 Criteria (org.springframework.data.mongodb.core.query.Criteria)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