[JAVA-1877] readPreference and db commands Created: 29/Jun/15  Updated: 11/Sep/19  Resolved: 30/Jun/15

Status: Closed
Project: Java Driver
Component/s: Command Operations
Affects Version/s: 3.0.0, 3.0.2
Fix Version/s: None

Type: Task Priority: Major - P3
Reporter: Marco Bonezzi Assignee: Unassigned
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Hi,

It looks like the readPreference for a db command is not always working as expected.

1 case:
readPreference needs to be set as a document option even if already set in the connection URL. i.e.

MongoClientURI connectionString = new MongoClientURI("mongodb://localhost:27017/myDB?w=2&readPreference=nearest&maxPoolSize=1100");

This is the document used:

Document point = new Document("type", "Point").append("coordinates", coordinates);
 
			Document geoQuery = new Document();
			geoQuery.append("geoNear", "places");
			geoQuery.append("near", point);
			geoQuery.append("query", condition);
			geoQuery.append("spherical", "true");
			geoQuery.append("limit", 1000);
			geoQuery.append("maxDistance", 50000);
			//geoQuery.append("$readPreference", new Document("mode", "nearest")); 

If this {{//geoQuery.append("$readPreference", new Document("mode", "nearest")) }} is commented, the queries will always go to the primary.
If it is not commented it would balance across primary and secondaries based on ping (as expected by using nearest).

2nd case:
With the following code, readPreference set to nearest seems to work as expected.

MongoClient m = new MongoClient(new MongoClientURI("mongodb://localhost:37019/sprint?w=2&readPreference=nearest&maxPoolSize=1100"));

BasicDBObject myCmd = new BasicDBObject();
        myCmd.append("geoNear", "places");
        myCmd.append("type", "Point");
        double[] loc = {101.7252, 3.1141};
        myCmd.append("near", loc);
        myCmd.append("spherical", true);
        myCmd.append("maxDistance", 100000);
CommandResult r = db.command(myCmd);

The node performing the queries is checked by using db.setLogLevel(3) and looking at the commands on each node.

If any other information is required please let me know.

Thank you,

Regards,

Marco



 Comments   
Comment by Marco Bonezzi [ 30/Jun/15 ]

Hi Jeff,

Thanks for your reply!
That definitely make sense, I didn't know about the option to define the readPreference as an option inside the db.runCommand.

The issue was related to a sharded cluster + replica set, where all geoNear commands were going to the primary. Unfortunately in a sharded collection $near cannot be used, which would have simplified the situation.

Thank you for the clarification on this, I believe this ticket can now be marked as solved.

Kind Regards,
Marco

Comment by Jeffrey Yemin [ 29/Jun/15 ]

Hi Marko,

I think you're running in to JAVA-1802, which is a documentation issue. The correct solution for your situation would be to use the MongoDatabase.runCommand overload that takes an explicit ReadPreference parameter. I would not expect the addition of a $readPreference to work when connected directly to a replica set, though it would work when connected to a sharded cluster.

The other option would be to use a normal query using the $near operator, as the driver will respect the configured read preference for normal queries.

The reasons for the generic command method of MongoDatabase to ignore the default read preference are enumerated in the server selection specification. See the section titled "General command method going to primary".

Generated at Thu Feb 08 08:55:45 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.