ReactiveMongo/ReactiveMongo — pull request #227 by skirino (2014-12-11 08:19:04+00:00)
Title: Read preference support for sharded cluster

Hi,

We are using ReactiveMongo with [Play-ReactiveMongo plugin](https://github.com/ReactiveMongo/Play-ReactiveMongo) to access our sharded mongo cluster. Queries to the mongo cluster are proxied by mongos processes, so each mongos has to choose an appropriate replica set member to send each query to, based on the read preference of the query.

Unfortunately it turns out that (as I understand) the current version of ReactiveMongo does not send read preferences to mongos. If one passes a `ReadPreference` to e.g. `GenericQueryBuilder#cursor`, most of that information is internally truncated and only `slaveOk` bit is passed to mongos, resulting in an unintended query routing. For example, queries with `PrimaryPreferred` are sent to secondary members.

In this pull request I'm adding basic support of read preference for sharded cluster:
I just include `$readPreference` field to query document as in [ruby driver implementation](https://github.com/mongodb/mongo-ruby-driver/blob/1.11.1/lib/mongo/cursor.rb#L681) and [C# driver release note](https://github.com/mongodb/mongo-csharp-driver/releases/tag/v1.6.1.4678) (I just couldn't find any official documents on `$readPreference` specs).

A few things on which I'd like some comments/suggestions:
- "Sending tag-sets to mongos" is not yet addressed.
- I'm stuck with `filterTag: Option[BSONDocument => Boolean]`.
Is it appropriate to simply change this to e.g. `tag: Option[BSONDocument]`?
- Also read preferences of `Command` queries are not yet correctly handled.
- I fixed a typo in scala symbols in https://github.com/skirino/ReactiveMongo/commit/8cb54a80379a2b1a5c0d9ed064d840c76e2659b0.
- Please tell me if backward compatibility is necessary here; I will redefine the old symbols as aliases to new ones.
- If this pull request is acceptable, I will also modify [Play-ReactiveMongo plugin](https://github.com/ReactiveMongo/Play-ReactiveMongo) when I have time.

Thanks in advance!