Compare commits

...

23 Commits
3.1.3 ... 3.1.5

Author SHA1 Message Date
Christoph Strobl
7779ded45c Release version 3.1.5 (2020.0.5).
See #3557
2021-02-18 10:59:16 +01:00
Christoph Strobl
918bf7c138 Prepare 3.1.5 (2020.0.5).
See #3557
2021-02-18 10:58:49 +01:00
Christoph Strobl
abe3b9f6d7 Updated changelog.
See #3557
2021-02-18 10:58:42 +01:00
Christoph Strobl
41c453cc83 Updated changelog.
See #3537
2021-02-17 14:20:39 +01:00
Christoph Strobl
77784d88c7 After release cleanups.
See #3536
2021-02-17 13:41:54 +01:00
Christoph Strobl
263c62c880 Prepare next development iteration.
See #3536
2021-02-17 13:41:53 +01:00
Christoph Strobl
24ab8f67bb Release version 3.1.4 (2020.0.4).
See #3536
2021-02-17 12:00:24 +01:00
Christoph Strobl
572ceb867e Prepare 3.1.4 (2020.0.4).
See #3536
2021-02-17 11:59:37 +01:00
Christoph Strobl
b7caea8602 Updated changelog.
See #3536
2021-02-17 11:59:32 +01:00
Christoph Strobl
3696f2144f Updated changelog.
See #3520
2021-02-17 11:34:25 +01:00
Christoph Strobl
b25c8acca6 Updated changelog.
See #3519
2021-02-17 10:58:24 +01:00
Christoph Strobl
00d6271468 Fix DocumentToStringConverter UUID representation when calling toJson.
This commit makes sure to use an Encoder having UuidRepresentation set when calling org.bson.Document#toJson, preventing CodecConfigurationException from being raised.

Future versions will make sure the UUID string representation matches the Java default one.

Closes #3546.
Original pull request: #3551.
2021-02-17 07:47:49 +01:00
Christoph Strobl
bb603ba7b9 Updated reference documentation regarding GeoJsonModule.
Original pull request: #3539.
Closes #3517
2021-02-02 14:50:54 +01:00
Christoph Strobl
02eaa4cbd2 Allow access to mongoDatabaseFactory used in ReactiveMongoTemplate.
By offering a getter method for the ReactiveMongoDatabaseFactory users subclassing ReactiveMongoTemplate could evaluate the current transaction state via ReactiveMongoDatabaseUtils.isTransactionActive(getDatabaseFactory()).
This change also aligns the reactive and imperative template implementation in that regard.

Closes #3540
Original pull request: #3541.
2021-02-02 14:22:15 +01:00
Christoph Strobl
7429503c63 Update count vs. estimatedCount documentation.
Closes #3055
Original pull request: #3541.
2021-02-02 14:22:15 +01:00
Christoph Strobl
82f4e2276b Fix Criteria chaining for Criteria.alike().
This commit fixes an issue where an Example probe would not be added to the criteria chain.

Closes #3544
Original pull request: #3549.
2021-02-01 09:14:52 +01:00
Mark Paluch
e1bce7d942 Polishing.
Align type variable naming with imperative extensions(I, O). Add extension without accepting KClass. Update since tags and tests.

See #3508.
Original pull request: #893.
2021-01-27 09:57:39 +01:00
wonwoo
8bf3d395be Add missing ReactiveMongoOperations.aggregate Kotlin extension.
See #3508.
Original pull request: #893.
2021-01-27 09:57:39 +01:00
Christoph Strobl
d3c00a93c0 Update QBE Documentation section.
This commit adds a note explaining scenarios suitable for an UntypedExampleMatcher.

Closes: #3474
Original pull request: #3538.
2021-01-26 15:04:10 +01:00
Christoph Strobl
0aa805e1a2 Fix method names in full text query documentation.
Closes #3525
2021-01-20 08:29:52 +01:00
Christoph Strobl
9dc1df3deb Updated changelog.
See #3521
2021-01-13 15:49:50 +01:00
Christoph Strobl
92a73a5cc0 After release cleanups.
See #3477
2021-01-13 15:01:50 +01:00
Christoph Strobl
910d66afb0 Prepare next development iteration.
See #3477
2021-01-13 15:01:46 +01:00
23 changed files with 393 additions and 37 deletions

View File

