Подтвердить что ты не робот

Лучший способ сделать взвешенный поиск по нескольким полям в mysql?

Вот что я хочу сделать:

  • соответствует теме поиска по нескольким полям моей таблицы.
  • упорядочить результаты по важности поля и релевантности соответствия (в указанном порядке)

Пример: допустим, у меня есть блог. Затем кто-то ищет "php". Результаты будут выглядеть следующим образом:

  • сначала совпадения для поля 'title', упорядоченные по релевантности
  • тогда совпадения для поля "тело", упорядоченные по релевантности тоже
  • и т.д. с указанными полями...

Я действительно сделал это с классом на PHP, но он использует много UNIONS (много!) и растет с размером объекта поиска. Поэтому я беспокоюсь о производительности и проблемах DOS. Кто-нибудь знает об этом?

4b9b3361

Ответ 1

Возможно, этот подход для взвешенного поиска/результатов подходит вам:

SELECT *,
    IF(
            `name` LIKE "searchterm%",  20, 
         IF(`name` LIKE "%searchterm%", 10, 0)
      )
      + IF(`description` LIKE "%searchterm%", 5,  0)
      + IF(`url`         LIKE "%searchterm%", 1,  0)
    AS `weight`
FROM `myTable`
WHERE (
    `name` LIKE "%searchterm%" 
    OR `description` LIKE "%searchterm%"
    OR `url`         LIKE "%searchterm%"
)
ORDER BY `weight` DESC
LIMIT 20

Он использует подзапрос select, чтобы обеспечить вес для упорядочения результатов. В этом случае три поля были просмотрены, вы можете указать вес для каждого поля. Это, вероятно, менее дорого, чем профсоюзы, и, вероятно, один из самых быстрых способов только в простом MySQL.

Если у вас больше данных и нужны результаты быстрее, вы можете использовать что-то вроде Sphinx или Lucene.

Ответ 2

вы можете добавить несколько значений mysql MATCH() вместе, сначала умножая каждый на свой вес.

упрощено, конечно...

'(MATCH(column1) AGAINST(\''.$_GET['search_string'].'\') * '.$column1_weight.')
 + (MATCH(column2) AGAINST(\''.$_GET['search_string'].'\') * '.$column2_weight.')
 + (MATCH(column3) AGAINST(\''.$_GET['search_string'].'\') * '.$column3_weight.')
 AS relevance'

затем

'ORDER BY relevance'

Ответ 3

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

Ответ 4

У меня был такой же вопрос, и он был полностью отвечен на одном из форумов MySQL. Здесь поток. Вид длинной нити (потому что я немного длинный), но выигрыш просто то, что вы ищете.