Skip to content

Commit

Permalink
DOCSP-46438: Read preference (#3260)
Browse files Browse the repository at this point in the history
* DOCSP-46438: Read preference

* edits

* tip

* fix test

* fix

* code

* JS feedback

* Switch example to SECONDARY_PREFERRED

* JT feedback

* apply phpcbf formatting

* tests

---------

Co-authored-by: Jérôme Tamarelle <[email protected]>
  • Loading branch information
norareidy and GromNaN authored Feb 7, 2025
1 parent 4c45ea8 commit 08d54d8
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 4 deletions.
109 changes: 109 additions & 0 deletions docs/fundamentals/read-operations.txt
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,8 @@ method:
results in a specified order based on field values
- :ref:`laravel-retrieve-one` uses the ``first()`` method to return the first document
that matches the query filter
- :ref:`laravel-read-pref` uses the ``readPreference()`` method to direct the query
to specific replica set members

.. _laravel-skip-limit:

Expand Down Expand Up @@ -606,3 +608,110 @@ field.

To learn more about the ``orderBy()`` method, see the
:ref:`laravel-sort` section of this guide.

.. _laravel-read-pref:

Set a Read Preference
~~~~~~~~~~~~~~~~~~~~~

To specify which replica set members receive your read operations,
set a read preference by using the ``readPreference()`` method.

The ``readPreference()`` method accepts the following parameters:

- ``mode``: *(Required)* A string value specifying the read preference
mode.

- ``tagSets``: *(Optional)* An array value specifying key-value tags that correspond to
certain replica set members.

- ``options``: *(Optional)* An array value specifying additional read preference options.

.. tip::

To view a full list of available read preference modes and options, see
:php:`MongoDB\Driver\ReadPreference::__construct </manual/en/mongodb-driver-readpreference.construct.php>`
in the MongoDB PHP extension documentation.

The following example queries for documents in which the value of the ``title``
field is ``"Carrie"`` and sets the read preference to ``ReadPreference::SECONDARY_PREFERRED``.
As a result, the query retrieves the results from secondary replica set
members or the primary member if no secondaries are available:

.. tabs::

.. tab:: Query Syntax
:tabid: query-syntax

Use the following syntax to specify the query:

.. literalinclude:: /includes/fundamentals/read-operations/ReadOperationsTest.php
:language: php
:dedent:
:start-after: start-read-pref
:end-before: end-read-pref

.. tab:: Controller Method
:tabid: controller

To see the query results in the ``browse_movies`` view, edit the ``show()`` function
in the ``MovieController.php`` file to resemble the following code:

.. io-code-block::
:copyable: true

.. input::
:language: php

class MovieController
{
public function show()
{
$movies = Movie::where('title', 'Carrie')
->readPreference(ReadPreference::SECONDARY_PREFERRED)
->get();

return view('browse_movies', [
'movies' => $movies
]);
}
}

.. output::
:language: none
:visible: false

Title: Carrie
Year: 1952
Runtime: 118
IMDB Rating: 7.5
IMDB Votes: 1458
Plot: Carrie boards the train to Chicago with big ambitions. She gets a
job stitching shoes and her sister's husband takes almost all of her pay
for room and board. Then she injures a finger and ...

Title: Carrie
Year: 1976
Runtime: 98
IMDB Rating: 7.4
IMDB Votes: 115528
Plot: A shy, outcast 17-year old girl is humiliated by her classmates for the
last time.

Title: Carrie
Year: 2002
Runtime: 132
IMDB Rating: 5.5
IMDB Votes: 7412
Plot: Carrie White is a lonely and painfully shy teenage girl with telekinetic
powers who is slowly pushed to the edge of insanity by frequent bullying from
both her classmates and her domineering, religious mother.

Title: Carrie
Year: 2013
Runtime: 100
IMDB Rating: 6
IMDB Votes: 98171
Plot: A reimagining of the classic horror tale about Carrie White, a shy girl
outcast by her peers and sheltered by her deeply religious mother, who unleashes
telekinetic terror on her small town after being pushed too far at her senior prom.
19 changes: 19 additions & 0 deletions docs/includes/fundamentals/read-operations/ReadOperationsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use App\Models\Movie;
use Illuminate\Support\Facades\DB;
use MongoDB\Driver\ReadPreference;
use MongoDB\Laravel\Tests\TestCase;

class ReadOperationsTest extends TestCase
Expand Down Expand Up @@ -33,6 +34,8 @@ protected function setUp(): void
['title' => 'movie_a', 'plot' => 'this is a love story'],
['title' => 'movie_b', 'plot' => 'love is a long story'],
['title' => 'movie_c', 'plot' => 'went on a trip'],
['title' => 'Carrie', 'year' => 1976],
['title' => 'Carrie', 'year' => 2002],
]);
}

Expand Down Expand Up @@ -164,4 +167,20 @@ public function arrayElemMatch(): void
$this->assertNotNull($movies);
$this->assertCount(2, $movies);
}

/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testReadPreference(): void
{
// start-read-pref
$movies = Movie::where('title', 'Carrie')
->readPreference(ReadPreference::SECONDARY_PREFERRED)
->get();
// end-read-pref

$this->assertNotNull($movies);
$this->assertCount(2, $movies);
}
}
13 changes: 13 additions & 0 deletions docs/includes/query-builder/QueryBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use MongoDB\BSON\ObjectId;
use MongoDB\BSON\Regex;
use MongoDB\Collection;
use MongoDB\Driver\ReadPreference;
use MongoDB\Laravel\Tests\TestCase;

use function file_get_contents;
Expand Down Expand Up @@ -452,6 +453,18 @@ public function testCursorTimeout(): void
$this->assertInstanceOf(\Illuminate\Support\Collection::class, $result);
}

public function testReadPreference(): void
{
// begin query read pref
$result = DB::table('movies')
->where('runtime', '>', 240)
->readPreference(ReadPreference::SECONDARY_PREFERRED)
->get();
// end query read pref

$this->assertInstanceOf(\Illuminate\Support\Collection::class, $result);
}

public function testNear(): void
{
$this->importTheaters();
Expand Down
34 changes: 30 additions & 4 deletions docs/query-builder.txt
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,7 @@ to use the following MongoDB-specific query operations:
- :ref:`Run MongoDB Query API operations <laravel-query-builder-whereRaw>`
- :ref:`Match documents that contain array elements <laravel-query-builder-elemMatch>`
- :ref:`Specify a cursor timeout <laravel-query-builder-cursor-timeout>`
- :ref:`Specify a read preference <laravel-query-builder-read-pref>`
- :ref:`Match locations by using geospatial searches <laravel-query-builder-geospatial>`

.. _laravel-query-builder-exists:
Expand Down Expand Up @@ -1033,6 +1034,31 @@ to specify a maximum duration to wait for cursor operations to complete.
`MongoDB\Collection::find() <https://www.mongodb.com/docs/php-library/current/reference/method/MongoDBCollection-find/>`__
in the PHP Library documentation.

.. _laravel-query-builder-read-pref:

Specify a Read Preference Example
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

You can control how the {+odm-short+} directs read operations to replica
set members by setting a read preference.

The following example queries the ``movies`` collection for documents
in which the ``runtime`` value is greater than ``240``. The example passes a
value of ``ReadPreference::SECONDARY_PREFERRED`` to the ``readPreference()``
method, which sends the query to secondary replica set members
or the primary member if no secondaries are available:

.. literalinclude:: /includes/query-builder/QueryBuilderTest.php
:language: php
:dedent:
:start-after: begin query read pref
:end-before: end query read pref

.. tip::

To learn more about read preferences, see :manual:`Read Preference
</core/read-preference/>` in the MongoDB {+server-docs-name+}.

.. _laravel-query-builder-geospatial:

Match Locations by Using Geospatial Operations
Expand Down Expand Up @@ -1061,7 +1087,7 @@ in the {+server-docs-name+}.
.. _laravel-query-builder-geospatial-near:

Near a Position Example
~~~~~~~~~~~~~~~~~~~~~~~
^^^^^^^^^^^^^^^^^^^^^^^

The following example shows how to use the ``near`` query operator
with the ``where()`` query builder method to match documents that
Expand All @@ -1081,7 +1107,7 @@ in the {+server-docs-name+}.
.. _laravel-query-builder-geospatial-geoWithin:

Within an Area Example
~~~~~~~~~~~~~~~~~~~~~~
^^^^^^^^^^^^^^^^^^^^^^

The following example shows how to use the ``geoWithin``
query operator with the ``where()``
Expand All @@ -1098,7 +1124,7 @@ GeoJSON object:
.. _laravel-query-builder-geospatial-geoIntersects:

Intersecting a Geometry Example
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The following example shows how to use the ``geoInstersects``
query operator with the ``where()`` query builder method to
Expand All @@ -1114,7 +1140,7 @@ the specified ``LineString`` GeoJSON object:
.. _laravel-query-builder-geospatial-geoNear:

Proximity Data for Nearby Matches Example
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The following example shows how to use the ``geoNear`` aggregation operator
with the ``raw()`` query builder method to perform an aggregation that returns
Expand Down

0 comments on commit 08d54d8

Please sign in to comment.