From 5e5e6aad9db6452657192a22b7e9787818ffbab1 Mon Sep 17 00:00:00 2001 From: jpedryc Date: Fri, 1 Nov 2024 02:52:01 +0100 Subject: [PATCH] Add compound full-text index search capabilities Previously there was no support for compound full-text index search capabilities. This extension handles these indexes by allowing sub-arrays within the existing `SearchUsingFullText` attribute. Example: Assuming we have a 2 column full-text index ("col_a", "col_b") and a single full-text index "col_b": `#SearchUsingFullText([["col_a", "col_b"], "col_c"])` will result in a SQL query like: MATCH (`t`.`col_a`, `t`.`col_b`) AGAINST ('term' IN ) OR MATCH (`t`.`col_c`) AGAINST ('term' IN ) NOTE: Previous usages of this attribute will be not affected by this change. --- src/Engines/DatabaseEngine.php | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/Engines/DatabaseEngine.php b/src/Engines/DatabaseEngine.php index f5d6e136..1d09792f 100644 --- a/src/Engines/DatabaseEngine.php +++ b/src/Engines/DatabaseEngine.php @@ -206,13 +206,39 @@ protected function initializeSearchQuery(Builder $builder, array $columns, array $likeOperator = $connectionType == 'pgsql' ? 'ilike' : 'like'; + $fullTextColumnsChecked = []; + foreach ($columns as $column) { - if (in_array($column, $fullTextColumns)) { + if (in_array($column, $fullTextColumnsChecked)) { + continue; + } + + if (in_array($column, Arr::flatten($fullTextColumns))) { + $fullTextColumnTarget = Arr::first( + $fullTextColumns, + fn ($entry) => is_array($entry) + ? in_array($column, $entry) + : $entry === $column + ); + + // Handle full-text query depending on given type (string - single index; array - compound index) + if (! is_array($fullTextColumnTarget)) { + $query->orWhereFullText( + $builder->model->qualifyColumn($column), + $builder->query, + $this->getFullTextOptions($builder) + ); + + continue; + } + $query->orWhereFullText( - $builder->model->qualifyColumn($column), + Arr::map($fullTextColumnTarget, fn ($target) => $builder->model->qualifyColumn($target)), $builder->query, $this->getFullTextOptions($builder) ); + + $fullTextColumnsChecked += $fullTextColumnTarget; } else { if ($canSearchPrimaryKey && $column === $builder->model->getScoutKeyName()) { continue;