@@ -5,7 +5,7 @@
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>3.1.3</version>
<version>3.1.5</version>
<packaging>pom</packaging>
<name>Spring Data MongoDB</name>
@@ -15,7 +15,7 @@
<parent>
<groupId>org.springframework.data.build</groupId>
<artifactId>spring-data-parent</artifactId>
<version>2.4.3</version>
<version>2.4.5</version>
</parent>
<modules>
@@ -26,7 +26,7 @@
<properties>
<project.type>multi</project.type>
<dist.id>spring-data-mongodb</dist.id>
<springdata.commons>2.4.3</springdata.commons>
<springdata.commons>2.4.5</springdata.commons>
<mongo>4.1.1</mongo>
<mongo.reactivestreams>${mongo}</mongo.reactivestreams>
<jmh.version>1.19</jmh.version>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>3.1.3</version>
<version>3.1.5</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -14,7 +14,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>3.1.3</version>
<version>3.1.5</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -11,7 +11,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>3.1.3</version>
<version>3.1.5</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -125,6 +125,11 @@ public interface ExecutableFindOperation {
/**
* Get the number of matching elements.
* <p />
* This method uses an {@link com.mongodb.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions) aggregation
* execution} even for empty {@link Query queries} which may have an impact on performance, but guarantees shard,
* session and transaction compliance. In case an inaccurate count satisfies the applications needs use
* {@link MongoOperations#estimatedCount(String)} for empty queries instead.
*
* @return total number of matching elements.
*/

View File

@@ -1160,6 +1160,12 @@ public interface MongoOperations extends FluentMongoOperations {
* influence on the resulting number of documents found as those values are passed on to the server and potentially
* limit the range and order within which the server performs the count operation. Use an {@literal unpaged} query to
* count all matches.
* <p />
* This method uses an
* {@link com.mongodb.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions)
* aggregation execution} even for empty {@link Query queries} which may have an impact on performance, but guarantees
* shard, session and transaction compliance. In case an inaccurate count satisfies the applications needs use
* {@link #estimatedCount(Class)} for empty queries instead.
*
* @param query the {@link Query} class that specifies the criteria used to find documents. Must not be
* {@literal null}.
@@ -1176,6 +1182,12 @@ public interface MongoOperations extends FluentMongoOperations {
* influence on the resulting number of documents found as those values are passed on to the server and potentially
* limit the range and order within which the server performs the count operation. Use an {@literal unpaged} query to
* count all matches.
* <p />
* This method uses an
* {@link com.mongodb.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions)
* aggregation execution} even for empty {@link Query queries} which may have an impact on performance, but guarantees
* shard, session and transaction compliance. In case an inaccurate count satisfies the applications needs use
* {@link #estimatedCount(String)} for empty queries instead.
*
* @param query the {@link Query} class that specifies the criteria used to find documents.
* @param collectionName must not be {@literal null} or empty.
@@ -1187,6 +1199,9 @@ public interface MongoOperations extends FluentMongoOperations {
/**
* Estimate the number of documents, in the collection {@link #getCollectionName(Class) identified by the given type},
* based on collection statistics.
* <p />
* Please make sure to read the MongoDB reference documentation about limitations on eg. sharded cluster or inside
* transactions.
*
* @param entityClass must not be {@literal null}.
* @return the estimated number of documents.
@@ -1200,6 +1215,9 @@ public interface MongoOperations extends FluentMongoOperations {
/**
* Estimate the number of documents in the given collection based on collection statistics.
* <p />
* Please make sure to read the MongoDB reference documentation about limitations on eg. sharded cluster or inside
* transactions.
*
* @param collectionName must not be {@literal null}.
* @return the estimated number of documents.
@@ -1214,6 +1232,12 @@ public interface MongoOperations extends FluentMongoOperations {
* influence on the resulting number of documents found as those values are passed on to the server and potentially
* limit the range and order within which the server performs the count operation. Use an {@literal unpaged} query to
* count all matches.
* <p />
* This method uses an
* {@link com.mongodb.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions)
* aggregation execution} even for empty {@link Query queries} which may have an impact on performance, but guarantees
* shard, session and transaction compliance. In case an inaccurate count satisfies the applications needs use
* {@link #estimatedCount(String)} for empty queries instead.
*
* @param query the {@link Query} class that specifies the criteria used to find documents. Must not be
* {@literal null}.

View File

@@ -28,7 +28,6 @@ import org.bson.Document;
import org.bson.conversions.Bson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
@@ -3454,7 +3453,20 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
}
}
/**
* @deprecated since 3.1.4. Use {@link #getMongoDatabaseFactory()} instead.
* @return the {@link MongoDatabaseFactory} in use.
*/
@Deprecated
public MongoDatabaseFactory getMongoDbFactory() {
return getMongoDatabaseFactory();
}
/**
* @return the {@link MongoDatabaseFactory} in use.
* @since 3.1.4
*/
public MongoDatabaseFactory getMongoDatabaseFactory() {
return mongoDbFactory;
}

View File

@@ -106,6 +106,12 @@ public interface ReactiveFindOperation {
/**
* Get the number of matching elements.
* <p />
* This method uses an
* {@link com.mongodb.reactivestreams.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions)
* aggregation execution} even for empty {@link Query queries} which may have an impact on performance, but
* guarantees shard, session and transaction compliance. In case an inaccurate count satisfies the applications
* needs use {@link ReactiveMongoOperations#estimatedCount(String)} for empty queries instead.
*
* @return {@link Mono} emitting total number of matching elements. Never {@literal null}.
*/

View File

@@ -940,6 +940,12 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
* influence on the resulting number of documents found as those values are passed on to the server and potentially
* limit the range and order within which the server performs the count operation. Use an {@literal unpaged} query to
* count all matches.
* <p />
* This method uses an
* {@link com.mongodb.reactivestreams.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions)
* aggregation execution} even for empty {@link Query queries} which may have an impact on performance, but guarantees
* shard, session and transaction compliance. In case an inaccurate count satisfies the applications needs use
* {@link #estimatedCount(Class)} for empty queries instead.
*
* @param query the {@link Query} class that specifies the criteria used to find documents. Must not be
* {@literal null}.
@@ -956,6 +962,12 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
* influence on the resulting number of documents found as those values are passed on to the server and potentially
* limit the range and order within which the server performs the count operation. Use an {@literal unpaged} query to
* count all matches.
* <p />
* This method uses an
* {@link com.mongodb.reactivestreams.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions)
* aggregation execution} even for empty {@link Query queries} which may have an impact on performance, but guarantees
* shard, session and transaction compliance. In case an inaccurate count satisfies the applications needs use
* {@link #estimatedCount(String)} for empty queries instead.
*
* @param query the {@link Query} class that specifies the criteria used to find documents.
* @param collectionName must not be {@literal null} or empty.
@@ -971,6 +983,12 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
* influence on the resulting number of documents found as those values are passed on to the server and potentially
* limit the range and order within which the server performs the count operation. Use an {@literal unpaged} query to
* count all matches.
* <p />
* This method uses an
* {@link com.mongodb.reactivestreams.client.MongoCollection#countDocuments(org.bson.conversions.Bson, com.mongodb.client.model.CountOptions)
* aggregation execution} even for empty {@link Query queries} which may have an impact on performance, but guarantees
* shard, session and transaction compliance. In case an inaccurate count satisfies the applications needs use
* {@link #estimatedCount(String)} for empty queries instead.
*
* @param query the {@link Query} class that specifies the criteria used to find documents. Must not be
* {@literal null}.
@@ -983,6 +1001,9 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
/**
* Estimate the number of documents, in the collection {@link #getCollectionName(Class) identified by the given type},
* based on collection statistics.
* <p />
* Please make sure to read the MongoDB reference documentation about limitations on eg. sharded cluster or inside
* transactions.
*
* @param entityClass must not be {@literal null}.
* @return a {@link Mono} emitting the estimated number of documents.
@@ -996,6 +1017,9 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
/**
* Estimate the number of documents in the given collection based on collection statistics.
* <p />
* Please make sure to read the MongoDB reference documentation about limitations on eg. sharded cluster or inside
* transactions.
*
* @param collectionName must not be {@literal null}.
* @return a {@link Mono} emitting the estimated number of documents.

View File

@@ -2730,6 +2730,14 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
return potentiallyForceAcknowledgedWrite(wc);
}
/**
* @return the {@link MongoDatabaseFactory} in use.
* @since 3.1.4
*/
public ReactiveMongoDatabaseFactory getMongoDatabaseFactory() {
return mongoDatabaseFactory;
}
@Nullable
private WriteConcern potentiallyForceAcknowledgedWrite(@Nullable WriteConcern wc) {

View File

@@ -32,6 +32,9 @@ import java.util.concurrent.atomic.AtomicLong;
import org.bson.BsonTimestamp;
import org.bson.Document;
import org.bson.UuidRepresentation;
import org.bson.codecs.Codec;
import org.bson.internal.CodecRegistryHelper;
import org.bson.types.Binary;
import org.bson.types.Code;
import org.bson.types.Decimal128;
@@ -45,11 +48,12 @@ import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.convert.WritingConverter;
import org.springframework.data.mongodb.core.query.Term;
import org.springframework.data.mongodb.core.script.NamedMongoScript;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.NumberUtils;
import org.springframework.util.StringUtils;
import com.mongodb.MongoClientSettings;
/**
* Wrapper class to contain useful converters for the usage with Mongo.
*
@@ -236,9 +240,13 @@ abstract class MongoConverters {
INSTANCE;
private final Codec<Document> codec = CodecRegistryHelper
.createRegistry(MongoClientSettings.getDefaultCodecRegistry(), UuidRepresentation.JAVA_LEGACY)
.get(Document.class);
@Override
public String convert(Document source) {
return source.toJson();
return source.toJson(codec);
}
}

View File

@@ -124,7 +124,12 @@ public class Criteria implements CriteriaDefinition {
}
/**
* Static factory method to create a {@link Criteria} matching an example object.
* Static factory method to create a {@link Criteria} matching an example object. <br />
* By default the {@link Example} uses typed matching restricting it to probe assignable types. For example, when
* sticking with the default type key ({@code _class}), the query has restrictions such as
* <code>_class : &#123; $in : [com.acme.Person] &#125; </code>. <br />
* To avoid the above mentioned type restriction use an {@link UntypedExampleMatcher} with
* {@link Example#of(Object, org.springframework.data.domain.ExampleMatcher)}.
*
* @param example must not be {@literal null}.
* @return new instance of {@link Criteria}.
@@ -615,8 +620,15 @@ public class Criteria implements CriteriaDefinition {
*/
public Criteria alike(Example<?> sample) {
criteria.put("$example", sample);
return this;
if (StringUtils.hasText(this.getKey())) {
criteria.put("$example", sample);
return this;
}
Criteria exampleCriteria = new Criteria();
exampleCriteria.criteria.put("$example", sample);
return registerCriteriaChainElement(exampleCriteria);
}
/**

View File

@@ -78,16 +78,31 @@ public interface MongoRepository<T, ID> extends PagingAndSortingRepository<T, ID
*/
<S extends T> List<S> insert(Iterable<S> entities);
/*
* (non-Javadoc)
/**
* Returns all entities matching the given {@link Example}. In case no match could be found an empty {@link List} is
* returned. <br />
* By default the {@link Example} uses typed matching restricting it to probe assignable types. For example, when
* sticking with the default type key ({@code _class}), the query has restrictions such as
* <code>_class : &#123; $in : [com.acme.Person] &#125;</code>. <br />
* To avoid the above mentioned type restriction use an {@link org.springframework.data.mongodb.core.query.UntypedExampleMatcher} with
* {@link Example#of(Object, org.springframework.data.domain.ExampleMatcher)}.
*
* @see org.springframework.data.repository.query.QueryByExampleExecutor#findAll(org.springframework.data.domain.Example)
*/
@Override
<S extends T> List<S> findAll(Example<S> example);
/*
* (non-Javadoc)
* @see org.springframework.data.repository.query.QueryByExampleExecutor#findAll(org.springframework.data.domain.Example, org.springframework.data.domain.Sort)
/**
* Returns all entities matching the given {@link Example} applying the given {@link Sort}. In case no match could be
* found an empty {@link List} is returned. <br />
* By default the {@link Example} uses typed matching restricting it to probe assignable types. For example, when
* sticking with the default type key ({@code _class}), the query has restrictions such as
* <code>_class : &#123; $in : [com.acme.Person] &#125;</code>. <br />
* To avoid the above mentioned type restriction use an {@link org.springframework.data.mongodb.core.query.UntypedExampleMatcher} with
* {@link Example#of(Object, org.springframework.data.domain.ExampleMatcher)}.
*
* @see org.springframework.data.repository.query.QueryByExampleExecutor#findAll(org.springframework.data.domain.Example,
* org.springframework.data.domain.Sort)
*/
@Override
<S extends T> List<S> findAll(Example<S> example, Sort sort);

View File

@@ -64,16 +64,33 @@ public interface ReactiveMongoRepository<T, ID> extends ReactiveSortingRepositor
*/
<S extends T> Flux<S> insert(Publisher<S> entities);
/*
* (non-Javadoc)
* @see org.springframework.data.repository.query.QueryByExampleExecutor#findAll(org.springframework.data.domain.Example)
/**
* Returns all entities matching the given {@link Example}. In case no match could be found an empty {@link Flux} is
* returned. <br />
* By default the {@link Example} uses typed matching restricting it to probe assignable types. For example, when
* sticking with the default type key ({@code _class}), the query has restrictions such as
* <code>_class : &#123; $in : [com.acme.Person] &#125;</code>. <br />
* To avoid the above mentioned type restriction use an {@link org.springframework.data.mongodb.core.query.UntypedExampleMatcher} with
* {@link Example#of(Object, org.springframework.data.domain.ExampleMatcher)}.
*
* @see org.springframework.data.repository.query.ReactiveQueryByExampleExecutor#findAll(org.springframework.data.domain.Example)
*/
@Override
<S extends T> Flux<S> findAll(Example<S> example);
/*
* (non-Javadoc)
* @see org.springframework.data.repository.query.QueryByExampleExecutor#findAll(org.springframework.data.domain.Example, org.springframework.data.domain.Sort)
/**
* Returns all entities matching the given {@link Example} applying the given {@link Sort}. In case no match could be
* found an empty {@link Flux} is returned. <br />
* By default the {@link Example} uses typed matching restricting it to probe assignable types. For example, when
* sticking with the default type key ({@code _class}), the query has restrictions such as
* <code>_class : &#123; $in : [com.acme.Person] &#125;</code>. <br />
* To avoid the above mentioned type restriction use an {@link org.springframework.data.mongodb.core.query.UntypedExampleMatcher} with
* {@link Example#of(Object, org.springframework.data.domain.ExampleMatcher)}.
*
* @see org.springframework.data.repository.query.ReactiveQueryByExampleExecutor#findAll(org.springframework.data.domain.Example,
* org.springframework.data.domain.Sort)
*/
@Override
<S extends T> Flux<S> findAll(Example<S> example, Sort sort);
}

View File

@@ -20,6 +20,8 @@ import com.mongodb.client.result.UpdateResult
import com.mongodb.reactivestreams.client.MongoCollection
import org.bson.Document
import org.springframework.data.geo.GeoResult
import org.springframework.data.mongodb.core.aggregation.Aggregation
import org.springframework.data.mongodb.core.aggregation.TypedAggregation
import org.springframework.data.mongodb.core.index.ReactiveIndexOperations
import org.springframework.data.mongodb.core.query.NearQuery
import org.springframework.data.mongodb.core.query.Query
@@ -210,6 +212,52 @@ inline fun <reified T : Any, reified E : Any> ReactiveMongoOperations.findDistin
if (collectionName != null) findDistinct(query, field, collectionName, E::class.java, T::class.java)
else findDistinct(query, field, E::class.java, T::class.java)
/**
* Extension for [ReactiveMongoOperations.aggregate] leveraging reified type parameters.
*
* @author Wonwoo Lee
* @since 3.1.4
*/
inline fun <reified O : Any> ReactiveMongoOperations.aggregate(
aggregation: TypedAggregation<*>,
collectionName: String
): Flux<O> =
this.aggregate(aggregation, collectionName, O::class.java)
/**
* Extension for [ReactiveMongoOperations.aggregate] leveraging reified type parameters.
*
* @author Wonwoo Lee
* @since 3.1.4
*/
inline fun <reified O : Any> ReactiveMongoOperations.aggregate(aggregation: TypedAggregation<*>): Flux<O> =
this.aggregate(aggregation, O::class.java)
/**
* Extension for [ReactiveMongoOperations.aggregate] leveraging reified type parameters.
*
* @author Wonwoo Lee
* @author Mark Paluch
* @since 3.1.4
*/
inline fun <reified I : Any, reified O : Any> ReactiveMongoOperations.aggregate(
aggregation: Aggregation
): Flux<O> =
this.aggregate(aggregation, I::class.java, O::class.java)
/**
* Extension for [ReactiveMongoOperations.aggregate] leveraging reified type parameters.
*
* @author Wonwoo Lee
* @since 3.1.4
*/
inline fun <reified O : Any> ReactiveMongoOperations.aggregate(
aggregation: Aggregation,
collectionName: String
): Flux<O> =
this.aggregate(aggregation, collectionName, O::class.java)
/**
* Extension for [ReactiveMongoOperations.geoNear] leveraging reified type parameters.
*

View File

@@ -139,16 +139,14 @@ public class QueryByExampleTests {
assertThat(result).containsExactlyInAnyOrder(p1, p2, p3);
}
@Test // DATAMONGO-1245
@Test // DATAMONGO-1245, GH-3544
public void findByExampleWithCriteria() {
Person sample = new Person();
sample.lastname = "stark";
Query query = new Query(new Criteria().alike(Example.of(sample)).and("firstname").regex("^ary*"));
List<Person> result = operations.find(query, Person.class);
assertThat(result).hasSize(1);
Query query = new Query(new Criteria().alike(Example.of(sample)).and("firstname").regex(".*n.*"));
assertThat(operations.find(query, Person.class)).containsExactly(p1);
}
@Test // DATAMONGO-1459

View File

@@ -30,6 +30,8 @@ import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import javax.persistence.metamodel.EmbeddableType;
import org.assertj.core.api.Assertions;
import org.bson.types.Code;
import org.bson.types.Decimal128;
@@ -2179,6 +2181,15 @@ public class MappingMongoConverterUnitTests {
assertThat(((LinkedHashMap) result.get("cluster")).get("_id")).isEqualTo(100L);
}
@Test // GH-3546
void readFlattensNestedDocumentToStringIfNecessary() {
org.bson.Document source = new org.bson.Document("street", new org.bson.Document("json", "string").append("_id", UUID.randomUUID()));
Address target = converter.read(Address.class, source);
assertThat(target.street).isNotNull();
}
static class GenericType<T> {
T content;
}

View File

@@ -771,6 +771,19 @@ public class QueryMapperUnitTests {
assertThat(document).containsEntry("legacyPoint.y", 20D);
}
@Test // GH-3544
void exampleWithCombinedCriteriaShouldBeMappedCorrectly() {
Foo probe = new Foo();
probe.embedded = new EmbeddedClass();
probe.embedded.id = "conflux";
Query query = query(byExample(probe).and("listOfItems").exists(true));
org.bson.Document document = mapper.getMappedObject(query.getQueryObject(), context.getPersistentEntity(Foo.class));
assertThat(document).containsEntry("embedded\\._id", "conflux").containsEntry("my_items", new org.bson.Document("$exists", true));
}
@Test // DATAMONGO-1988
void mapsStringObjectIdRepresentationToObjectIdWhenReferencingIdProperty() {

View File

@@ -19,6 +19,8 @@ import example.first.First
import io.mockk.mockk
import io.mockk.verify
import org.junit.Test
import org.springframework.data.mongodb.core.aggregation.Aggregation
import org.springframework.data.mongodb.core.aggregation.TypedAggregation
import org.springframework.data.mongodb.core.query.NearQuery
import org.springframework.data.mongodb.core.query.Query
import org.springframework.data.mongodb.core.query.Update
@@ -28,6 +30,7 @@ import reactor.core.publisher.Mono
* @author Sebastien Deleuze
* @author Christoph Strobl
* @author Mark Paluch
* @author Wonwoo Lee
*/
class ReactiveMongoOperationsExtensionsTests {
@@ -598,7 +601,6 @@ class ReactiveMongoOperationsExtensionsTests {
verify { operations.findDistinct(query, "field", "collection", First::class.java, String::class.java) }
}
@Test // DATAMONGO-1761
@Suppress("DEPRECATION")
fun `findDistinct(Query, String, KClass) should call java counterpart`() {
@@ -606,6 +608,55 @@ class ReactiveMongoOperationsExtensionsTests {
val query = mockk<Query>()
operations.findDistinct<String>(query, "field", First::class)
verify { operations.findDistinct(query, "field", First::class.java, String::class.java) }
verify {
operations.findDistinct(
query,
"field",
First::class.java,
String::class.java
)
}
}
@Test // #893
fun `aggregate(TypedAggregation, String, KClass) should call java counterpart`() {
val aggregation = mockk<TypedAggregation<String>>()
operations.aggregate<First>(aggregation, "foo")
verify { operations.aggregate(aggregation, "foo", First::class.java) }
}
@Test // #893
fun `aggregate(TypedAggregation, KClass) should call java counterpart`() {
val aggregation = mockk<TypedAggregation<String>>()
operations.aggregate<First>(aggregation)
verify { operations.aggregate(aggregation, First::class.java) }
}
@Test // #893
fun `aggregate(Aggregation, KClass) should call java counterpart`() {
val aggregation = mockk<Aggregation>()
operations.aggregate<String, First>(aggregation)
verify {
operations.aggregate(
aggregation,
String::class.java,
First::class.java
)
}
}
@Test // #893
fun `aggregate(Aggregation, String) should call java counterpart`() {
val aggregation = mockk<Aggregation>()
operations.aggregate<First>(aggregation, "foo")
verify { operations.aggregate(aggregation, "foo", First::class.java) }
}
}

View File

@@ -1446,6 +1446,7 @@ The geo-near operations return a `GeoResults` wrapper object that encapsulates `
MongoDB supports https://geojson.org/[GeoJSON] and simple (legacy) coordinate pairs for geospatial data. Those formats can both be used for storing as well as querying data. See the https://docs.mongodb.org/manual/core/2dsphere/#geospatial-indexes-store-geojson/[MongoDB manual on GeoJSON support] to learn about requirements and restrictions.
[[mongo.geo-json.domain.classes]]
==== GeoJSON Types in Domain Classes
Usage of https://geojson.org/[GeoJSON] types in domain classes is straightforward. The `org.springframework.data.mongodb.core.geo` package contains types such as `GeoJsonPoint`, `GeoJsonPolygon`, and others. These types are extend the existing `org.springframework.data.geo` types. The following example uses a `GeoJsonPoint`:
@@ -1469,6 +1470,7 @@ public class Store {
----
====
[[mongo.geo-json.query-methods]]
==== GeoJSON Types in Repository Query Methods
Using GeoJSON types as repository query parameters forces usage of the `$geometry` operator when creating the query, as the following example shows:
@@ -1529,6 +1531,7 @@ repo.findByLocationWithin( <4>
<4> Use the legacy format `$polygon` operator.
====
[[mongo.geo-json.metrics]]
==== Metrics and Distance calculation
Then MongoDB `$geoNear` operator allows usage of a GeoJSON Point or legacy coordinate pairs.
@@ -1700,6 +1703,29 @@ Returning the 3 Documents just like the GeoJSON variant:
<4> Distance from center point in _Kilometers_ - take it times 1000 to match _Meters_ of the GeoJSON variant.
====
[[mongo.geo-json.jackson-modules]]
==== GeoJSON Jackson Modules
By using the <<core.web>>, Spring Data registers additional Jackson ``Modules``s to the `ObjectMapper` for deserializing common Spring Data domain types.
Please refer to the <<core.web.basic.jackson-mappers>> section to learn more about the infrastructure setup of this feature.
The MongoDB module additionally registers ``JsonDeserializer``s for the following GeoJSON types via its `GeoJsonConfiguration` exposing the `GeoJsonModule`.
----
org.springframework.data.mongodb.core.geo.GeoJsonPoint
org.springframework.data.mongodb.core.geo.GeoJsonMultiPoint
org.springframework.data.mongodb.core.geo.GeoJsonLineString
org.springframework.data.mongodb.core.geo.GeoJsonMultiLineString
org.springframework.data.mongodb.core.geo.GeoJsonPolygon
org.springframework.data.mongodb.core.geo.GeoJsonMultiPolygon
----
[NOTE]
====
The `GeoJsonModule` only registers ``JsonDeserializer``s!
The next major version (`4.0`) will register both, ``JsonDeserializer``s and ``JsonSerializer``s for GeoJSON types by default.
====
[[mongo.textsearch]]
=== Full-text Queries
@@ -1731,7 +1757,7 @@ A query searching for `coffee cake` can be defined and run as follows:
[source,java]
----
Query query = TextQuery
.searching(new TextCriteria().matchingAny("coffee", "cake"));
.queryText(new TextCriteria().matchingAny("coffee", "cake"));
List<Document> page = template.find(query, Document.class);
----
@@ -1744,7 +1770,7 @@ To sort results by relevance according to the `weights` use `TextQuery.sortBySco
[source,java]
----
Query query = TextQuery
.searching(new TextCriteria().matchingAny("coffee", "cake"))
.queryText(new TextCriteria().matchingAny("coffee", "cake"))
.sortByScore() <1>
.includeScore(); <2>
@@ -1759,8 +1785,8 @@ You can exclude search terms by prefixing the term with `-` or by using `notMatc
[source,java]
----
// search for 'coffee' and not 'cake'
TextQuery.searching(new TextCriteria().matching("coffee").matching("-cake"));
TextQuery.searching(new TextCriteria().matching("coffee").notMatching("cake"));
TextQuery.queryText(new TextCriteria().matching("coffee").matching("-cake"));
TextQuery.queryText(new TextCriteria().matching("coffee").notMatching("cake"));
----
`TextCriteria.matching` takes the provided term as is. Therefore, you can define phrases by putting them between double quotation marks (for example, `\"coffee cake\")` or using by `TextCriteria.phrase.` The following example shows both ways of defining a phrase:
@@ -1768,8 +1794,8 @@ TextQuery.searching(new TextCriteria().matching("coffee").notMatching("cake"));
[source,java]
----
// search for phrase 'coffee cake'
TextQuery.searching(new TextCriteria().matching("\"coffee cake\""));
TextQuery.searching(new TextCriteria().phrase("coffee cake"));
TextQuery.queryText(new TextCriteria().matching("\"coffee cake\""));
TextQuery.queryText(new TextCriteria().phrase("coffee cake"));
----
You can set flags for `$caseSensitive` and `$diacriticSensitive` by using the corresponding methods on `TextCriteria`. Note that these two optional flags have been introduced in MongoDB 3.2 and are not included in the query unless explicitly set.
@@ -2221,6 +2247,7 @@ With the introduction of <<mongo.transactions>> this was no longer possible beca
So in version 2.x `MongoOperations.count()` would use the collection statistics if no transaction was in progress, and the aggregation variant if so.
As of Spring Data MongoDB 3.x any `count` operation uses regardless the existence of filter criteria the aggregation-based count approach via MongoDBs `countDocuments`.
If the application is fine with the limitations of working upon collection statistics `MongoOperations.estimatedCount()` offers an alternative.
[NOTE]
====

View File

@@ -97,3 +97,10 @@ Query query = new Query(new Criteria().alike(example));
List<Person> result = template.find(query, Person.class);
----
====
[NOTE]
====
`UntypedExampleMatcher` is likely the right choice for you if you are storing different entities within a single collection or opted out of writing <<mongo-template.type-mapping,type hints>>.
Also, keep in mind that using `@TypeAlias` requires eager initialization of the `MappingContext`. To do so, configure `initialEntitySet` to to ensure proper alias resolution for read operations.
====

View File

@@ -1,6 +1,68 @@
Spring Data MongoDB Changelog
=============================
Changes in version 3.1.5 (2021-02-18)
-------------------------------------
Changes in version 3.2.0-M3 (2021-02-17)
----------------------------------------
* #3553 - Upgrade to MongoDB driver 4.2.0.
* #3546 - org.bson.codecs.configuration.CodecConfigurationException: The uuidRepresentation has not been specified, so the UUID cannot be encoded.
* #3544 - alike Criteria can't add andOperator.
* #3542 - Relax field name checks for TypedAggregations.
* #3540 - Allow access to mongoDatabaseFactory used in ReactiveMongoTemplate.
* #3529 - Update repository after GitHub issues migration.
* #3525 - Bug in full text query documentation [DATAMONGO-2673].
* #3517 - GeoJson: Improper Deserialization of Document with a GeoJsonPolygon [DATAMONGO-2664].
* #3508 - Add ReactiveMongoOperations.aggregate(…) Kotlin extension [DATAMONGO-2655].
* #3474 - Search by alike() criteria is broken when type alias information is not available [DATAMONGO-2620].
* #3055 - Improve count() and countDocuments() mapping documentation and/or method availability [DATAMONGO-2192].
* #2803 - Support flattening embedded/nested objects [DATAMONGO-1902].
Changes in version 3.1.4 (2021-02-17)
-------------------------------------
* #3546 - org.bson.codecs.configuration.CodecConfigurationException: The uuidRepresentation has not been specified, so the UUID cannot be encoded.
* #3544 - alike Criteria can't add andOperator.
* #3540 - Allow access to mongoDatabaseFactory used in ReactiveMongoTemplate.
* #3525 - Bug in full text query documentation [DATAMONGO-2673].
* #3517 - GeoJson: Improper Deserialization of Document with a GeoJsonPolygon [DATAMONGO-2664].
* #3508 - Add ReactiveMongoOperations.aggregate(…) Kotlin extension [DATAMONGO-2655].
* #3474 - Search by alike() criteria is broken when type alias information is not available [DATAMONGO-2620].
* #3055 - Improve count() and countDocuments() mapping documentation and/or method availability [DATAMONGO-2192].
Changes in version 3.0.7.RELEASE (2021-02-17)
---------------------------------------------
* DATAMONGO-2671 - DateFromParts millisecondsOf returns "milliseconds" as $dateFromParts function but it should be millisecond.
* DATAMONGO-2665 - Update CI jobs with Docker Login.
* #3544 - alike Criteria can't add andOperator.
* #3534 - Update copyright year to 2021.
* #3529 - Update repository after GitHub issues migration.
* #3525 - Bug in full text query documentation [DATAMONGO-2673].
* #3517 - GeoJson: Improper Deserialization of Document with a GeoJsonPolygon [DATAMONGO-2664].
* #3474 - Search by alike() criteria is broken when type alias information is not available [DATAMONGO-2620].
Changes in version 2.2.13.RELEASE (2021-02-17)
----------------------------------------------
* #3544 - alike Criteria can't add andOperator.
* #3534 - Update copyright year to 2021.
* #3529 - Update repository after GitHub issues migration.
* #3525 - Bug in full text query documentation [DATAMONGO-2673].
Changes in version 3.2.0-M2 (2021-01-13)
----------------------------------------
* DATAMONGO-2671 - DateFromParts millisecondsOf returns "milliseconds" as $dateFromParts function but it should be millisecond.
* DATAMONGO-2665 - Update CI jobs with Docker Login.
* DATAMONGO-2651 - Allow AggregationExpression as part of group operation.
* #3534 - Update copyright year to 2021.
* #3529 - Update repository after GitHub issues migration.
* #3515 - Deprecate KPropertyPath in favor of Spring Data Common's KPropertyPath [DATAMONGO-2662].
Changes in version 3.1.3 (2021-01-13)
-------------------------------------
* DATAMONGO-2671 - DateFromParts millisecondsOf returns "milliseconds" as $dateFromParts function but it should be millisecond.
@@ -3264,6 +3326,12 @@ Repository

View File

@@ -1,4 +1,4 @@
Spring Data MongoDB 3.1.3 (2020.0.3)
Spring Data MongoDB 3.1.5 (2020.0.5)
Copyright (c) [2010-2019] Pivotal Software, Inc.
This product is licensed to you under the Apache License, Version 2.0 (the "License").
@@ -23,3 +23,5 @@ conditions of the subcomponent's license, as noted in the LICENSE file.