@@ -269,11 +269,7 @@ public CommandResult command( DBObject cmd , int options, ReadPreference readPre
269
269
*/
270
270
public CommandResult command ( DBObject cmd , int options , ReadPreference readPrefs , DBEncoder encoder ){
271
271
readPrefs = getCommandReadPreference (cmd , readPrefs );
272
-
273
- // TODO: automate an integration test for this condition
274
- if (getMongo ().isMongosConnection ()) {
275
- cmd .put (QueryOpBuilder .READ_PREFERENCE_META_OPERATOR , readPrefs .toDBObject ());
276
- }
272
+ cmd = wrapCommand (cmd , readPrefs );
277
273
278
274
Iterator <DBObject > i =
279
275
getCollection ("$cmd" ).__find (cmd , new BasicDBObject (), 0 , -1 , 0 , options , readPrefs ,
@@ -288,6 +284,22 @@ public CommandResult command( DBObject cmd , int options, ReadPreference readPre
288
284
return cr ;
289
285
}
290
286
287
+ // Only append $readPreference meta-operator if connected to a mongos, read preference is not primary
288
+ // or secondary preferred,
289
+ // and command is an instance of BasicDBObject. The last condition is unfortunate, but necessary in case
290
+ // the encoder is not capable of encoding a BasicDBObject
291
+ // Due to issues with compatibility between different versions of mongos, also wrap the command in a
292
+ // $query field, so that the $readPreference is not rejected
293
+ private DBObject wrapCommand (DBObject cmd , final ReadPreference readPrefs ) {
294
+ if (getMongo ().isMongosConnection () &&
295
+ !(ReadPreference .primary ().equals (readPrefs ) || ReadPreference .secondaryPreferred ().equals (readPrefs )) &&
296
+ cmd instanceof BasicDBObject ) {
297
+ cmd = new BasicDBObject ("$query" , cmd )
298
+ .append (QueryOpBuilder .READ_PREFERENCE_META_OPERATOR , readPrefs .toDBObject ());
299
+ }
300
+ return cmd ;
301
+ }
302
+
291
303
/**
292
304
* Executes a database command.
293
305
* @see <a href="http://mongodb.onconfluence.com/display/DOCS/List+of+Database+Commands">List of Commands</a>
0 commit comments