繁体   English   中英

具有多个模型的 laravel scout 搜索

[英]laravel scout search with multiple model

我使用了这个旧代码,并开始使用laravel/scout重构它。 此代码是一个简单的搜索功能,也可以在帖子和页面中搜索,并显示结果混合分页。

旧代码:

public function search($term) {
   $post = Post::where('title', 'LIKE', $term);
   $page = Page::where('content', 'LIKE', $term);
   $result = $page->union($post)->orderBy('created_at')->paginate();
   return $result;
}

新代码不起作用:

public function search($term) {
   $post = Post::search($term);
   $page = Page::search($term);
   $result = $page->union($post)->orderBy('created_at')->paginate(); 
   return $result;
}

得到错误: Method Laravel\Scout\Builder::union does not exist.

这个问题的最佳语法是什么?

由于Scout\Builder不支持union 为 Scout 支持的所有可能的搜索引擎实现union功能并非易事。

但是, Scout\Builder提供了一个query()函数来自定义 eloquent 结果查询。

这提供了一种逃生舱口,侦察员可以在一个模型上利用(在两个模型中)

public function search($term)
{
    $postQuery = Post::query()
        ->where('some_column', 'like', $term . "%");
    $results = Page::search($term)
        ->query(
            fn($query) => $query->union($postQuery)
                ->orderBy('created_at', 'desc')
        )
        ->paginate();
}

Laravel Scout - 自定义 Eloquent 结果查询

对于 Algolia 引擎

如果使用 Algolia 作为搜索引擎,还有Algolia Scout Extended ,它支持多模型搜索。

对于其他引擎

使用 Scout 搜索多个模型并获得分页结果的另一种方法是:

  • 使用 Scout 获取单个模型的搜索结果(使用Model::search('query')->get();
  • 连接生成的集合
  • 对集合进行分页

在服务提供者的boot方法中为Illuminate\Support\Collection定义一个宏(例如在App\Providers\AppServiceProvider中)

<?php

namespace App\Providers;

use Illuminate\Support\Collection;
use Illuminate\Support\ServiceProvider;
use Illuminate\Pagination\LengthAwarePaginator;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Collection::macro('paginate', function ($perPage, $total = null, $page = null, $pageName = 'page') {
            $page = $page ?: LengthAwarePaginator::resolveCurrentPage($pageName);

            return new LengthAwarePaginator(
                $total ? $this : $this->forPage($page, $perPage)->values(),
                $total ?: $this->count(),
                $perPage,
                $page,
                [
                    'path'     => LengthAwarePaginator::resolveCurrentPath(),
                    'pageName' => $pageName,
                ]
            );
        });
    }
}

然后在控制器中

public function search($term) {
   $post = Post::where('title', 'LIKE', $term)->get();
   $page = Page::where('content', 'LIKE', $term)->get();
   $result = $page->concat($post)->sortBy('created_at')->paginate(5);
   return $result;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM