Reactive Scala Driver for MongoDB

Asynchronous & Non-Blocking

Use Read Preferences

Read preference describes how MongoDB clients route read operations to members of a replica set. (MongoDB Read Preference Documentation)

The following Read Preferences are supported:

The Read preference can be chosen globally using the MongoConnectionOptions, or for each cursor.

import scala.concurrent.ExecutionContext.Implicits.global

import reactivemongo.bson.BSONDocument
import reactivemongo.api.ReadPreference
import reactivemongo.api.collections.bson.BSONCollection

def readFromSecondary1(collection: BSONCollection) = 
  collection.find(BSONDocument("city" -> "San Francisco")).
    // read from any secondary whenever possible
    cursor[BSONDocument](ReadPreference.secondaryPreferred).
    collect[List]()

The default read preference can also be set in the connection options.

Tag support

Tag sets allow you to specify custom read preferences and write concerns so that your application can target operations to specific members.

Custom read preferences and write concerns evaluate tags sets in different ways. Read preferences consider the value of a tag when selecting a member to read from. Write concerns ignore the value of a tag to when selecting a member, except to consider whether or not the value is unique.

MongoDB Read Preference Documentation

If you properly tagged the servers of your replica set, then you can use Tag-aware Read Preferences.

Let’s suppose that the replica set is configured that way:

{
    "_id" : "rs0",
    "version" : 2,
    "members" : [
             {
                     "_id" : 0,
                     "host" : "mongodb0.example.net:27017",
                     "tags" : {
                             "dc": "NYC",
                             "disk": "ssd"
                     }
             },
             {
                     "_id" : 1,
                     "host" : "mongodb1.example.net:27017",
                     "tags" : {
                             "dc": "NYC"
                     }
             },
             {
                     "_id" : 2,
                     "host" : "mongodb2.example.net:27017",
                     "tags" : {
                             "dc": "Paris"
                     }
             }
     ]
}

Then we can tell ReactiveMongo to query only from the nodes that are tagged with dc: "NYC":

import scala.concurrent.ExecutionContext.Implicits.global

import reactivemongo.bson.BSONDocument
import reactivemongo.api.ReadPreference
import reactivemongo.api.collections.bson.BSONCollection

def readFromSecondary2(collection: BSONCollection) = 
  collection.find(BSONDocument("city" -> "San Francisco")).
    // read from any secondary tagged with `dc: "NYC"`
    one[BSONDocument](ReadPreference.secondaryPreferred(
      tag = BSONDocument("dc" -> "NYC")))