@Override public BulkOperations remove(Query query) { Assert.notNull(query, "Query must not be null!"); DeleteOptions deleteOptions = new DeleteOptions(); query.getCollation().map(Collation::toMongoCollation).ifPresent(deleteOptions::collation); models.add(new DeleteManyModel<>(query.getQueryObject(), deleteOptions)); return this; }
public long count(Query query, @Nullable Class<?> entityClass, String collectionName) { Assert.notNull(query, "Query must not be null!"); Assert.hasText(collectionName, "Collection name must not be null or empty!"); CountOptions options = new CountOptions(); query.getCollation().map(Collation::toMongoCollation).ifPresent(options::collation); Document document = queryMapper.getMappedObject(query.getQueryObject(), Optional.ofNullable(entityClass).map(it -> mappingContext.getPersistentEntity(entityClass))); return doCount(collectionName, document, options); }
@Nullable @Override public <T> T findAndRemove(Query query, Class<T> entityClass, String collectionName) { Assert.notNull(query, "Query must not be null!"); Assert.notNull(entityClass, "EntityClass must not be null!"); Assert.notNull(collectionName, "CollectionName must not be null!"); return doFindAndRemove(collectionName, query.getQueryObject(), query.getFieldsObject(), getMappedSortObject(query, entityClass), query.getCollation().orElse(null), entityClass); }
@Nullable @Override public <T> T findOne(Query query, Class<T> entityClass, String collectionName) { Assert.notNull(query, "Query must not be null!"); Assert.notNull(entityClass, "EntityClass must not be null!"); Assert.notNull(collectionName, "CollectionName must not be null!"); if (ObjectUtils.isEmpty(query.getSortObject()) && !query.getCollation().isPresent()) { return doFindOne(collectionName, query.getQueryObject(), query.getFieldsObject(), entityClass); } else { query.limit(1); List<T> results = find(query, entityClass, collectionName); return results.isEmpty() ? null : results.get(0); } }
@Nullable @Override public <T> T findAndModify(Query query, Update update, FindAndModifyOptions options, Class<T> entityClass, String collectionName) { Assert.notNull(query, "Query must not be null!"); Assert.notNull(update, "Update must not be null!"); Assert.notNull(options, "Options must not be null!"); Assert.notNull(entityClass, "EntityClass must not be null!"); Assert.notNull(collectionName, "CollectionName must not be null!"); FindAndModifyOptions optionsToUse = FindAndModifyOptions.of(options); Optionals.ifAllPresent(query.getCollation(), optionsToUse.getCollation(), (l, r) -> { throw new IllegalArgumentException( "Both Query and FindAndModifyOptions define a collation. Please provide the collation only via one of the two."); }); query.getCollation().ifPresent(optionsToUse::collation); return doFindAndModify(collectionName, query.getQueryObject(), query.getFieldsObject(), getMappedSortObject(query, entityClass), entityClass, update, optionsToUse); }
public <T> Mono<T> findAndModify(Query query, Update update, FindAndModifyOptions options, Class<T> entityClass, String collectionName) { FindAndModifyOptions optionsToUse = FindAndModifyOptions.of(options); Optionals.ifAllPresent(query.getCollation(), optionsToUse.getCollation(), (l, r) -> { throw new IllegalArgumentException( "Both Query and FindAndModifyOptions define a collation. Please provide the collation only via one of the two."); }); query.getCollation().ifPresent(optionsToUse::collation); return doFindAndModify(collectionName, query.getQueryObject(), query.getFieldsObject(), getMappedSortObject(query, entityClass), entityClass, update, optionsToUse); }
@Override public boolean exists(Query query, @Nullable Class<?> entityClass, String collectionName) { if (query == null) { throw new InvalidDataAccessApiUsageException("Query passed in to exist can't be null"); } Assert.notNull(collectionName, "CollectionName must not be null!"); Document mappedQuery = queryMapper.getMappedObject(query.getQueryObject(), getPersistentEntity(entityClass)); return execute(collectionName, new ExistsCallback(mappedQuery, query.getCollation().map(Collation::toMongoCollation).orElse(null))); }
public Mono<Long> count(Query query, @Nullable Class<?> entityClass, String collectionName) { Assert.notNull(query, "Query must not be null!"); Assert.hasText(collectionName, "Collection name must not be null or empty!"); return createMono(collectionName, collection -> { Document filter = query == null ? null : queryMapper.getMappedObject(query.getQueryObject(), entityClass == null ? null : mappingContext.getPersistentEntity(entityClass)); CountOptions options = new CountOptions(); if (query != null) { query.getCollation().map(Collation::toMongoCollation).ifPresent(options::collation); } if (LOGGER.isDebugEnabled()) { LOGGER.debug("Executing count: {} in collection: {}", serializeToJsonSafely(filter), collectionName); } return collection.count(filter, options); }); }
public <T> Mono<T> findAndRemove(Query query, Class<T> entityClass, String collectionName) { return doFindAndRemove(collectionName, query.getQueryObject(), query.getFieldsObject(), getMappedSortObject(query, entityClass), query.getCollation().orElse(null), entityClass); }
public Mono<Boolean> exists(Query query, @Nullable Class<?> entityClass, String collectionName) { if (query == null) { throw new InvalidDataAccessApiUsageException("Query passed in to exist can't be null"); } return createFlux(collectionName, collection -> { Document filter = queryMapper.getMappedObject(query.getQueryObject(), getPersistentEntity(entityClass)); FindPublisher<Document> findPublisher = collection.find(filter, Document.class) .projection(new Document("_id", 1)); if (LOGGER.isDebugEnabled()) { LOGGER.debug("exists: {} in collection: {}", serializeToJsonSafely(filter), collectionName); } findPublisher = query.getCollation().map(Collation::toMongoCollation).map(findPublisher::collation) .orElse(findPublisher); return findPublisher.limit(1); }).hasElements(); }
@SuppressWarnings("unchecked") public <T> Flux<T> findDistinct(Query query, String field, String collectionName, Class<?> entityClass, Class<T> resultClass) { Assert.notNull(query, "Query must not be null!"); Assert.notNull(field, "Field must not be null!"); Assert.notNull(collectionName, "CollectionName must not be null!"); Assert.notNull(entityClass, "EntityClass must not be null!"); Assert.notNull(resultClass, "ResultClass must not be null!"); MongoPersistentEntity<?> entity = getPersistentEntity(entityClass); Document mappedQuery = queryMapper.getMappedObject(query.getQueryObject(), entity); String mappedFieldName = queryMapper.getMappedFields(new Document(field, 1), entity).keySet().iterator().next(); Class<T> mongoDriverCompatibleType = mongoDatabaseFactory.getCodecFor(resultClass) // .map(Codec::getEncoderClass) // .orElse((Class<T>) BsonValue.class); Flux<?> result = execute(collectionName, collection -> { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Executing findDistinct using query {} for field: {} in collection: {}", serializeToJsonSafely(mappedQuery), field, collectionName); } DistinctPublisher<T> publisher = collection.distinct(mappedFieldName, mappedQuery, mongoDriverCompatibleType); return query.getCollation().map(Collation::toMongoCollation).map(publisher::collation).orElse(publisher); }); if (resultClass == Object.class || mongoDriverCompatibleType != resultClass) { Class<?> targetType = getMostSpecificConversionTargetType(resultClass, entityClass, field); MongoConverter converter = getConverter(); result = result.map(it -> converter.mapValueToTargetType(it, targetType, NO_OP_REF_RESOLVER)); } return (Flux<T>) result; }
/** * Performs update and upsert bulk operations. * * @param query the {@link Query} to determine documents to update. * @param update the {@link Update} to perform, must not be {@literal null}. * @param upsert whether to upsert. * @param multi whether to issue a multi-update. * @return the {@link BulkOperations} with the update registered. */ private BulkOperations update(Query query, Update update, boolean upsert, boolean multi) { Assert.notNull(query, "Query must not be null!"); Assert.notNull(update, "Update must not be null!"); UpdateOptions options = new UpdateOptions(); options.upsert(upsert); query.getCollation().map(Collation::toMongoCollation).ifPresent(options::collation); if (multi) { models.add(new UpdateManyModel<>(query.getQueryObject(), update.getUpdateObject(), options)); } else { models.add(new UpdateOneModel<>(query.getQueryObject(), update.getUpdateObject(), options)); } return this; }
public <T> Mono<T> findOne(Query query, Class<T> entityClass, String collectionName) { if (ObjectUtils.isEmpty(query.getSortObject())) { return doFindOne(collectionName, query.getQueryObject(), query.getFieldsObject(), entityClass, query.getCollation().orElse(null)); } query.limit(1); return find(query, entityClass, collectionName).next(); }
@Override public <S, T> Mono<T> findAndReplace(Query query, S replacement, FindAndReplaceOptions options, Class<S> entityType, String collectionName, Class<T> resultType) { Assert.notNull(query, "Query must not be null!"); Assert.notNull(replacement, "Replacement must not be null!"); Assert.notNull(options, "Options must not be null! Use FindAndReplaceOptions#empty() instead."); Assert.notNull(entityType, "Entity class must not be null!"); Assert.notNull(collectionName, "CollectionName must not be null!"); Assert.notNull(resultType, "ResultType must not be null! Use Object.class instead."); Assert.isTrue(query.getLimit() <= 1, "Query must not define a limit other than 1 ore none!"); Assert.isTrue(query.getSkip() <= 0, "Query must not define skip."); MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityType); Document mappedQuery = queryMapper.getMappedObject(query.getQueryObject(), entity); Document mappedFields = queryMapper.getMappedFields(query.getFieldsObject(), entity); Document mappedSort = queryMapper.getMappedSort(query.getSortObject(), entity); Document mappedReplacement = operations.forEntity(replacement).toMappedDocument(this.mongoConverter).getDocument(); return doFindAndReplace(collectionName, mappedQuery, mappedFields, mappedSort, query.getCollation().map(Collation::toMongoCollation).orElse(null), entityType, mappedReplacement, options, resultType); }
@Override public <S, T> T findAndReplace(Query query, S replacement, FindAndReplaceOptions options, Class<S> entityType, String collectionName, Class<T> resultType) { Assert.notNull(query, "Query must not be null!"); Assert.notNull(replacement, "Replacement must not be null!"); Assert.notNull(options, "Options must not be null! Use FindAndReplaceOptions#empty() instead."); Assert.notNull(entityType, "EntityType must not be null!"); Assert.notNull(collectionName, "CollectionName must not be null!"); Assert.notNull(resultType, "ResultType must not be null! Use Object.class instead."); Assert.isTrue(query.getLimit() <= 1, "Query must not define a limit other than 1 ore none!"); Assert.isTrue(query.getSkip() <= 0, "Query must not define skip."); MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityType); Document mappedQuery = queryMapper.getMappedObject(query.getQueryObject(), entity); Document mappedFields = queryMapper.getMappedFields(query.getFieldsObject(), entity); Document mappedSort = queryMapper.getMappedSort(query.getSortObject(), entity); Document mappedReplacement = operations.forEntity(replacement).toMappedDocument(this.mongoConverter).getDocument(); return doFindAndReplace(collectionName, mappedQuery, mappedFields, mappedSort, query.getCollation().map(Collation::toMongoCollation).orElse(null), entityType, mappedReplacement, options, resultType); }
@Override public Mono<Long> count(Query query, @Nullable Class<?> entityClass, String collectionName) { if (!session.hasActiveTransaction()) { return super.count(query, entityClass, collectionName); } return createMono(collectionName, collection -> { Document filter = query == null ? null : delegate.queryMapper.getMappedObject(query.getQueryObject(), entityClass == null ? null : delegate.mappingContext.getPersistentEntity(entityClass)); CountOptions options = new CountOptions(); if (query != null) { query.getCollation().map(Collation::toMongoCollation).ifPresent(options::collation); } if (LOGGER.isDebugEnabled()) { LOGGER.debug("Executing count: {} in collection: {}", serializeToJsonSafely(filter), collectionName); } return collection.countDocuments(filter, options); }); } }
/** * Create a {@code $count} aggregation for {@link Query} and optionally a {@link Class entity class}. * * @param query must not be {@literal null}. * @param entityClass can be {@literal null} if the {@link Query} object is empty. * @return the {@link Aggregation} pipeline definition to run a {@code $count} aggregation. */ Aggregation createCountAggregation(Query query, @Nullable Class<?> entityClass) { List<AggregationOperation> pipeline = computeCountAggregationPipeline(query, entityClass); Aggregation aggregation = entityClass != null ? Aggregation.newAggregation(entityClass, pipeline) : Aggregation.newAggregation(pipeline); aggregation.withOptions(AggregationOptions.builder().collation(query.getCollation().orElse(null)).build()); return aggregation; }
.getPersistentEntity(targetType.equals(Document.class) ? Object.class : targetType))); collation = query.getCollation().map(org.springframework.data.mongodb.core.query.Collation::toMongoCollation) .orElse(null);
query.getCollation().ifPresent(collation -> document.append("collation", collation.toDocument()));
query.getCollation().map(Collation::toMongoCollation).ifPresent(options::collation);