在 Laravel Scout 中搜索多个单词

问题描述 投票:0回答:1

我目前正在使用 Laravel Scout 通过数据库驱动程序搜索我的模型

我的搜索控制器看起来像这样

Post::search($request->filter)->get();

假设我有一篇帖子,上面写着“你好,这是一篇帖子”

当我单独搜索“Hello”或“Post”时,它有效。但是当我一起搜索“Hello Post”时,却没有,因为中间还有其他单词,并且搜索方法调用的执行查询

column WHERE LIKE %Hello Post%
没有找到匹配项。有没有办法检查模型中的文本是否包含查询字符串的所有单词,无论它们的顺序和外观如何?对我来说,似乎我必须找到一种方法来进行像
column WHERE LIKE %Hello% AND column WHERE LIKE %Post%
这样的查询。

我尝试将搜索查询转换为由空格分隔的数组,如

explode(' ', $request->filter)
。但是模型上的搜索方法不接受数组。只有一根绳子。我尝试单独循环和搜索每个数组项的元素,例如

foreach(explode(' ', $request->filter) as $filter) {
  $results = Post::search($filter)->get();
}

但它给了我错误的结果,因为我需要所有单词都适合的帖子,而不仅仅是个别单词。我考虑过用

Str::containsAll($column, explode(' ', $request->filter)
过滤结果,但这不是所需的解决方案。

我需要一种方法来进行正确的数据库查询,如上所述,如

column WHERE LIKE %Hello% AND column WHERE LIKE %Post%
但如何使用 Laravel Scout 实现这一点?

php laravel eloquent laravel-scout
1个回答
1
投票

修改搜索查询:

use Illuminate\Http\Request;
use App\Models\Post;

public function search(Request $request)
{
    $query = Post::query();  // Start with a base query

    $words = explode(' ', $request->input('filter'));  // Split the filter input into words
    foreach ($words as $word) {
        $query->where('text', 'LIKE', '%' . $word . '%');  // Add a LIKE condition for each word
    }

    $results = $query->get();  // Execute the query

    return view('search.results', ['posts' => $results]);  // Return the results to a view
}

在这种情况下,您可以确保在幕后执行的 SQL 如下所示:

SELECT * FROM posts WHERE text LIKE '%Hello%' AND text LIKE '%Post%';

但为了确保测试搜索功能: 单个单词搜索、常用单词搜索和空搜索输入。

但是如果您发现搜索速度很慢:

检查数据库文本列是否已正确索引。但请注意,LIKE '%word%' 查询通常不会从传统索引中受益。不过还是看一下吧。

如果您的数据库支持全文搜索功能,请考虑使用它们(例如 MySQL 的 FULLTEXT 索引或 PostgreSQL 的文本搜索功能)。如果设置正确,Laravel Scout 可以配置为使用这些功能。

对于大型数据集或列,使用原始 LIKE 查询可能效率低下。在这种情况下,请考虑切换到 Laravel Scout 支持的更强大的搜索驱动程序,例如 Algolia、MeiliSearch,甚至特定于数据库的文本搜索。

使用 Redis 等缓存解决方案可以显着提高搜索功能的性能。

© www.soinside.com 2019 - 2024. All rights reserved.