spring-data-mongodb icon indicating copy to clipboard operation
spring-data-mongodb copied to clipboard

Add readPreference secondaryPreferred to QueryCursorPreparer

Open peterfouquet0001 opened this issue 3 years ago • 9 comments

Hello, we will execute find queries on the secondaries in our mongo cluster, but the CursorOption SECONDARY_READS is mapped to primaryPreferred in MongoTemplate.QueryCursorPreparer.getReadPreference. The mapping isn't customizable and the code isn't extendable by subclassing the MongoTemplate. Please add a mapping for CursorOption SECONDARY_PREFRERRED with secondaryPreferred. Kind regards Peter

peterfouquet0001 avatar Jun 15 '21 06:06 peterfouquet0001

CursorOption is a legacy from the early MongoDB driver where DBCollection.find(…) accepted a flag parameter called option. See the historical Javadoc of QUERYOPTION_*. The modern driver with MongoCollection does not accept options at all, however, the mentioned code is in place for compatibility reasons.

If you want to customize ReadPreference, please set it directly on MongoTemplate

mp911de avatar Jun 15 '21 08:06 mp911de

How can I set a different ReadPreference for a single query? With the mongo driver i use mongoCollection.withReadPreference(ReadPreference.secondaryPreferred()) to execute these query on a secondary, while all other queries where execute with the defaultReadPreference on the primary. When I change the read preference for the mongo template, I change the read preference for all queries. Also i will configure these option for a query with the @Meta annotation. Or is there any other way to execute a single query with a different read preference. {code} @Override @Meta(flags = {SLAVE_OK}) @Query("{}") List<LeverDefinition> findAll(); {code}

peterfouquet0001 avatar Jun 15 '21 11:06 peterfouquet0001

You could override MongoTemplate's MongoCollection<Document> prepareCollection(MongoCollection<Document> collection) to supply a read preference based on the collection. Other than that, there's no method that would accept sufficient context to determine a ReadPreference.

mp911de avatar Jun 16 '21 06:06 mp911de

When I override the prepareCollection I can't set the read preference for a single query and i can't set the read preference for an annotation based query, because these queries are using the mongo template implizit. The only way to support query specific read preferences is extending the CursorOptions and the mapping in the QueryCursorPreparer

peterfouquet0001 avatar Jun 16 '21 14:06 peterfouquet0001

Let me take your request to our team to check whether we can come up with something. For WriteConcern we have a WriteConcernResolver taking a MongoAction as context parameter.

mp911de avatar Jun 16 '21 14:06 mp911de

HI, do you have a solution to configure the ReadPreference for a single query? Kind regards Peter

peterfouquet0001 avatar Jun 28 '21 06:06 peterfouquet0001

Right now, we do not have the means to configure ReadPreference on a per-query basis. Introducing a ReadPreferenceResolver is something that we want to explore in combination with a possibility of declarative configuration that can be used with repository query methods.

mp911de avatar Jun 29 '21 06:06 mp911de

Hey @mp911de, adding some more info that might be useful here. We have a similar use case where we would like to set the read preference per query (basically we always read from the secondary, but when we don't find anything we then try to read from the primary). To work around this, we are setting the readPreference on the Template to secondary before reading for the first time and setting it to primary before retrying. After some investigation, we found that for our particular implementation which is multithreaded, this causes race conditions. It would be highly appreciated if it was possible to set the readConcern on a query basis the same way it is possible to do it via mongo shell

david-azevedo avatar Feb 10 '22 16:02 david-azevedo

And why does the SECONDARY_READS cursor option return a primaryPreferred() ReadPreference? Shouldn't it return either secondary() or secondaryPreferred() ?

Maybe I am missing something.. can anyone explain

Liveitabhi14 avatar Jul 26 '22 17:07 Liveitabhi14

Fixed via #4286.

mp911de avatar Feb 28 '23 14:02 mp911de