Usage

Database Sharding Strategy usage

How to use?

  1. Create a custom MongoTemplate bean using the snippet given in this example .


@Configuration
public class DatabaseShardedMongoConfiguration {

    private static final String SPRING_MONGO_DB_URI_DATABASE_SHARDED_DS0 = "spring.mongodb.sharded.database.ds0.uri";
    private static final String SPRING_MONGO_DB_URI_DATABASE_SHARDED_DS1 = "spring.mongodb.sharded.database.ds1.uri";
    private static final String SPRING_MONGO_DB_URI_DATABASE_SHARDED_DS2 = "spring.mongodb.sharded.database.ds2.uri";

    @Autowired
    private Environment environment;

    @Bean
    public MongoDatabaseFactory ds0ShardedMongoDbFactory() {
        return new SimpleMongoClientDatabaseFactory(environment.getProperty(SPRING_MONGO_DB_URI_DATABASE_SHARDED_DS0));
    }

    @Bean
    public MongoDatabaseFactory ds1ShardedMongoDbFactory() {
        return new SimpleMongoClientDatabaseFactory(environment.getProperty(SPRING_MONGO_DB_URI_DATABASE_SHARDED_DS1));
    }

    @Bean
    public MongoDatabaseFactory ds2ShardedMongoDbFactory() {
        return new SimpleMongoClientDatabaseFactory(environment.getProperty(SPRING_MONGO_DB_URI_DATABASE_SHARDED_DS2));
    }

    @Bean("databaseShardedMongoTemplate")
    public MongoTemplate databaseShardedMongoTemplate() {
        DatabaseShardingOptions shardingOptions = DatabaseShardingOptions.withIntegerStreamHints(IntStream.range(0, 3));
        Map<String, MongoDatabaseFactory> factoryMap = new HashMap<String, MongoDatabaseFactory>() {{
            put(String.valueOf(0), ds0ShardedMongoDbFactory());
            put(String.valueOf(1), ds1ShardedMongoDbFactory());
            put(String.valueOf(2), ds2ShardedMongoDbFactory());
        }};
        return new DatabaseShardedMongoTemplate(factoryMap, shardingOptions);
    }
}
  1. Implement your entity classes from DatabaseShardedEntity like the example given below. This will ensure the writes to the entity gets routed to the right database.

// Sample TestShardedEntity
@Document("TEST")
@Data
@FieldNameConstants
public class TestShardedEntity implements CollectionShardedEntity {

    @Id
    private String id;

    @Indexed(unique = true)
    private String indexedField;

    @Override
    public String resolveDatabaseHint() {
        return String.valueOf(indexedField.charAt(0) - '0');
    }
}
  1. Autowire the databaseShardedMongoTemplate and use it wherever required.

Sharding Hint

In order to route the write queries, the entities are supposed to implement from DatabaseShardedEntity. But, the find queries can take place with different criterion, with different fields. In order to route the find query to the right database, sharding hint is used.

import java.util.Optional;

public class TestRepository {

    @Autowired
    @Qualifier("databaseShardedMongoTemplate")
    private MongoTemplate databaseShardedMongoTemplate;

    public Optional<TestShardEntity> findById() {
        ShardingHintManager.setDatabaseHint("3");
        return Optional.ofNullable(
                databaseShardedMongoTemplate.findById(
                        "6427b9327a2cad734d5ff051",
                        TestShardEntity.class));
    }
}

If the sharding hint is not set, methods will throw a UnresolvableShardException.

Using Hint Resolution Callback

Refer to the Collection Sharding Strategy document to know how to use HintResolutionCallback for resolving the Sharding hint by registering callbacks to the MongoTemplate object.

Last updated