I have 5 tables:
library_item
============
id
title
description
index_text
library_item_rel_category
=========================
item_id
category_id
library_category
================
id
parent_id
name
library_item_rel_tag
====================
item_id
tag_id
library_tag
===========
id
name
And currently I have this MySQL request (Using PHP PDO):
SELECT
i.*,
((
((MATCH (i.title) AGAINST (:terms)) * 5) +
((MATCH (i.description) AGAINST (:terms)) * 4) +
((MATCH (i.index_text) AGAINST (:terms)) * 3) +
(MATCH (i.title, i.description, i.index_text) AGAINST (:terms))
) + IFNULL(c.score, 0) + IFNULL(t.score, 0)) as score
FROM
library_item AS i
LEFT JOIN
(
SELECT
rel_c.item_id,
((MATCH(c.name) AGAINST (:terms)) * 5) AS score
FROM
library_item_rel_category rel_c
INNER JOIN
library_category c ON rel_c.category_id = c.id
WHERE
MATCH(c.name) AGAINST (:terms)
ORDER BY
score DESC
) AS c ON c.item_id = i.id
LEFT JOIN
(
SELECT
rel_t.item_id,
((MATCH(t.name) AGAINST (:terms)) * 5) AS score
FROM
library_item_rel_tag rel_t
INNER JOIN
library_tag t ON rel_t.tag_id = t.id
WHERE
MATCH(t.name) AGAINST (:terms)
ORDER BY
score DESC
LIMIT 1
) AS t ON t.item_id = i.id
WHERE
i.is_archive = 0 AND
((
((MATCH (i.title) AGAINST (:terms)) * 5) +
((MATCH (i.description) AGAINST (:terms)) * 4) +
((MATCH (i.index_text) AGAINST (:terms)) * 3) +
(MATCH (i.title, i.description, i.index_text) AGAINST (:terms))
) + IFNULL(c.score, 0) + IFNULL(t.score, 0)) > 5
GROUP BY
i.id
ORDER BY
score DESC
I would like to add the ability to match the parent categories too until it hits the root. Is it possible using MySQL in this single query?
I am ready to change table structure if needed, it’s my first recursive tree.
MySQL does not support recursive queries as some other databases do. There is no way to find all parent categories in a single query with the way you’re storing the parent_id.
See my presentation Models for Hierarchical Data with SQL and PHP for an overview of different techniques for storing and querying tree-like structures in MySQL.
See also my answer to What is the most efficient/elegant way to parse a flat table into a tree?