Mysql с расширенными условиями, порядок по релевантности

У меня есть запрос sql для функции поиска, которая немного сложна, но отлично работает.

SELECT
    SQL_CALC_FOUND_ROWS p.id as id,
    p.title as title,
    co.title as company,
    p.price as price,
    p.image_url as image_url FROM products p 
JOIN product_categories pc ON p.id = pc.product_id
JOIN categories cat ON pc.category_id = cat.id
JOIN companies co ON p.company_id = co.id

        WHERE MATCH(p.title) AGAINST("nalle" IN BOOLEAN MODE)
        OR MATCH(p.description) AGAINST("nalle" IN BOOLEAN MODE)
        OR MATCH(cat.title) AGAINST("nalle" IN BOOLEAN MODE)
        OR MATCH(co.title) AGAINST("nalle" IN BOOLEAN MODE)

    GROUP BY p.id
    ORDER BY p.title
    LIMIT :offset, :limit

Теперь он упорядочен по названию продукта, но на первом месте должны быть самые релевантные результаты. Это означает, что если он соответствует как p.title, так и p.description, он более релевантен, чем если он соответствует только p.title. Лучшим совпадением было бы совпадение всех четырех.

Из-за сложности запроса я не знаю, как его вычислить.

Я предполагаю, что мне нужно SELECT ??? as points ... ORDER BY points.


person Jens Törnell    schedule 10.04.2018    source источник


Ответы (1)


Возможно, вы можете попробовать это, если это InnoDB, я не уверен, что это MyISAM:

SELECT
    SQL_CALC_FOUND_ROWS p.id as id,
    p.title as title,
    co.title as company,
    p.price as price,
    p.image_url as image_url,
    MATCH(p.title, p.description, cat.title, co.title)
         AGAINST("nalle" IN BOOLEAN MODE) as Relevance
FROM products p 
JOIN product_categories pc ON p.id = pc.product_id
JOIN categories cat ON pc.category_id = cat.id
JOIN companies co ON p.company_id = co.id

WHERE MATCH(p.title, p.description, cat.title, co.title) AGAINST("nalle" IN BOOLEAN MODE)

GROUP BY p.id
ORDER BY Relevance DESC, p.title
LIMIT :offset, :limit

В примере здесь вы можете увидеть, как они вычисляют счет. Если слово, которое вы ищете, находится в большем количестве полей, оценка будет выше.

person Daniel E.    schedule 10.04.2018
comment
В моих совпадениях используется ИЛИ, но ваши совпадения сгруппированы в одно, что означает, что теперь они используют И. - person Jens Törnell; 10.04.2018
comment
Я не согласен, посмотрите ссылку на mysql, я дал ссылку в своем ответе и здесь: dev.mysql.com/doc/refman/5.7/en/fulltext-boolean.html - person Daniel E.; 10.04.2018
comment
Я попробовал это, и я получаю ошибку синтаксического анализа. # 1064 - Ошибка синтаксического анализа рядом с «ПОИСКПОЗ (p.title, p.description, cat.title, co.title) AGAINST (nalle IN BOOLEAN MO» в строке 7. - person Jens Törnell; 11.04.2018
comment
Я должен был упомянуть, что увидел запятую и исправил ее, и после этого я получил ошибку. (до того, как у меня была другая ошибка, связанная с запятой). Кстати, я использую innoDB. - person Jens Törnell; 11.04.2018
comment
Нет, ошибка запятой породила другое сообщение об ошибке: 3 erros was found during analysis. An alias was found. (near "Relevance" at position 265) An alias was expected. (near " " at position 264) Unknown token. (near "Relevance" at position 265) - person Jens Törnell; 12.04.2018
comment
Единственная разница, которую я вижу между классическим примером и здесь, это простая кавычка/двойная кавычка в Match. Например, здесь: stackoverflow.com/questions/1241602/ - person Daniel E.; 12.04.2018