Как я могу сортировать по релевантности моему поисковому запросу в Laravel при выполнении полнотекстового поиска?
Миграция
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::dropIfExists('posts');
Schema::create('posts',function (Blueprint $table){
// More columns will be added in next migrations.
$table->id();
$table->string('name');
$table->fulltext(['name']);
});
}
public function down(): void
{
Schema::dropIfExists('posts');
}
};
Модель
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $table = "posts";
}
Я выполняю полнотекстовый поиск в контроллере следующим образом:
class PostController extends Controller
{
public function search()
{
$searchterm = $request->get('searchterm');
$qb = Post::query();
if (!empty($searchterm)){
$qb=$qb->whereFullText(['name'],$searchterm);
}
$page = $request->get('page')??1;
$limit = $request->get('limit')??20;
$results = $qb->offset(($page - 1) * $limit)
->simplePaginate($limit);
return new JsonResponse($results,200);
}
}
Однако мне нужно выяснить, как вернуть результаты, упорядоченные по релевантности, в моем контроллере. Я хочу, чтобы наиболее близкие совпадения отображались первыми. Как я могу этого добиться?
Но мои данные хранятся в базе данных, и в базе данных есть встроенные функции для этого.






Подход к размещению необработанных частей запроса, таких как:
class PostController extends Controller
{
public function search()
{
$searchterm = $request->get('searchterm');
$qb = Post::query();
if (!empty($searchterm)){
$qb=$qb->whereRaw("MATCH(name) AGAINST(? IN BOOLEAN MODE)",["*".$searchterm."*"])
->orderByRaw("MATCH(name) AGAINST(?) DESC", ["*".$searchterm."*"]);
}
$page = $request->get('page')??1;
$limit = $request->get('limit')??20;
$results = $qb->offset(($page - 1) * $limit)
->simplePaginate($limit);
return new JsonResponse($results,200);
}
}
Я использовал whereRaw и orderByRaw для сортировки и фильтрации результатов. Это применимо ТОЛЬКО при использовании mysql или mariadb, и это только его недостаток, особенно при реализации приложения, доступного для нескольких rdbms (например, ваше приложение поддерживает как mysql, так и postgres).
В PHP есть встроенные функции для взвешивания спичек. Возможно, вы захотите поиграть с ними. Левенштейн(), аналогичный_текст(), soundex() и т. д.