Overview
All MongoDB drivers follow a defined algorithm when selecting a server to read or write
from. By using the server_selector property of MongoClient, you can customize this
algorithm to choose the server that works best for your application.
Important
Customizing the server-selection algorithm can have unintended consequences, such as degraded read or write performance.
Customized Selection Algorithm
When PyMongo executes a read operation, it performs the following steps, in order, to select a MongoDB deployment:
From the list of known servers, PyMongo selects all servers that match the active read preference.
If at least one readable server exists, PyMongo calls the user-defined server-selector function and passes in the list from the previous step.
PyMongo applies the
localThresholdMSconnection setting to the list of servers returned from the function.PyMongo selects a server at random from the servers still on the list and executes the operation against this server.
When PyMongo executes a write operation, it begins by selecting all writeable servers, not just those that match the active read preference. The remaining steps are identical.
To learn more about the default server-selection algorithm, which the driver follows
when you don't use the server_selector argument, see
Server Selection Algorithm in the
MongoDB Server manual.
Example: Select Servers on localhost
When using a sharded cluster with multiple mongos servers, you might want to prefer
deployments running on localhost. Operations against these deployments
usually have lower latency and higher throughput.
This example shows how to customize the server-selection algorithm to favor
servers running on localhost.
First, write a Python function to select your preferred servers. The server-selection function must meet the following criteria:
Accepts a list of
ServerDescriptionobjects as a parameterReturns the list of
ServerDescriptionobjects suitable for the read or write operationDoesn't create or modify any
ServerDescriptionobjects
The following example defines a function named prefer_local that accepts and returns a list of
ServerDescription objects:
def prefer_local(server_descriptions): ... return servers # list containing preferred servers
Next, implement your server-selection logic in the function body. You can use any
property defined in the ServerDescription class to select your preferred servers.
To return only MongoDB deployments running on localhost, this example loops on the
servers in server_descriptions and checks the address property of each server
for the value "localhost":
def prefer_local(server_descriptions): servers = [ server for server in server_descriptions if server.address[0] == "localhost" ] return servers
Next, consider the case when your algorithm finds no matching servers. If your function
returns an empty list, your application can't communicate with MongoDB. Therefore,
return a list containing at least one ServerDescription object from your function.
In this example, if no matching server is found, the prefer_local function returns
the list of servers originally passed as an argument:
def prefer_local(server_descriptions): servers = [ server for server in server_descriptions if server.address[0] == "localhost" ] if not servers: return server_descriptions return servers
Finally, instruct PyMongo to use your function. To do so, call the MongoClient
constructor and pass the server_selector argument with your function name as the value.
Select the Synchronous or Asynchronous tab to see the corresponding
code:
client = pymongo.MongoClient("mongodb://<db_username>:<db_password>@<hostname>:<port>", server_selector=prefer_local)
client = pymongo.AsyncMongoClient("mongodb://<db_username>:<db_password>@<hostname>:<port>", server_selector=prefer_local)
API Documentation
For more information about customizing PyMongo's server-selection algorithm, see the following API documentation: