如何在LaravelEloquent中对查询结果进行排序

来自菜鸟教程
跳转至:导航、​搜索

在本系列的 上一部分 中,您学习了如何在 Eloquent 模型中使用 all() 方法获取数据库记录。 您可能还记得使用了一种称为 sortDesc() 的方法,该方法用于按降序对记录进行排序。

sortDesc() 方法是 Collection 类的一部分,它是一个强大的 Laravel 实用程序类,可作为原生 PHP 数组的改进版本。 此方法不会在数据库查询本身中对结果进行排序,而是反转集合的顺序,以便最后一个项目首先出现在集合中。 虽然这适用于较小的结果集,但它没有提供与在数据库查询本身中对结果进行排序相同的灵活性。

要对数据库查询中的结果进行排序,您需要使用 orderBy() 方法,并提供要用作排序条件的表字段。 这将使您更灵活地构建查询,该查询将仅从数据库中获取您需要的结果。

您现在将更改 routes/web.php 文件中的代码,以根据 created_at 表字段显示从最新到最旧的结果。

当您在表迁移中包含 timestamps() 定义时,created_atupdated_at 字段都由 Eloquent 管理。 您不应手动更新这些字段,但可以使用它们对查询进行排序和过滤。


在代码编辑器中打开此文件:

routes/web.php

这是代码现在的样子:

路线/web.php

<?php
 
use Illuminate\Support\Facades\Route;
use App\Models\Link;
use App\Models\LinkList;
 
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
 
Route::get('/', function () {
    $links = Link::all()->sortDesc();
    return view('index', [
        'links' => $links,
        'lists' => LinkList::all()
    ]);
});
 
Route::get('/{slug}', function ($slug) {
    $list = LinkList::where('slug', $slug)->first();
    if (!$list) {
        abort(404);
    }
 
    return view('index', [
        'list' => $list,
        'links' => $list->links,
        'lists' => LinkList::all()
    ]);
})->name('link-list');
 

注意 /{slug} 路由,它负责按 slug 列出链接,目前没有使用任何排序方法。 链接是通过 list 变量获得的,在代码中突出显示,使用 LinkList 模型中定义的关系。

如果您现在将多个链接添加到列表中,默认情况下查询将返回从最旧到最新排序的结果。 尽管您可以使用 sortDesc() 方法在 $list->links 调用中重新排序集合,但使用 orderBy() 方法提供了更大的灵活性,并允许您在以后包含其他过滤条件。 您可以将此方法与 where() 调用链接以获得更细粒度的结果。

将前面代码示例中突出显示的行替换为以下行:

路线/web.php

'links' => $list->links()->orderBy('created_at', 'desc')->get(),

请注意,这次我们通过调用 $list->links() 方法来调用内置查询构建器,该方法引用 LinkList 类中定义的关系方法。 这与将 $list->links 作为类属性(不带括号)调用不同,后者将调用模型中的魔术方法来获取与该列表相关的所有链接。

这是完成后完整的 routes/web.php 文件的样子:

路线/web.php

<?php

use Illuminate\Support\Facades\Route;
use App\Models\Link;
use App\Models\LinkList;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    $links = Link::all()->sortDesc();
    return view('index', [
        'links' => $links,
        'lists' => LinkList::all()
    ]);
});

Route::get('/{slug}', function ($slug) {
    $list = LinkList::where('slug', $slug)->first();
    if (!$list) {
        abort(404);
    }

    return view('index', [
        'list' => $list,
        'links' => $list->links()->orderBy('created_at', 'desc')->get(),
        'lists' => LinkList::all()
    ]);
})->name('link-list');

保存并关闭文件。 现在,使用 link:new Artisan 命令添加几个新链接。 您可以使用默认列表:

docker-compose exec app php artisan link:new
Output Link URL:
 > https://laravel.com/docs/8.x/eloquent

 Link Description:
 > Laravel Eloquent Docs

 Link List (leave blank to use default):
 > 

New Link:
https://laravel.com/docs/8.x/eloquent - Laravel Eloquent Docs
Listed in: default

 Is this information correct? (yes/no) [no]:
 > yes

Saved.

如果您重新加载默认链接列表页面,您现在应该获得从最新到最旧的链接:

http://localhost:8000/default

同样,如果您希望按链接描述的字母顺序对链接进行排序,则必须更改该行以在方法调用中使用该表字段,如下所示:

'links' => $list->links()->orderBy('description', 'asc')->get(),

以下是此类更改后链接的排序方式:

在本系列的下一部分中,您将学习如何从 Laravel Eloquent 查询中获取总结果数。