Skip to content

Merge 4.1 into 4.2 #2886

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 120 additions & 25 deletions docs/fundamentals/read-operations.txt
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,11 @@ retrieve documents that meet the following criteria:

Use the following syntax to specify the query:

.. code-block:: php

$movies = Movie::where('year', 2010)
->where('imdb.rating', '>', 8.5)
->get();
.. literalinclude:: /includes/fundamentals/read-operations/ReadOperationsTest.php
:language: php
:dedent:
:start-after: start-query
:end-before: end-query

.. tab:: Controller Method
:tabid: controller
Expand Down Expand Up @@ -188,6 +188,8 @@ method:

- :ref:`laravel-skip-limit` uses the ``skip()`` method to set the number of documents
to skip and the ``take()`` method to set the total number of documents to return
- :ref:`laravel-sort` uses the ``orderBy()`` method to return query
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

Expand All @@ -207,12 +209,11 @@ documents.

Use the following syntax to specify the query:

.. code-block:: php

$movies = Movie::where('year', 1999)
->skip(2)
->take(3)
->get();
.. literalinclude:: /includes/fundamentals/read-operations/ReadOperationsTest.php
:language: php
:dedent:
:start-after: start-skip-limit
:end-before: end-skip-limit

.. tab:: Controller Method
:tabid: controller
Expand Down Expand Up @@ -269,6 +270,105 @@ documents.
Plot: A sci-fi update of the famous 6th Century poem. In a beseiged land, Beowulf must
battle against the hideous creature Grendel and his vengeance seeking mother.

.. _laravel-sort:

Sort Query Results
~~~~~~~~~~~~~~~~~~

To order query results based on the values of specified fields, use the ``where()`` method
followed by the ``orderBy()`` method.

You can set an **ascending** or **descending** sort direction on
results. By default, the ``orderBy()`` method sets an ascending sort on
the supplied field name, but you can explicitly specify an ascending
sort by passing ``'asc'`` as the second parameter. To
specify a descending sort, pass ``'desc'`` as the second parameter.

If your documents contain duplicate values in a specific field, you can
handle the tie by specifying additional fields to sort on. This ensures consistent
results if the additional fields contain unique values.

This example queries for documents in which the value of the ``countries`` field contains
``'Indonesia'`` and orders results first by an ascending sort on the
``year`` field, then a descending sort on the ``title`` field.

.. 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-sort
:end-before: end-sort

.. 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('countries', 'Indonesia')
->orderBy('year')
->orderBy('title', 'desc')
->get();

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

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

Title: Joni's Promise
Year: 2005
Runtime: 83
IMDB Rating: 7.6
IMDB Votes: 702
Plot: A film delivery man promises ...

Title: Gie
Year: 2005
Runtime: 147
IMDB Rating: 7.5
IMDB Votes: 470
Plot: Soe Hok Gie is an activist who lived in the sixties ...

Title: Requiem from Java
Year: 2006
Runtime: 120
IMDB Rating: 6.6
IMDB Votes: 316
Plot: Setyo (Martinus Miroto) and Siti (Artika Sari Dewi)
are young married couple ...

...

.. tip::

To learn more about sorting, see the following resources:

- :manual:`Natural order </reference/glossary/#std-term-natural-order>`
in the Server manual glossary
- `Ordering, Grouping, Limit and Offset <https://laravel.com/docs/queries#ordering-grouping-limit-and-offset>`__
in the Laravel documentation

.. _laravel-retrieve-one:

Return the First Result
Expand All @@ -292,11 +392,11 @@ field.

Use the following syntax to specify the query:

.. code-block:: php

$movies = Movie::where('runtime', 30)
->orderBy('_id')
->first();
.. literalinclude:: /includes/fundamentals/read-operations/ReadOperationsTest.php
:language: php
:dedent:
:start-after: start-first
:end-before: end-first

.. tab:: Controller Method
:tabid: controller
Expand All @@ -314,12 +414,12 @@ field.
{
public function show()
{
$movies = Movie::where('runtime', 30)
$movie = Movie::where('runtime', 30)
->orderBy('_id')
->first();

return view('browse_movies', [
'movies' => $movies
'movies' => $movie
]);
}
}
Expand All @@ -337,10 +437,5 @@ field.

.. tip::

To learn more about sorting, see the following resources:

- :manual:`Natural order </reference/glossary/#std-term-natural-order>`
in the Server manual glossary
- `Ordering, Grouping, Limit and Offset <https://laravel.com/docs/10.x/queries#ordering-grouping-limit-and-offset>`__
in the Laravel documentation

To learn more about the ``orderBy()`` method, see the
:ref:`laravel-sort` section of this guide.
12 changes: 12 additions & 0 deletions docs/includes/fundamentals/read-operations/Movie.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace App\Models;

use MongoDB\Laravel\Eloquent\Model;

class Movie extends Model
{
protected $connection = 'mongodb';
protected $collection = 'movies';
protected $fillable = ['title', 'year', 'runtime', 'imdb', 'plot'];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

declare(strict_types=1);

namespace App\Http\Controllers;

use App\Models\Movie;
use MongoDB\Laravel\Tests\TestCase;

class ReadOperationsTest extends TestCase
{
protected function setUp(): void
{
require_once __DIR__ . '/Movie.php';

parent::setUp();

Movie::truncate();
Movie::insert([
['year' => 2010, 'imdb' => ['rating' => 9]],
['year' => 2010, 'imdb' => ['rating' => 9.5]],
['year' => 2010, 'imdb' => ['rating' => 7]],
['year' => 1999, 'countries' => ['Indonesia', 'Canada'], 'title' => 'Title 1'],
['year' => 1999, 'countries' => ['Indonesia'], 'title' => 'Title 2'],
['year' => 1999, 'countries' => ['Indonesia'], 'title' => 'Title 3'],
['year' => 1999, 'countries' => ['Indonesia'], 'title' => 'Title 4'],
['year' => 1999, 'countries' => ['Canada'], 'title' => 'Title 5'],
['year' => 1999, 'runtime' => 30],
]);
}

/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testFindFilter(): void
{
// start-query
$movies = Movie::where('year', 2010)
->where('imdb.rating', '>', 8.5)
->get();
// end-query

$this->assertNotNull($movies);
$this->assertCount(2, $movies);
}

/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testSkipLimit(): void
{
// start-skip-limit
$movies = Movie::where('year', 1999)
->skip(2)
->take(3)
->get();
// end-skip-limit

$this->assertNotNull($movies);
$this->assertCount(3, $movies);
}

/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testSort(): void
{
// start-sort
$movies = Movie::where('countries', 'Indonesia')
->orderBy('year')
->orderBy('title', 'desc')
->get();
// end-sort

$this->assertNotNull($movies);
$this->assertCount(4, $movies);
}

/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testFirst(): void
{
// start-first
$movie = Movie::where('runtime', 30)
->orderBy('_id')
->first();
// end-first

$this->assertNotNull($movie);
$this->assertInstanceOf(Movie::class, $movie);
}
}