Home Setting readPreference option in Spring Data MongoDB projects
Post
Cancel

Setting readPreference option in Spring Data MongoDB projects

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.

This post is licensed under CC BY 4.0 by the author.

How to easily optimize replica set resource consumption & performance in MongoDB?

Using declarative HTTP client in Spring Shell project with Kotlin

Comments powered by Disqus.