use of org.springframework.data.mongodb.core.aggregation.TypedAggregation in project spring-data-mongodb by spring-projects.
the class ReactiveMongoTemplate method changeStream.
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#tail(org.springframework.data.mongodb.core.aggregation.Aggregation, java.lang.Class, org.springframework.data.mongodb.core.ChangeStreamOptions, java.lang.String)
*/
@Override
public <T> Flux<ChangeStreamEvent<T>> changeStream(@Nullable Aggregation filter, Class<T> resultType, ChangeStreamOptions options, String collectionName) {
Assert.notNull(resultType, "Result type must not be null!");
Assert.notNull(options, "ChangeStreamOptions must not be null!");
Assert.hasText(collectionName, "Collection name must not be null or empty!");
if (filter == null) {
return changeStream(Collections.emptyList(), resultType, options, collectionName);
}
AggregationOperationContext context = filter instanceof TypedAggregation ? new TypeBasedAggregationOperationContext(((TypedAggregation) filter).getInputType(), mappingContext, queryMapper) : Aggregation.DEFAULT_CONTEXT;
return changeStream(filter.toPipeline(new PrefixingDelegatingAggregationOperationContext(context, "fullDocument", Arrays.asList("operationType", "fullDocument", "documentKey", "updateDescription", "ns"))), resultType, options, collectionName);
}
use of org.springframework.data.mongodb.core.aggregation.TypedAggregation in project spring-data-mongodb by spring-projects.
the class MongoTemplate method aggregateStream.
@SuppressWarnings("ConstantConditions")
protected <O> CloseableIterator<O> aggregateStream(Aggregation aggregation, String collectionName, Class<O> outputType, @Nullable AggregationOperationContext context) {
Assert.hasText(collectionName, "Collection name must not be null or empty!");
Assert.notNull(aggregation, "Aggregation pipeline must not be null!");
Assert.notNull(outputType, "Output type must not be null!");
Assert.isTrue(!aggregation.getOptions().isExplain(), "Can't use explain option with streaming!");
AggregationDefinition aggregationDefinition = queryOperations.createAggregation(aggregation, context);
AggregationOptions options = aggregation.getOptions();
List<Document> pipeline = aggregationDefinition.getAggregationPipeline();
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format("Streaming aggregation: %s in collection %s", serializeToJsonSafely(pipeline), collectionName));
}
ReadDocumentCallback<O> readCallback = new ReadDocumentCallback<>(mongoConverter, outputType, collectionName);
return execute(collectionName, (CollectionCallback<CloseableIterator<O>>) collection -> {
AggregateIterable<Document> cursor = collection.aggregate(pipeline, Document.class).allowDiskUse(options.isAllowDiskUse());
if (options.getCursorBatchSize() != null) {
cursor = cursor.batchSize(options.getCursorBatchSize());
}
options.getComment().ifPresent(cursor::comment);
options.getHint().ifPresent(cursor::hint);
Class<?> domainType = aggregation instanceof TypedAggregation ? ((TypedAggregation) aggregation).getInputType() : null;
Optionals.firstNonEmpty(options::getCollation, () -> operations.forType(domainType).getCollation()).map(Collation::toMongoCollation).ifPresent(cursor::collation);
return new CloseableIterableCursorAdapter<>(cursor, exceptionTranslator, readCallback);
});
}
use of org.springframework.data.mongodb.core.aggregation.TypedAggregation in project spring-data-mongodb by spring-projects.
the class ReactiveChangeStreamOperationSupportUnitTests method listenWithDomainTypeCreatesTypedAggregation.
// DATAMONGO-2089
@Test
void listenWithDomainTypeCreatesTypedAggregation() {
Criteria criteria = where("operationType").is("insert");
changeStreamSupport.changeStream(Person.class).filter(criteria).listen().subscribe();
ArgumentCaptor<ChangeStreamOptions> optionsArgumentCaptor = ArgumentCaptor.forClass(ChangeStreamOptions.class);
verify(template).changeStream(isNull(), optionsArgumentCaptor.capture(), eq(Person.class));
assertThat(optionsArgumentCaptor.getValue().getFilter()).hasValueSatisfying(it -> {
assertThat(it).isInstanceOf(TypedAggregation.class);
TypedAggregation<?> aggregation = (TypedAggregation<?>) it;
assertThat(aggregation.getInputType()).isEqualTo(Person.class);
assertThat(extractPipeline(aggregation)).containsExactly(new Document("$match", new Document("operationType", "insert")));
});
}
use of org.springframework.data.mongodb.core.aggregation.TypedAggregation in project spring-data-mongodb by spring-projects.
the class StringBasedAggregation method doExecute.
/*
* (non-Javascript)
* @see org.springframework.data.mongodb.repository.query.AbstractReactiveMongoQuery#doExecute(org.springframework.data.mongodb.repository.query.MongoQueryMethod, org.springframework.data.repository.query.ResultProcessor, org.springframework.data.mongodb.repository.query.ConvertingParameterAccessor, java.lang.Class)
*/
@Override
protected Object doExecute(MongoQueryMethod method, ResultProcessor resultProcessor, ConvertingParameterAccessor accessor, Class<?> typeToRead) {
Class<?> sourceType = method.getDomainClass();
Class<?> targetType = typeToRead;
List<AggregationOperation> pipeline = computePipeline(method, accessor);
AggregationUtils.appendSortIfPresent(pipeline, accessor, typeToRead);
if (method.isSliceQuery()) {
AggregationUtils.appendLimitAndOffsetIfPresent(pipeline, accessor, LongUnaryOperator.identity(), limit -> limit + 1);
} else {
AggregationUtils.appendLimitAndOffsetIfPresent(pipeline, accessor);
}
boolean isSimpleReturnType = isSimpleReturnType(typeToRead);
boolean isRawAggregationResult = ClassUtils.isAssignable(AggregationResults.class, typeToRead);
if (isSimpleReturnType) {
targetType = Document.class;
} else if (isRawAggregationResult) {
// 🙈
targetType = method.getReturnType().getRequiredActualType().getRequiredComponentType().getType();
}
AggregationOptions options = computeOptions(method, accessor);
TypedAggregation<?> aggregation = new TypedAggregation<>(sourceType, pipeline, options);
if (method.isStreamQuery()) {
Stream<?> stream = mongoOperations.aggregateStream(aggregation, targetType).stream();
if (isSimpleReturnType) {
return stream.map(it -> AggregationUtils.extractSimpleTypeResult((Document) it, typeToRead, mongoConverter));
}
return stream;
}
AggregationResults<Object> result = (AggregationResults<Object>) mongoOperations.aggregate(aggregation, targetType);
if (isRawAggregationResult) {
return result;
}
List<Object> results = result.getMappedResults();
if (method.isCollectionQuery()) {
return isSimpleReturnType ? convertResults(typeToRead, results) : results;
}
if (method.isSliceQuery()) {
Pageable pageable = accessor.getPageable();
int pageSize = pageable.getPageSize();
List<Object> resultsToUse = isSimpleReturnType ? convertResults(typeToRead, results) : results;
boolean hasNext = resultsToUse.size() > pageSize;
return new SliceImpl<>(hasNext ? resultsToUse.subList(0, pageSize) : resultsToUse, pageable, hasNext);
}
Object uniqueResult = result.getUniqueMappedResult();
return isSimpleReturnType ? AggregationUtils.extractSimpleTypeResult((Document) uniqueResult, typeToRead, mongoConverter) : uniqueResult;
}
Aggregations