pmatseykanets/laravel-scout-postgres

Laravel Scout 的 PostgreSQL 全文搜索驱动程序

v7.3.0 2021-01-06 18:43 UTC

README

Latest Version on Packagist Software License tests StyleCI Total Downloads License

此包使您能够轻松使用原生 PostgreSQL 全文搜索功能与 Laravel Scout

如果您觉得这个包很有用,请考虑为我买杯咖啡。

Buy Me a Coffee at ko-fi.com

内容

安装

您可以通过 composer 安装此包

composer require pmatseykanets/laravel-scout-postgres

Laravel

如果您使用的是 Laravel < 5.5 或如果您已关闭包自动发现,您必须手动注册服务提供程序

// config/app.php
'providers' => [
    ...
    ScoutEngines\Postgres\PostgresEngineServiceProvider::class,
],

Lumen

Scout 服务提供程序使用 config_path 辅助函数,该函数不包括在 Lumen 中。要修复此问题,请将以下代码片段直接放入 bootstrap.app 或您的自动加载辅助文件中,例如 app/helpers.php

if (! function_exists('config_path')) {
    /**
     * Get the configuration path.
     *
     * @param  string  $path
     * @return string
     */
    function config_path($path = '')
    {
        return app()->basePath() . '/config'.($path ? DIRECTORY_SEPARATOR.$path : $path);
    }
}

app/config 文件夹中创建名为 scout.php 的配置文件,内容如下

<?php

return [
    'driver' => env('SCOUT_DRIVER', 'pgsql'),
    'prefix' => env('SCOUT_PREFIX', ''),
    'queue' => false,
    'pgsql' => [
        'connection' => 'pgsql',
        'maintain_index' => true,
        'config' => 'english',
    ],
];

注册服务提供程序

// bootstrap/app.php
$app->register(Laravel\Scout\ScoutServiceProvider::class);
$app->configure('scout');
$app->register(ScoutEngines\Postgres\PostgresEngineServiceProvider::class);

配置

配置引擎

在 Laravel Scout 配置文件 config/scout.php 中指定用于访问索引文档的数据库连接

// config/scout.php
...
'pgsql' => [
    // Connection to use. See config/database.php
    'connection' => env('DB_CONNECTION', 'pgsql'),
    // You may want to update index documents directly in PostgreSQL (i.e. via triggers).
    // In this case you can set this value to false.
    'maintain_index' => true,
    // You can explicitly specify what PostgreSQL text search config to use by scout.
    // Use \dF in psql to see all available configurations in your database.
    'config' => 'english',
    // You may set the default querying method
    // Possible values: plainquery, phrasequery, tsquery
    // plainquery is used if this option is omitted.
    'search_using' => 'tsquery'
],
...

配置 PostgreSQL

请确保全局(在 postgresql.conf 中)、特定数据库(ALTER DATABASE ... SET default_text_search_config TO ...)或另设会话中设置了适当的 默认全文搜索配置

要检查当前值

SHOW default_text_search_config;

准备架构

默认情况下,该引擎期望解析的文档(模型数据)存储在与模型相同的表中,列名为 searchable 的类型为 tsvector。您需要在架构中创建此列和一个索引。您可以在 PostgreSQL 中选择 GINGiST 索引。

class CreatePostsTable extends Migration
{
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->text('title');
            $table->text('content')->nullable();
            $table->integer('user_id');
            $table->timestamps();
        });

        DB::statement('ALTER TABLE posts ADD searchable tsvector NULL');
        DB::statement('CREATE INDEX posts_searchable_index ON posts USING GIN (searchable)');
        // Or alternatively
        // DB::statement('CREATE INDEX posts_searchable_index ON posts USING GIST (searchable)');
    }

    public function down()
    {
        Schema::drop('posts');
    }
}

配置可搜索数据

除了模型属性外,您还可以将其他任何数据引入索引文档。例如,文章的标签列表。

public function toSearchableArray()
{
    return [
        'title' => $this->title,
        'content' => $this->content,
        'author' => $this->user->name,
        'tags' => $this->tags->pluck('tag')->implode(' '),
    ];
}

配置模型

您可以通过在模型中实现 searchableOptions() 来调整特定模型的引擎行为。

class Post extends Model
{
    use Searchable;

    // ...
    public function searchableOptions()
    {
        return [
            // You may wish to change the default name of the column
            // that holds parsed documents
            'column' => 'indexable',
            // You may want to store the index outside of the Model table
            // In that case let the engine know by setting this parameter to true.
            'external' => true,
            // If you don't want scout to maintain the index for you
            // You can turn it off either for a Model or globally
            'maintain_index' => true,
            // Ranking groups that will be assigned to fields
            // when document is being parsed.
            // Available groups: A, B, C and D.
            'rank' => [
                'fields' => [
                    'title' => 'A',
                    'content' => 'B',
                    'author' => 'D',
                    'tags' => 'C',
                ],
                // Ranking weights for searches.
                // [D-weight, C-weight, B-weight, A-weight].
                // Default [0.1, 0.2, 0.4, 1.0].
                'weights' => [0.1, 0.2, 0.4, 1.0],
                // Ranking function [ts_rank | ts_rank_cd]. Default ts_rank.
                'function' => 'ts_rank_cd',
                // Normalization index. Default 0.
                'normalization' => 32,
            ],
            // You can explicitly specify a PostgreSQL text search configuration for the model.
            // Use \dF in psql to see all available configurationsin your database.
            'config' => 'simple',
        ];
    }
}
...

如果您决定将模型的索引放在模型表之外,您可以让引擎知道您想将额外的字段推送到索引表,然后您可以使用 Scout Builder 中的 where() 来过滤结果集。在这种情况下,您需要在模型中实现 searchableAdditionalArray()。当然,外部表的架构应包括这些额外的列。

public function searchableAdditionalArray()
{
    return [
        'user_id' => $this->user_id,
    ];
}

您可能希望将可搜索列隐藏起来,以免它挡在您的路上

protected $hidden = [
    'searchable',
];

用法

// plainto_tsquery()
$posts = App\Post::search('cat rat')
    ->usingPlainQuery()->get()

// phraseto_tsquery()
$posts = App\Post::search('cat rat')
    ->usingPhraseQuery()->get()

// to_tsquery()
$posts = App\Post::search('fat & (cat | rat)')
    ->usingTsQuery()->get()

// websearch_to_tsquery()
// uses web search syntax 
$posts = App\Post::search('"sad cat" or "fat rat" -mouse')
    ->usingWebSearchQuery()->get()

// DIY using a callback
use ScoutEngines\Postgres\TsQuery\ToTsQuery;

$results = App\Post::search('fat & (cat | rat)', function ($builder, $config) {
    return new ToTsQuery($builder->query, $config);
})->get();

有关如何使用 Laravel Scout 的详细信息,请参阅 官方文档

测试

composer test

安全

如果您发现任何安全问题,请通过电子邮件 pmatseykanets@gmail.com 而不是使用问题跟踪器。

变更日志

有关最近更改的更多信息,请参阅 CHANGELOG

贡献

有关详细信息,请参阅 CONTRIBUTING

致谢

许可

MIT 许可证(MIT)。请参阅许可文件以获取更多信息。