Skip to content

DOCSP-35962: sorts #2879

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 6 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
141 changes: 118 additions & 23 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/11.x/queries#ordering-grouping-limit-and-offset>`__
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That may be a subject to be dealt with separately, but we can't freeze the version like that. How to update the links when a new Laravel version is released? Perhaps the easiest way is to link to the latest version. But you run the risk of having a broken link.

Suggested change
- `Ordering, Grouping, Limit and Offset <https://laravel.com/docs/11.x/queries#ordering-grouping-limit-and-offset>`__
- `Ordering, Grouping, Limit and Offset <https://laravel.com/docs/queries#ordering-grouping-limit-and-offset>`__

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can link to the latest version, or we can store the laravel version as a source constant. Either way, the risk of linking to a broken link is there, so I'll update to just use latest for now.

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 Down Expand Up @@ -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,95 @@
<?php

declare(strict_types=1);

namespace App\Http\Controllers;

use App\Models\Cargo;

// <add your imports here including any models and facades>

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Schema\SQLiteBuilder;
use Illuminate\Support\Facades\Schema;
use MongoDB\Laravel\Tests\TestCase;

use function assert;

class ReadOperationsTest extends TestCase
{

/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testFindFilter(): void
{
require_once __DIR__ . '/Movie.php';

// 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
{
require_once __DIR__ . '/Movie.php';

// 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
{
require_once __DIR__ . '/Movie.php';

// start-sort
$movies = Movie::where('countries', 'Indonesia')
->orderBy('year')
->orderBy('title', 'desc')
->get();
// end-sort

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

/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testFirst(): void
{
require_once __DIR__ . '/Movie.php';

// start-first
$movies = Movie::where('runtime', 30)
->orderBy('_id')
->first();
// end-first

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

}