Support hints on Update.
This commit makes sure to read query hints and apply them to the MongoDB UpdateOptions when running an update via Reactive-/MongoTemplate. Original pull request: #4311 Closes: #3218
This commit is contained in:
committed by
Mark Paluch
parent
0020499d4e
commit
cd63501680
@@ -27,6 +27,7 @@ import org.springframework.util.StringUtils;
|
||||
* Function object to apply a query hint. Can be an index name or a BSON document.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Christoph Strobl
|
||||
* @since 4.1
|
||||
*/
|
||||
class HintFunction {
|
||||
@@ -67,6 +68,23 @@ class HintFunction {
|
||||
return (hint instanceof String hintString && StringUtils.hasText(hintString)) || hint instanceof Bson;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the hint to consumers depending on the hint format if {@link #isPresent() present}.
|
||||
*
|
||||
* @param registryProvider
|
||||
* @param stringConsumer
|
||||
* @param bsonConsumer
|
||||
* @param <R>
|
||||
*/
|
||||
public <R> void ifPresent(@Nullable CodecRegistryProvider registryProvider, Function<String, R> stringConsumer,
|
||||
Function<Bson, R> bsonConsumer) {
|
||||
|
||||
if (!isPresent()) {
|
||||
return;
|
||||
}
|
||||
apply(registryProvider, stringConsumer, bsonConsumer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the hint to consumers depending on the hint format.
|
||||
*
|
||||
|
||||
@@ -715,6 +715,7 @@ class QueryOperations {
|
||||
.arrayFilters(update.getArrayFilters().stream().map(ArrayFilter::asDocument).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
HintFunction.from(getQuery().getHint()).ifPresent(codecRegistryProvider, options::hintString, options::hint);
|
||||
applyCollation(domainType, options::collation);
|
||||
|
||||
if (callback != null) {
|
||||
|
||||
@@ -978,6 +978,28 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
|
||||
assertThat(options.getValue().getCollation().getLocale()).isEqualTo("fr");
|
||||
}
|
||||
|
||||
@Test // GH-3218
|
||||
void updateUsesHintStringFromQuery() {
|
||||
|
||||
template.updateFirst(new Query().withHint("index-1"), new Update().set("spring", "data"), Human.class);
|
||||
|
||||
ArgumentCaptor<UpdateOptions> options = ArgumentCaptor.forClass(UpdateOptions.class);
|
||||
verify(collection).updateOne(any(Bson.class), any(Bson.class), options.capture());
|
||||
|
||||
assertThat(options.getValue().getHintString()).isEqualTo("index-1");
|
||||
}
|
||||
|
||||
@Test // GH-3218
|
||||
void updateUsesHintDocumentFromQuery() {
|
||||
|
||||
template.updateFirst(new Query().withHint("{ name : 1 }"), new Update().set("spring", "data"), Human.class);
|
||||
|
||||
ArgumentCaptor<UpdateOptions> options = ArgumentCaptor.forClass(UpdateOptions.class);
|
||||
verify(collection).updateOne(any(Bson.class), any(Bson.class), options.capture());
|
||||
|
||||
assertThat(options.getValue().getHint()).isEqualTo(new Document("name", 1));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1518
|
||||
void replaceOneShouldUseCollationWhenPresent() {
|
||||
|
||||
|
||||
@@ -350,7 +350,28 @@ public class ReactiveMongoTemplateUnitTests {
|
||||
verify(collection).updateMany(any(), any(Bson.class), options.capture());
|
||||
|
||||
assertThat(options.getValue().getCollation().getLocale()).isEqualTo("fr");
|
||||
}
|
||||
|
||||
@Test // GH-3218
|
||||
void updateUsesHintStringFromQuery() {
|
||||
|
||||
template.updateFirst(new Query().withHint("index-1"), new Update().set("spring", "data"), Person.class).subscribe();
|
||||
|
||||
ArgumentCaptor<UpdateOptions> options = ArgumentCaptor.forClass(UpdateOptions.class);
|
||||
verify(collection).updateOne(any(Bson.class), any(Bson.class), options.capture());
|
||||
|
||||
assertThat(options.getValue().getHintString()).isEqualTo("index-1");
|
||||
}
|
||||
|
||||
@Test // GH-3218
|
||||
void updateUsesHintDocumentFromQuery() {
|
||||
|
||||
template.updateFirst(new Query().withHint("{ firstname : 1 }"), new Update().set("spring", "data"), Person.class).subscribe();
|
||||
|
||||
ArgumentCaptor<UpdateOptions> options = ArgumentCaptor.forClass(UpdateOptions.class);
|
||||
verify(collection).updateOne(any(Bson.class), any(Bson.class), options.capture());
|
||||
|
||||
assertThat(options.getValue().getHint()).isEqualTo(new Document("firstname", 1));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1518
|
||||
|
||||
@@ -922,6 +922,7 @@ Most methods return the `Update` object to provide a fluent style for the API.
|
||||
* *updateMulti*: Updates all objects that match the query document criteria with the updated document.
|
||||
|
||||
WARNING: `updateFirst` does not support ordering. Please use <<mongo-template.find-and-upsert, findAndModify>> to apply `Sort`.
|
||||
NOTE: Index hints for the update operation can be provided via `Query.withHint(...)`.
|
||||
|
||||
[[mongodb-template-update.update]]
|
||||
==== Methods in the `Update` Class
|
||||
|
||||
Reference in New Issue
Block a user