clarkwinkelmann/flarum-ext-scout

为 Flarum 提供的 Algolia 和 Meilisearch 搜索

安装数: 2,376

依赖: 1

建议者: 2

安全性: 0

星标: 10

关注者: 2

分支: 3

开放问题: 2

类型:flarum-extension

0.3.5 2023-05-08 21:15 UTC

This package is auto-updated.

Last update: 2024-09-09 00:16:18 UTC


README

MIT license Latest Stable Version Total Downloads Donate

集成 Laravel Scout 与 Flarum 讨论和用户搜索。

与 Laravel 类似,每次在 Flarum 中更新模型时,数据都会自动与搜索索引同步。您只需要在启用扩展时手动导入数据(请参阅下面的命令)。

外部搜索驱动程序在服务器端用于过滤 MySQL 结果,因此它应该仍然与其他扩展和搜索策略兼容。

扩展中包含 AlgoliaMeilisearch 驱动程序。支持 TNTSearch,但需要手动安装额外的包。Scout 数据库和集合驱动程序不能使用(它们会比 Flarum 内置的数据库搜索更差)。

以下是每个驱动程序的具体要求和配置。

虽然 Flarum 中只有讨论和用户可搜索,但此实现还使用了一个 posts 搜索索引,该索引以类似于 Flarum 原生搜索的方式与讨论搜索结果合并。当前讨论结果排序优先考虑最佳帖子匹配,因为我还没有找到合并讨论和帖子索引匹配分数的方法。

所有 Scout CLI 命令都可用,另外还有一个特殊的 "导入所有" 命令。

php flarum scout:import-all           Import all Flarum models into the search index
                                      (a shortcut to scout:import with every searchable class known to Flarum)
php flarum scout:flush {model}        Flush all of the model's records from the index
php flarum scout:import {model}       Import the given model into the search index
php flarum scout:index {name}         Create an index (generally not needed)
php flarum scout:delete-index {name}  Delete an index (generally not needed)

Algolia

Algolia 驱动程序需要在同名的云服务上有一个账户。

Meilisearch

Meilisearch 驱动程序需要一个正在运行的 Meilisearch 服务器实例。服务器可以托管在任何地方,只要它可以通过网络访问。默认情况下,扩展尝试连接到 127.0.0.1:7700 的服务器。

如果您没有运行最新的 Meilisearch 版本,您可能需要明确安装旧版本的 SDK。同样,如果您经常运行 composer update 来更新所有依赖项,您还应该在您的 composer.json 中添加对 Meilisearch SDK 的明确要求,因为扩展需要 *,这可能会在新版本的 Meilisearch SDK 发布时跳转到较新版本。

要安装和锁定当前最新版本

composer require meilisearch/meilisearch-php

不幸的是,Meilisearch 似乎没有宣传与每个服务器版本兼容的特定 Composer 包版本。您可以在 https://packagist.org.cn/packages/meilisearch/meilisearch-php 找到发布列表。

一旦您知道需要哪个版本,您就可以将其锁定,例如安装旧版本的 0.23。

composer require meilisearch/meilisearch-php:"0.23.*"

Meilisearch 的唯一设置是 主机密钥。其他一切都在 Meilisearch 服务器本身中进行配置。

即使您没有配置 默认结果限制 值并使用 Meilisearch,扩展也会自动将其设置为 200,因为 Meilisearch 的默认值(20)非常低,最多只能有 2 页的结果。

TNTSearch

TNTSearch 库需要 sqlite PHP 扩展,因此它默认不包含在 Scout 中。

要安装它,请确保您已为命令行和 web 服务器启用了 sqlite PHP 扩展,然后运行

composer require teamtnt/laravel-scout-tntsearch-driver

TNTSearch 使用本地 sqlite 数据库为每个索引。数据库存储在 <flarum>/storage/tntsearch 中,该目录必须可写。

以下设置被公开。每个设置的具体作用并不完全清楚,TNTSearch 的官方文档没有提供很多指导。

  • 最大文档数:这可能会影响 Flarum 对查询能显示多少结果
  • 模糊度(开启/关闭):看起来是用于错误拼写或变体匹配
  • 模糊度 Levenshtein 距离
  • 模糊度前缀长度:不知道它的作用
  • 模糊度最大扩展:不知道它的作用

即时搜索搜索布尔 被硬编码为启用,尽管它们在 TNTSearch 文档中描述的似乎不起作用。

安装

此扩展仍然是实验性的。请在测试服务器上先进行测试。我还没有亲自测试 Algolia,但从反馈来看,它似乎可以正常工作。

composer require clarkwinkelmann/flarum-ext-scout

支持的扩展和字段

此列表并不完整。如果您在扩展中添加了对 Scout 的支持,请告诉我,以便我可以更新此列表。

讨论

通过 Flarum 的搜索功能搜索讨论时,也会查询 帖子 字段。

  • 标题:Scout 内置支持。
  • Formulaire 讨论字段:自 Formulaire 1.8 起支持(仅限访客可访问的表单)。

帖子

  • 内容:Scout 内置支持,使用的值是输出 HTML 的纯文本版本,不带任何标签。因此,一些信息(如链接 URL、图片 URL 和图片 alt 文本)不会被索引。这可能在未来的版本中改变。

用户

  • 显示名称:Scout 内置支持。
  • 用户名:Scout 内置支持。
  • FoF 生物:Scout 内置支持(不在 FoF 生物本身中)。
  • Formulaire 个人资料字段:自 Formulaire 1.8 起支持(仅限访客可访问的表单)。

Email 故意不提供搜索,因为目前还没有机制可以阻止普通用户使用此功能泄露电子邮件。

Formulaire

表单和提交可以选择通过 Scout 索引。有关详细信息,请参阅 Formulaire 文档

开发者

扩展现有模型的搜索索引

使用扩展器注册您的属性,类似于扩展 Flarum 的序列化器。

此外,您应该注册一个在您的属性值更改时触发的事件监听器。

<?php

use ClarkWinkelmann\Scout\Extend\Scout;
use Acme\Event\SubtitleRenamed;

return [
    (new Scout(Discussion::class))
        ->listenSaved(SubtitleRenamed::class, function (SubtitleRenamed $event) {
            return $event->discussion;
        })
        ->attributes(function (Discussion $discussion): array {
            return [
                'subtitle' => $discussion->subtitle,
            ];
        }),
];

如果注册事件监听器不是一个选项,您也可以在更改值后手动调用更新代码

<?php

use ClarkWinkelmann\Scout\ScoutModelWrapper;
use Flarum\Discussion\Discussion;

/**
 * @var Discussion $discussion
 */
$discussion->subtitle = 'New value';
$discussion->save();

(new ScoutModelWrapper($discussion))->scoutObserverSaved();

如果您正在修改 Flarum 模型,而不是原始的存储/编辑/删除处理程序,别忘了触发 Flarum 事件(如讨论的 StartedDeleted),以便 Scout 可以同步您的更改。

添加您自己的搜索引擎

任何扩展 Laravel\Scout\Engines\Engine 且与 Laravel Scout 一起工作的搜索引擎都应与此 Flarum 实现兼容。

目前没有扩展器可以将来自外部包的新引擎连接到 Scout。您可能需要通过分叉此扩展或使用容器绑定来覆盖 EngineManager

使您自己的模型可搜索

由于 Scout 可选且可扩展的约束,Scout 的模型配置和检索 API 与 Laravel 相比有许多变化。在可能的情况下,已保留类似名称的概念,即使它们现在通过扩展器或新全局方法发生。

由于无法在不使 Scout 成为要求的情况下将 Searchable 特性添加到 Flarum(或扩展)Eloquent 模型,因此未使用该特性。不要将 Searchable 特性添加到您的 Eloquent 模型中,即使您有能力编辑模型源代码!

本文档提到了两种模型,“真实”模型是Flarum或没有Searchable特质的扩展的Eloquent模型,例如Flarum\User\User。“包装”模型是本扩展的一个特殊功能,其中“真实”模型被包装在一个特殊的模型中,使其具有Searchable能力。通常,“包装”模型将由该扩展在底层透明地使用,无需程序员进行任何特殊操作。如果您希望手动获取“包装”模型以调用其特定的Scout方法,可以使用new ScoutModelWrapper($model)对其进行包装。

未使用内置的Scout模型观察者,而是使用Flarum事件来触发索引更新。

与Laravel的差异总结

Support/Eloquent集合方法与真实或包装模型的数组一起工作

  • Illuminate\Support\Collection::searchable():功能相同。
  • Illuminate\Support\Collection::unsearchable():功能相同。

查询构建器方法/作用域在真实模型上工作

  • Eloquent\Builder::searchable():功能相同
  • Eloquent\Builder::unsearchable():功能相同

Scout方法在真实模型上不可用,但所有有用的方法都有其他可调用的替代方式

  • Model::shouldBeSearchable():使用扩展器进行修改。
  • Model::searchIndexShouldBeUpdated():不可定制。以后可能添加到扩展器中。
  • Model::search():不可用。直接使用构建器。
  • Model::makeAllSearchable():使用ScoutStatic::makeAllSearchable()代替。
  • Model::makeAllSearchableUsing():不可定制。以后可能添加到扩展器中。
  • Model::searchable():不可用。手动在集合中包装或使用ScoutModelWrapper调用。
  • Model::removeAllFromSearch():使用ScoutStatic::removeAllFromSearch()代替。
  • Model::unsearchable():不可用。手动在集合中包装或使用ScoutModelWrapper调用。
  • Model::wasSearchableBeforeUpdate():不可定制。以后可能添加到扩展器中。
  • Model::wasSearchableBeforeDelete():不可定制。以后可能添加到扩展器中。
  • Model::getScoutModelsByIds():应该可以通过包装器使用,但建议不要使用。
  • Model::queryScoutModelsByIds():应该可以通过包装器使用,但建议不要使用。
  • Model::enableSearchSyncing():不可用。
  • Model::disableSearchSyncing():不可用。
  • Model::withoutSyncingToSearch():不可用。
  • Model::searchableAs():不可定制。前缀可以在扩展设置中更改。
  • Model::toSearchableArray():使用扩展器进行修改。
  • Model::syncWithSearchUsing():不可定制。以后可能添加到扩展器中。
  • Model::syncWithSearchUsingQueue():不可定制。以后可能添加到扩展器中。
  • Model::pushSoftDeleteMetadata():不可用。
  • Model::scoutMetadata():不可定制。以后可能添加到扩展器中。
  • Model::withScoutMetadata():不可用。
  • Model::getScoutKey():不可定制。以后可能添加到扩展器中。
  • Model::getScoutKeyName():不可定制。以后可能添加到扩展器中。
  • Model::usesSoftDelete():不可用。

不使用Scout::静态对象

  • Laravel\Scout\Scout::$makeSearchableJob:不可定制。
  • Laravel\Scout\Scout::$removeFromSearchJob:不可定制。
  • Laravel\Scout\Scout::makeSearchableUsing():不可定制。
  • Laravel\Scout\Scout::removeFromSearchUsing():不可定制。

提供了一个新的静态方法对象,不属于原始的Scout

  • ScoutStatic::makeAllSearchable(string $modelClass):触发给定类的索引或所有模型的索引。
  • ScoutStatic::removeAllFromSearch(string $modelClass):触发给定类的去索引或所有模型的去索引。
  • ScoutStatic::makeBuilder(string $modelClass, string $query, callable $callback = null):获取针对给定模型配置的Laravel\Scout\Builder实例。

要使用侦察兵在代码中过滤结果,我建议忽略每个构建器/模型方法,并直接通过Scout Builder实例检索匹配的ID。

然后,您可以使用那个匹配ID的数组来修改Flarum搜索器(请参阅此扩展源代码中的帖子/用户搜索器)、过滤器或手动查询。

注意:ID数组将包含已删除和私有内容。请确保在查询中始终使用Flarum的whereVisibleTo()

为了保持搜索结果顺序,一个选项是使用FIELD() SQL方法。如果您不进行分页,您还可以在从数据库检索结果后在PHP中重新排序结果。

<?php

use ClarkWinkelmann\Scout\ScoutStatic;
use Flarum\User\User;

$builder = ScoutStatic::makeBuilder(User::class, 'Hello World');

$ids = $builder->keys();

$users = User::newQuery()
    ->whereVisibleTo($actor)
    ->whereIn('id', $ids)
    ->orderByRaw('FIELD(id' . str_repeat(', ?', count($ids)) . ')', $ids)
    ->limit(10)
    ->get();

支持

此扩展处于最小维护状态。

它是为某个客户开发的,并作为开源软件发布,以造福社区。我可能会免费发布简单的错误修复或兼容性更新。

您可以联系我赞助额外功能或更新。

支持通过Flarum社区线程提供,基于“尽力而为”原则。

链接