Reputation: 407
I am using Spring Boot and Spring Data MongoDB to interface with an underlying sharded MongoDB cluster. My Spring Boot Application access the cluster via a mongos
router.
Using Spring Data MongoDB, you can specify the collection an object is persisted to via @Document(collection = "nameOfCollection")
, or it defaults to the class name (first letter lowercase). These collections do not need to exist before-hand; they can be created at runtime.
To shard a collection in MongoDB, you need to
1 - Enable sharding on the Database: sh.enableSharding("myDb")
2 - Shard the collection on a sharded database: sh.shardCollection("myDb.myCollection", {id:"hashed"})
Assuming there is an existing sharded database, does Spring Data MongoDB offer a way to shard a collection with a shard key? As far as I can tell, I cannot shard a collection with Spring, and therefore must configure the sharded collection before my Boot application runs. I find it odd that Spring would allow me to use undefined collections, but does not provide a way to configure the collection.
Edit: I have seen both Sharding with spring mongo and How configuring access to a sharded collection in spring-data for mongo? which refer more to the deployment of a sharded MongoDB cluster. This question assumes all the plumbing is there and that the collection itself simply must be sharded.
Upvotes: 8
Views: 8750
Reputation: 21
Was running into the same problem with our update queries that internally used a save().
How it was solved?
So I now have overridden the spring-data-mongo core dependency from spring-boot-starter which is 2.1.x by 3.x release in our model which is now supporting @Sharded() annotation .
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>3.1.5</version>
</dependency>
allows you to say
@Document(collection = "hotelsdevice")
@Sharded(shardKey = { "device" })
public class Hotel extends BaseModel {
which internally is now able to tell the underlying mongo which is our shardkey. I am assuming this will further fix our count() queries too which were failing due to the same error "query need to target a shard "
Upvotes: 2
Reputation: 474
Despite this question being old, I've got the same question, and it looks like there is away to provide custom sharding key since recently.
Annotation-based Shard Key configuration is available on spring-data-mongodb:3.x
,
https://docs.spring.io/spring-data/mongodb/docs/3.0.x/reference/html/#sharding
@Document("users")
@Sharded(shardKey = { "country", "userId" })
public class User {
@Id
Long id;
@Field("userid")
String userId;
String country;
}
As of today spring-boot-starter-mongodb
comes with 2.x version though.
Upvotes: 4
Reputation: 407
Even though this is not a Spring Data solution, a potential workaround is posed in how to execute mongo admin command from java, where DB
can be acquired from a Spring MongoTemplate
.
DB db = mongo.getDB("admin");
DBObject cmd = new BasicDBObject();
cmd.put("shardcollection", "testDB.x");
cmd.put("key", new BasicDBObject("userId", 1));
CommandResult result = db.command(cmd);
Upvotes: 1