Reputation: 3277
I have the following method to create a search query that scores the search term by occurrence:
public function findAll($search, array $data = []) {
$query = DB::query("
SELECT
SQL_CALC_FOUND_ROWS
*,
SUM(MATCH(text) AGAINST('{$search}' IN BOOLEAN MODE)) as score
FROM " . DB::prefix() . "search_index
WHERE MATCH(text) AGAINST('{$search}' IN BOOLEAN MODE)
OR text LIKE '%{$search}%'
GROUP BY language_id, type, object_id
ORDER BY score DESC
LIMIT " . (int)$data['start'] . ", " . (int)$data['limit'] . "
");
$count = DB::query("SELECT FOUND_ROWS() AS total");
return [
'count' => (int)$count->row['total'],
'query' => $query->rows
];
}
This works beautifully, but I need to add in a query to the tag
table so that it will increment the score and add items to the array for content that may not already exist in the main query:
$tags = DB::query("
SELECT * FROM " . DB::prefix() . "tag
WHERE tag = '{$search}'
");
Any ideas on how to implement this into the main query so that I'm only executing a single query?
Upvotes: 2
Views: 91
Reputation: 3277
I was able to combine these with a UNION query:
$query = DB::query("
(SELECT
SQL_CALC_FOUND_ROWS
type, object_id, language_id,
SUM(MATCH(text) AGAINST('{$search}' IN BOOLEAN MODE)) as score
FROM " . DB::prefix() . "search_index
WHERE MATCH(text) AGAINST('{$search}' IN BOOLEAN MODE)
OR text LIKE '%{$search}%'
GROUP BY language_id, type, object_id
ORDER BY score DESC
LIMIT " . (int)$data['start'] . ", " . (int)$data['limit'] . ")
UNION DISTINCT
(SELECT
section, element_id, language_id, tag
FROM " . DB::prefix() . "tag
WHERE tag = '{$search}')
");
Upvotes: 1