# Read Preferences

MongoDB 2.2 and version 1.3.0 of the driver add support for » read preferences, which allow control over how queries are directed to mongod instances in a replica set environment. Read preferences may be specified on either a per-connection, per-database, or per-collection basis. Preferences defined at a higher level will be inherited by default (e.g. MongoCollection will inherit read preferences defined on the corresponding MongoDB instance).

Read preferences are specified with a combination of modes and tag sets. Modes determine how mongod instances are prioritized, while » tag sets specify criteria for eligible mongod instances. Mongod instances are only eligible if they are within a 15ms difference in ping time from the nearest mongod instance.

### Read Preference Modes

Warning

All read preference modes except `MongoClient::RP_PRIMARY` may return stale data as secondaries replicate operations from the primary with some delay. Ensure that your application can tolerate stale data if you choose to use a mode other than `MongoClient::RP_PRIMARY`.

- `MongoClient::RP_PRIMARY`

  All read operations use only the current replica set primary. This is the default. If the primary is unavailable, read operations will produce an exception.

  This mode is incompatible with use of tag sets. Specifying a tag set with `MongoClient::RP_PRIMARY` will result in an exception.

- `MongoClient::RP_PRIMARY_PREFERRED`

  In most situations, operations read from the primary member of the set. However, if the primary is unavailable, as is the case during failover situations, operations read from secondary members.

  When the read preference includes a tag set, the client reads first from the primary, if available, and then from secondaries that match the specified tags. If no secondaries have matching tags, the read operation will produce an exception.

  Warning

  Version 2.2 of mongos added full support for read preferences. When connecting to older mongos instances, `MongoClient::RP_PRIMARY_PREFERRED` will send queries to secondaries.

- `MongoClient::RP_SECONDARY`

  Operations read only from the secondary members of the set. If no secondaries are available, read operations will produce an exception.

  Most sets have at least one secondary, but there are situations where there may be no available secondary. For example, a set with a primary, a secondary, and an arbiter may not have any secondaries if a member is in recovering state or unavailable.

  When the read preference includes a tag set, the client attempts to find secondary members that match the specified tag set and directs reads to a random secondary from among the nearest group. If no secondaries have matching tags, the read operation will produce an exception.

- `MongoClient::RP_SECONDARY_PREFERRED`

  In most situations, operations read from secondary members, but in situations where the set consists of a single primary with no other members, the read operation will use the set's primary.

  When the read preference includes a tag set, the client attempts to find a secondary member that matches the specified tag set and directs reads to a random secondary from among the nearest group. If no secondaries have matching tags, the read operation will produce an exception.

- `MongoClient::RP_NEAREST`

  The driver reads from a random member of the set that has a ping time that is less than 15ms slower than the member with the lowest ping time. Reads in the `MongoClient::RP_NEAREST` mode do not consider the member's type and may read from both primaries and secondaries.

  Set this mode to minimize the effect of network latency on read operations without preference for current or stale data.

  If you specify a tag set, the client attempts to find a member that matches the specified tag set and directs reads to a random node from among the nearest group.

  > Note:

  > All operations read from the nearest member of the replica set that matches the specified read preference mode. The `MongoClient::RP_NEAREST` mode prefers low latency reads over a member's primary or secondary status.

### Tag Sets

» Tag sets allow you to specify criteria so that your application can target read operations to specific members, based on custom parameters. Tag sets make it possible to ensure that read operations target members in a particular data center or target mongod instances designated for a particular class of operations, such as reporting or analytics.

You can specify tag sets with the following read preference modes:

- `MongoClient::RP_PRIMARY_PREFERRED`

- `MongoClient::RP_SECONDARY`

- `MongoClient::RP_SECONDARY_PREFERRED`

- `MongoClient::RP_NEAREST`

You cannot specify tag sets with the `MongoClient::RP_PRIMARY` read preference mode. Tags apply only when selecting a secondary member of a set, except for the when in the nearest mode.

### Specifying Read Preferences

Read preferences may be specified in either the connection URI provided to MongoClient::__construct(), which uses a query string syntax, or via setter methods on the core classes, which use an array syntax for tag sets.

When specifying read preference modes in a query string, the tag sets for the `readPreferenceTags` value should be a comma-delimited sequence of colon-delimited key/value pairs.

> Note:

> Each tag set defined in the query string will use the `readPreferenceTags` name. Unlike how PHP might handle URL query strings, successive values for `readPreferenceTags` will not overwrite each other. The driver will collect tag sets in the order they appear in the query string.

Warning

If the driver cannot find a matching tag set the read will fail! It is your responsibility of providing suitable fallback, such as an empty `readPreferenceTags` value to fallback to "no tag set preference".

Example #1 Connection URI read preferences with query string syntax

`<?php
// Prefer the nearest server with no tag preference
$uri = 'mongodb://rs1.example.com,rs2.example.com/';
$uri .= '?readPreference=nearest';
$m = new MongoClient($uri, array('replicaSet' => 'rs'));
// Pick the nearest server in the "east" data center
$uri = 'mongodb://rs1.example.com,rs2.example.com/';
$uri .= '?readPreference=nearest';
$uri .= '&readPreferenceTags=dc:east';
$m = new MongoClient($uri, array('replicaSet' => 'rs'));
// Prefer the nearest server in the "east" data center also used for reporting,
// but fall back to a server in the "west" data center
$uri = 'mongodb://rs1.example.com,rs2.example.com/';
$uri .= '?readPreference=nearest';
$uri .= '&readPreferenceTags=dc:east,use:reporting';
$uri .= '&readPreferenceTags=dc:west';
$m = new MongoClient($uri, array('replicaSet' => 'rs'));
// Prefer the nearest server in the "east" data center, then a server in the
// "west" data center, and finally fall back to no tag set preference
$uri = 'mongodb://rs1.example.com,rs2.example.com/';
$uri .= '?readPreference=nearest';
$uri .= '&readPreferenceTags=dc:east';
$uri .= '&readPreferenceTags=dc:west';
$uri .= '&readPreferenceTags=';
$m = new MongoClient($uri, array('replicaSet' => 'rs'));
?>`

Example #2 Setting read preferences with array syntax for tag sets

`<?php
$m = new MongoClient('mongodb://rs1.example.com,rs2.example.com', array(
'replicaSet' => 'rs',
));
// Prefer the nearest server with no tag preference
$m->setReadPreference(MongoClient::RP_NEAREST, array());
// Pick the nearest server in the "east" data center
$m->setReadPreference(MongoClient::RP_NEAREST, array(
array('dc' => 'east'),
));
// Prefer the nearest server in the "east" data center also used for reporting,
// but fall back to a server in the "west" data center
$m->setReadPreference(MongoClient::RP_NEAREST, array(
array('dc' => 'east', 'use' => 'reporting'),
array('dc' => 'west'),
));
// Prefer the nearest server in the "east" data center, then a server in the
// "west" data center, and finally fall back to no tag set preference
$m->setReadPreference(MongoClient::RP_NEAREST, array(
array('dc' => 'east'),
array('dc' => 'west'),
array(),
));
?>`