Introduction
In previous post I wrote about MongoDB optimization by reading from secondary nodes.
In this post I will show you how to use this option in Spring Boot project.
Using secondary reads globally
If you use Spring Data MongoDB on daily basis, you probably create MongoRepository
like this:
1
2
3
4
@Document(collection = "books")
data class Book(@Id val id: String, val title: String)
interface BooksRepository : MongoRepository<Book, String>
SimpleMongoRepository
which is basic implementation of MongoRepository
uses MongoTemplate
to execute queries.
So if you want to switch all reads to for example secondaryPreferred
you can just create new bean with the readPreference
option set properly. Like this:
1
2
3
4
5
6
7
8
9
10
@Configuration
class MongoConfig {
@Bean
fun mongoTemplate(@Value("\${mongoUri}") mongoUri: String): MongoTemplate {
val mongoTemplate = MongoTemplate(SimpleMongoClientDatabaseFactory(mongoUri))
mongoTemplate.setReadPreference(ReadPreference.secondaryPreferred())
return mongoTemplate
}
}
After setting this bean in your project all repositories will use MongoTemplate
which will execute queries with readPreference
set to secondaryPreferred
.
Using secondary reads on specific queries
Unfortunately, there is no option to set readPreference
option on specific queries. Or maybe only I don’t know how to do that and you can give me a hint in comments.
The only option which I found is to use annotation
1
2
3
4
interface BooksRepository : MongoRepository<Book, String> {
@Meta(flags = [CursorOption.SECONDARY_READS])
override fun findAll(): List<Book>
}
Or if you code queries by your own using MongoOperations
or FluentMongoOperations
you can allow secondary reads like that:
1
2
3
4
5
6
7
8
9
10
@Repository
class MyBooksRepository(private val mongoOperations: MongoOperations) {
fun findAll(): List<Book> =
mongoOperations.find(
Query
.query(Criteria())
.allowSecondaryReads(),
Book::class.java
)
}
But be careful!
This option set readPreference
only to primaryPreferred
(you can see it in MongoTemplate
implementation).
This means that queries will be executed on primary
anyway, unless primary
becomes unavailable.
So if you want to execute some of queries with different readPrefence
you have to create many MongoTemplate
with option set appropriately. Then use the appropriate MongoTemplate
for specific queries.
Comments powered by Disqus.