diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java
index 4179c0f67..07a4e2bd6 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java
@@ -1640,7 +1640,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
collection.find(filter, Document.class).projection(updateContext.getMappedShardKey(entity)).first());
}
}
-
+
ReplaceOptions replaceOptions = updateContext.getReplaceOptions(entityClass);
return collection.replaceOne(filter, updateObj, replaceOptions);
} else {
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryOperations.java
index f6852c333..357f1bdde 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryOperations.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryOperations.java
@@ -40,6 +40,7 @@ import org.springframework.data.mongodb.core.convert.QueryMapper;
import org.springframework.data.mongodb.core.convert.UpdateMapper;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
+import org.springframework.data.mongodb.core.mapping.ShardKey;
import org.springframework.data.mongodb.core.query.BasicQuery;
import org.springframework.data.mongodb.core.query.Collation;
import org.springframework.data.mongodb.core.query.Query;
@@ -58,9 +59,10 @@ import com.mongodb.client.model.UpdateOptions;
/**
* {@link QueryOperations} centralizes common operations required before an operation is actually ready to be executed.
* This involves mapping {@link Query queries} into their respective MongoDB representation, computing execution options
- * for {@literal count}, {@literal remove}, ...
+ * for {@literal count}, {@literal remove}, and other methods.
*
* @author Christoph Strobl
+ * @author Mark Paluch
* @since 3.0
*/
class QueryOperations {
@@ -71,6 +73,7 @@ class QueryOperations {
private final CodecRegistryProvider codecRegistryProvider;
private final MappingContext extends MongoPersistentEntity>, MongoPersistentProperty> mappingContext;
private final AggregationUtil aggregationUtil;
+ private final Map, Document> mappedShardKey = new ConcurrentHashMap<>(1);
/**
* Create a new instance of {@link QueryOperations}.
@@ -503,7 +506,6 @@ class QueryOperations {
private final boolean upsert;
private final @Nullable UpdateDefinition update;
private final @Nullable MappedDocument mappedDocument;
- private final Map, Document> mappedShardKey = new ConcurrentHashMap<>(1);
/**
* Create a new {@link UpdateContext} instance.
@@ -624,41 +626,49 @@ class QueryOperations {
return mappedQuery;
}
- Document applyShardKey(@Nullable MongoPersistentEntity domainType, Document filter,
- @Nullable Document existing) {
+ Document applyShardKey(MongoPersistentEntity domainType, Document filter, @Nullable Document existing) {
Document shardKeySource = existing != null ? existing
: mappedDocument != null ? mappedDocument.getDocument() : getMappedUpdate(domainType);
Document filterWithShardKey = new Document(filter);
- for (String key : getMappedShardKeyFields(domainType)) {
- if (!filterWithShardKey.containsKey(key)) {
- filterWithShardKey.append(key, shardKeySource.get(key));
- }
- }
+ getMappedShardKeyFields(domainType).forEach(key -> filterWithShardKey.putIfAbsent(key, shardKeySource.get(key)));
return filterWithShardKey;
}
- boolean requiresShardKey(Document filter, @Nullable MongoPersistentEntity domainType) {
+ boolean requiresShardKey(Document filter, @Nullable MongoPersistentEntity> domainType) {
- if (multi || domainType == null || !domainType.isSharded() || domainType.idPropertyIsShardKey()) {
- return false;
- }
-
- if (filter.keySet().containsAll(getMappedShardKeyFields(domainType))) {
- return false;
- }
-
- return true;
+ return !multi && domainType != null && domainType.isSharded() && !shardedById(domainType)
+ && !filter.keySet().containsAll(getMappedShardKeyFields(domainType));
}
- Set getMappedShardKeyFields(@Nullable MongoPersistentEntity> entity) {
+ /**
+ * @return {@literal true} if the {@link MongoPersistentEntity#getShardKey() shard key} is the entities
+ * {@literal id} property.
+ * @since 3.0
+ */
+ private boolean shardedById(MongoPersistentEntity> domainType) {
+
+ ShardKey shardKey = domainType.getShardKey();
+ if (shardKey.size() != 1) {
+ return false;
+ }
+
+ String key = shardKey.getPropertyNames().iterator().next();
+ if ("_id".equals(key)) {
+ return true;
+ }
+
+ MongoPersistentProperty idProperty = domainType.getIdProperty();
+ return idProperty != null && idProperty.getName().equals(key);
+ }
+
+ Set getMappedShardKeyFields(MongoPersistentEntity> entity) {
return getMappedShardKey(entity).keySet();
}
- Document getMappedShardKey(@Nullable MongoPersistentEntity> entity) {
-
+ Document getMappedShardKey(MongoPersistentEntity> entity) {
return mappedShardKey.computeIfAbsent(entity.getType(),
key -> queryMapper.getMappedFields(entity.getShardKey().getDocument(), entity));
}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java
index b2324f94f..b2f457132 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java
@@ -1637,7 +1637,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
? collection //
: collection.withWriteConcern(writeConcernToUse);
- Publisher> publisher = null;
+ Publisher> publisher;
if (!mapped.hasId()) {
publisher = collectionToUse.insertOne(document);
} else {
@@ -1647,20 +1647,23 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
Document filter = updateContext.getMappedQuery(entity);
Document replacement = updateContext.getMappedUpdate(entity);
- Mono theFilter = Mono.just(filter);
+ Mono deferredFilter;
- if(updateContext.requiresShardKey(filter, entity)) {
+ if (updateContext.requiresShardKey(filter, entity)) {
if (entity.getShardKey().isImmutable()) {
- theFilter = Mono.just(updateContext.applyShardKey(entity, filter, null));
+ deferredFilter = Mono.just(updateContext.applyShardKey(entity, filter, null));
} else {
- theFilter = Mono.from(
- collection.find(filter, Document.class).projection(updateContext.getMappedShardKey(entity)).first())
+ deferredFilter = Mono
+ .from(
+ collection.find(filter, Document.class).projection(updateContext.getMappedShardKey(entity)).first())
.defaultIfEmpty(replacement).map(it -> updateContext.applyShardKey(entity, filter, it));
}
+ } else {
+ deferredFilter = Mono.just(filter);
}
- publisher = theFilter.flatMap(
- it -> Mono.from(collectionToUse.replaceOne(it, replacement, updateContext.getReplaceOptions(entityClass))));
+ publisher = deferredFilter.flatMapMany(
+ it -> collectionToUse.replaceOne(it, replacement, updateContext.getReplaceOptions(entityClass)));
}
return Mono.from(publisher).map(o -> mapped.getId());
@@ -1800,20 +1803,22 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
if (!UpdateMapper.isUpdateObject(updateObj)) {
Document filter = new Document(queryObj);
- Mono theFilter = Mono.just(filter);
+ Mono deferredFilter;
- if(updateContext.requiresShardKey(filter, entity)) {
+ if (updateContext.requiresShardKey(filter, entity)) {
if (entity.getShardKey().isImmutable()) {
- theFilter = Mono.just(updateContext.applyShardKey(entity, filter, null));
+ deferredFilter = Mono.just(updateContext.applyShardKey(entity, filter, null));
} else {
- theFilter = Mono.from(
+ deferredFilter = Mono.from(
collection.find(filter, Document.class).projection(updateContext.getMappedShardKey(entity)).first())
.defaultIfEmpty(updateObj).map(it -> updateContext.applyShardKey(entity, filter, it));
}
+ } else {
+ deferredFilter = Mono.just(filter);
}
ReplaceOptions replaceOptions = updateContext.getReplaceOptions(entityClass);
- return theFilter.flatMap(it -> Mono.from(collectionToUse.replaceOne(it, updateObj, replaceOptions)));
+ return deferredFilter.flatMap(it -> Mono.from(collectionToUse.replaceOne(it, updateObj, replaceOptions)));
}
return multi ? collectionToUse.updateMany(queryObj, updateObj, updateOptions)
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentEntity.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentEntity.java
index cbc67b13a..3a9fa8a66 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentEntity.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentEntity.java
@@ -96,7 +96,26 @@ public class BasicMongoPersistentEntity extends BasicPersistentEntity extends BasicPersistentEntity entity) {
-
- if (!entity.isAnnotationPresent(Sharded.class)) {
- return ShardKey.none();
- }
-
- Sharded sharded = entity.getRequiredAnnotation(Sharded.class);
-
- String[] keyProperties = sharded.shardKey();
- if (ObjectUtils.isEmpty(keyProperties)) {
- keyProperties = new String[] { "_id" };
- }
-
- ShardKey shardKey = ShardingStrategy.HASH.equals(sharded.shardingStrategy()) ? ShardKey.hash(keyProperties)
- : ShardKey.range(keyProperties);
-
- return sharded.immutableKey() ? ShardKey.immutable(shardKey) : shardKey;
- }
-
/**
* Handler to collect {@link MongoPersistentProperty} instances and check that each of them is mapped to a distinct
* field name.
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoPersistentEntity.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoPersistentEntity.java
index 1cef658d9..b5a3afc41 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoPersistentEntity.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoPersistentEntity.java
@@ -86,29 +86,11 @@ public interface MongoPersistentEntity extends PersistentEntityShard
* Key used to distribute documents across a sharded MongoDB cluster.
*
- * {@link ShardKey#isImmutable() Immutable} shard keys indicate a fixed value that is not updated (see
+ * {@link ShardKey#isImmutable() Immutable} shard keys indicates a fixed value that is not updated (see
* MongoDB
- * Reference: Change a Document’s Shard Key Value), which allows to skip server round trips in cases where a
+ * Reference: Change a Document's Shard Key Value), which allows to skip server round trips in cases where a
* potential shard key change might have occurred.
*
* @author Christoph Strobl
+ * @author Mark Paluch
* @since 3.0
*/
public class ShardKey {
@@ -68,14 +69,23 @@ public class ShardKey {
/**
* @return {@literal true} if the shard key of an document does not change.
* @see MongoDB
- * Reference: Change a Document’s Shard Key Value
+ * Reference: Change a Document's Shard Key Value
*/
public boolean isImmutable() {
return immutable;
}
/**
- * Get the unmapped MongoDB representation of the {@link ShardKey}.
+ * Return whether the shard key represents a sharded key. Return {@literal false} if the key is not sharded.
+ *
+ * @return {@literal true} if the key is sharded; {@literal false} otherwise.
+ */
+ public boolean isSharded() {
+ return !propertyNames.isEmpty();
+ }
+
+ /**
+ * Get the raw MongoDB representation of the {@link ShardKey}.
*
* @return never {@literal null}.
*/
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/Sharded.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/Sharded.java
index 646edfd6a..514475982 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/Sharded.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/Sharded.java
@@ -25,26 +25,29 @@ import org.springframework.core.annotation.AliasFor;
import org.springframework.data.annotation.Persistent;
/**
- * The {@link Sharded} annotation provides meta information about the actual distribution of data across multiple
- * machines. The {@link #shardKey()} is used to distribute documents across shards.
- * Please visit the MongoDB Documentation for more information
- * about requirements and limitations of sharding.
- * Spring Data will automatically add the shard key to filter queries used for
+ * The {@link Sharded} annotation provides meta information about the actual distribution of data. The
+ * {@link #shardKey()} is used to distribute documents across shards.
+ * Please see the MongoDB Documentation for more information
+ * about requirements and limitations of sharding.
+ *
+ * Spring Data adds the shard key to filter queries used for
* {@link com.mongodb.client.MongoCollection#replaceOne(org.bson.conversions.Bson, Object)} operations triggered by
* {@code save} operations on {@link org.springframework.data.mongodb.core.MongoOperations} and
- * {@link org.springframework.data.mongodb.core.ReactiveMongoOperations} as well as {@code update/upsert} operation
+ * {@link org.springframework.data.mongodb.core.ReactiveMongoOperations} as well as {@code update/upsert} operations
* replacing/upserting a single existing document as long as the given
- * {@link org.springframework.data.mongodb.core.query.UpdateDefinition} holds a full copy of the entity.
+ * {@link org.springframework.data.mongodb.core.query.UpdateDefinition} holds a full copy of the entity.
+ *
* All other operations that require the presence of the {@literal shard key} in the filter query need to provide the
* information via the {@link org.springframework.data.mongodb.core.query.Query} parameter when invoking the method.
*
* @author Christoph Strobl
+ * @author Mark Paluch
* @since 3.0
*/
@Persistent
@Inherited
@Retention(RetentionPolicy.RUNTIME)
-@Target({ ElementType.TYPE })
+@Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE })
public @interface Sharded {
/**
@@ -57,15 +60,15 @@ public @interface Sharded {
String[] value() default {};
/**
- * The shard key determines the distribution of the collection’s documents among the cluster’s shards. The shard key
- * is either a single or multiple indexed properties that exist in every document in the collection.
+ * The shard key determines the distribution of the collection's documents among the cluster's shards. The shard key
+ * is either a single or multiple indexed properties that exist in every document in the collection.
+ *
* By default the {@literal id} property is used for sharding.
- * NOTE Required indexes will not be created automatically. Use
- * {@link org.springframework.data.mongodb.core.index.Indexed} or
+ * NOTE Required indexes are not created automatically. Create these either externally, via
+ * {@link org.springframework.data.mongodb.core.index.IndexOperations#ensureIndex(org.springframework.data.mongodb.core.index.IndexDefinition)}
+ * or by annotating your domain model with {@link org.springframework.data.mongodb.core.index.Indexed}/
* {@link org.springframework.data.mongodb.core.index.CompoundIndex} along with enabled
- * {@link org.springframework.data.mongodb.config.MongoConfigurationSupport#autoIndexCreation() auto index creation}
- * or set up them up via
- * {@link org.springframework.data.mongodb.core.index.IndexOperations#ensureIndex(org.springframework.data.mongodb.core.index.IndexDefinition)}.
+ * {@link org.springframework.data.mongodb.config.MongoConfigurationSupport#autoIndexCreation() auto index creation}.
*
* @return an empty key by default. Which indicates to use the entities {@literal id} property.
*/
@@ -82,10 +85,10 @@ public @interface Sharded {
/**
* As of MongoDB 4.2 it is possible to change the shard key using update. Using immutable shard keys avoids server
* round trips to obtain an entities actual shard key from the database.
- *
- * @return {@literal false} by default;
+ *
+ * @return {@literal false} by default.
* @see MongoDB
- * Reference: Change a Document’s Shard Key Value
+ * Reference: Change a Document's Shard Key Value
*/
boolean immutableKey() default false;
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java
index 7f93fdc8e..3d87afad8 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java
@@ -1843,14 +1843,16 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
@Test // DATAMONGO-2341
void saveShouldAppendNonDefaultShardKeyToVersionedEntityIfNotPresentInFilter() {
- when(collection.replaceOne(any(), any(), any(ReplaceOptions.class))).thenReturn(UpdateResult.acknowledged(1, 1L, null));
+ when(collection.replaceOne(any(), any(), any(ReplaceOptions.class)))
+ .thenReturn(UpdateResult.acknowledged(1, 1L, null));
template.save(new ShardedVersionedEntityWithNonDefaultShardKey("id-1", 1L, "AT", 4230));
ArgumentCaptor filter = ArgumentCaptor.forClass(Bson.class);
verify(collection).replaceOne(filter.capture(), any(), any());
- assertThat(filter.getValue()).isEqualTo(new Document("_id", "id-1").append("version", 1L).append("country", "AT").append("userid", 4230));
+ assertThat(filter.getValue())
+ .isEqualTo(new Document("_id", "id-1").append("version", 1L).append("country", "AT").append("userid", 4230));
}
@Test // DATAMONGO-2341
@@ -1910,7 +1912,8 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
@Test // DATAMONGO-2341
void saveVersionedShouldProjectOnShardKeyWhenLoadingExistingDocument() {
- when(collection.replaceOne(any(), any(), any(ReplaceOptions.class))).thenReturn(UpdateResult.acknowledged(1, 1L, null));
+ when(collection.replaceOne(any(), any(), any(ReplaceOptions.class)))
+ .thenReturn(UpdateResult.acknowledged(1, 1L, null));
when(findIterable.first()).thenReturn(new Document("_id", "id-1").append("country", "US").append("userid", 4230));
template.save(new ShardedVersionedEntityWithNonDefaultShardKey("id-1", 1L, "AT", 4230));
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateUnitTests.java
index 240fdb6c3..e34f4922c 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateUnitTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateUnitTests.java
@@ -1076,7 +1076,8 @@ public class ReactiveMongoTemplateUnitTests {
@Test // DATAMONGO-2341
void saveShouldProjectOnShardKeyWhenLoadingExistingDocument() {
- when(findPublisher.first()).thenReturn(Mono.just(new Document("_id", "id-1").append("country", "US").append("userid", 4230)));
+ when(findPublisher.first())
+ .thenReturn(Mono.just(new Document("_id", "id-1").append("country", "US").append("userid", 4230)));
template.save(new ShardedEntityWithNonDefaultShardKey("id-1", "AT", 4230)).subscribe();
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/UpdateOperationsUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/UpdateOperationsUnitTests.java
index 8edffec3e..26eee53bf 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/UpdateOperationsUnitTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/UpdateOperationsUnitTests.java
@@ -35,6 +35,8 @@ import org.springframework.lang.Nullable;
import com.mongodb.MongoClientSettings;
/**
+ * Unit test for {@link com.mongodb.internal.operation.UpdateOperation}.
+ *
* @author Christoph Strobl
*/
class UpdateOperationsUnitTests {
@@ -141,10 +143,9 @@ class UpdateOperationsUnitTests {
super(update, upsert);
}
- Document applyShardKey(@Nullable Class domainType, Document filter, @Nullable Document existing) {
+ Document applyShardKey(Class domainType, Document filter, @Nullable Document existing) {
return applyShardKey(entityOf(domainType), filter, existing);
}
}
-
}
}
diff --git a/src/main/asciidoc/new-features.adoc b/src/main/asciidoc/new-features.adoc
index afa253e62..dc84a6093 100644
--- a/src/main/asciidoc/new-features.adoc
+++ b/src/main/asciidoc/new-features.adoc
@@ -8,6 +8,7 @@
* Support for <>.
* Removal of `_id` flattening for composite Id's when using `MongoTemplate` aggregations.
* Apply pagination when using GridFS `find(Query)`.
+* <> via `@Sharded`.
[[new-features.2-2-0]]
== What's New in Spring Data MongoDB 2.2
diff --git a/src/main/asciidoc/reference/sharding.adoc b/src/main/asciidoc/reference/sharding.adoc
index 2ca3713a2..8678dc217 100644
--- a/src/main/asciidoc/reference/sharding.adoc
+++ b/src/main/asciidoc/reference/sharding.adoc
@@ -1,12 +1,13 @@
[[sharding]]
= Sharding
-MongoDB supports large data sets via sharding, a method for distributing data across multiple machines. Please refer to the https://docs.mongodb.com/manual/sharding/[MongoDB Documentation] to learn how to set up a sharded cluster, its requirements and limitations.
+MongoDB supports large data sets via sharding, a method for distributing data across multiple database servers.
+Please refer to the https://docs.mongodb.com/manual/sharding/[MongoDB Documentation] to learn how to set up a sharded cluster, its requirements and limitations.
Spring Data MongoDB uses the `@Sharded` annotation to identify entities stored in sharded collections as shown below.
====
-[source, java]
+[source,java]
----
@Document("users")
@Sharded(shardKey = { "country", "userId" }) <1>
@@ -21,23 +22,24 @@ public class User {
String country;
}
----
-<1> The properties of the shard key are mapped to the actual field names. See
+<1> The properties of the shard key get mapped to the actual field names.
====
[[sharding.sharded-collections]]
== Sharded Collections
-Spring Data MongoDB does not auto set up sharding for collections nor indexes required for it. The snippet below shows how to do so using the MongoDB client API.
+Spring Data MongoDB does not auto set up sharding for collections nor indexes required for it.
+The snippet below shows how to do so using the MongoDB client API.
====
-[source, java]
+[source,java]
----
MongoDatabase adminDB = template.getMongoDbFactory()
- .getMongoDatabase("admin"); <1>
+ .getMongoDatabase("admin"); <1>
-adminDB.runCommand(new Document("enableSharding", "db")); <2>
+adminDB.runCommand(new Document("enableSharding", "db")); <2>
-Document shardCmd = new Document("shardCollection", "db.users") <3>
+Document shardCmd = new Document("shardCollection", "db.users") <3>
.append("key", new Document("country", 1).append("userid", 1)); <4>
adminDB.runCommand(shardCmd);
@@ -45,24 +47,28 @@ adminDB.runCommand(shardCmd);
<1> Sharding commands need to be run against the _admin_ database.
<2> Enable sharding for a specific database if necessary.
<3> Shard a collection within the database having sharding enabled.
-<4> Set the shard key (Range based sharding in this case).
+<4> Specify the shard key.
+This example uses range based sharding.
====
[[sharding.shard-key]]
== Shard Key Handling
-The shard key consists of a single or multiple properties present in every document within the target collection, and is used to distribute them across shards.
+The shard key consists of a single or multiple properties that must exist in every document in the target collection.
+It is used to distribute documents across shards.
-Adding the `@Sharded` annotation to an entity enables Spring Data MongoDB to do best effort optimisations required for sharded scenarios when using repositories.
-This means essentially adding required shard key information, if not already present, to `replaceOne` filter queries when upserting entities. This may require an additional server round trip to determine the actual value of the current shard key.
+Adding the `@Sharded` annotation to an entity enables Spring Data MongoDB to apply best effort optimisations required for sharded scenarios.
+This means essentially adding required shard key information, if not already present, to `replaceOne` filter queries when upserting entities.
+This may require an additional server round trip to determine the actual value of the current shard key.
-TIP: By setting `@Sharded(immutableKey = true)` no attempt will be made to check if an entities shard key changed.
+TIP: By setting `@Sharded(immutableKey = true)` Spring Data does not attempt to check if an entity shard key was changed.
-Please see the https://docs.mongodb.com/manual/reference/method/db.collection.replaceOne/#upsert[MongoDB Documentation] for further details and the list below for which operations are eligible for auto include the shard key.
+Please see the https://docs.mongodb.com/manual/reference/method/db.collection.replaceOne/#upsert[MongoDB Documentation] for further details.
+The following list contains which operations are eligible for shard key auto-inclusion:
-* `Reactive/CrudRepository.save(...)`
-* `Reactive/CrudRepository.saveAll(...)`
-* `Reactive/MongoTemplate.save(...)`
+* `(Reactive)CrudRepository.save(…)`
+* `(Reactive)CrudRepository.saveAll(…)`
+* `(Reactive)MongoTemplate.save(…)`