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);
}
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));
});
}
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");
}
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");
}
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();
});
}
Aggregations