Полнотекстовый поиск с использованием булевых операторов MySQL с тегами

Когда я смотрю на первые 30 точек данных, я вижу:

first_30

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

y = amplitude * sin(pi * (x - center) / width) + Offset

amplitude =  3.3098923173806202E+02
center =  2.1702445745645457E+02
width =  1.8508302910055434E+00
Offset = -9.6083629945476581E+00

few_cycles

, а не весь набор данных. Теперь я могу включить те параметры назад к уравнению экспоненциального распада как константы (или начальные оценки параметра) и решить для экспоненциального распада с помощью всех данных.

5
задан 2 September 2009 в 02:48
поделиться

6 ответов

Забавно, это 3-й вопрос почти о той же проблеме, которую я вижу через 2 дня, посмотрите эти два сообщения: 1 , 2

0
ответ дан 14 December 2019 в 19:20
поделиться

Начиная с ответа @ james.c.funk, но с некоторыми изменениями.

SELECT a.id, a.title, 
  MATCH (a.title) AGAINST (?) AS relevance
FROM articles AS a
LEFT OUTER JOIN (articles_tags AS at
  JOIN tags AS t ON (t.id = at.tag_id AND t.name = ?))
  ON (a.id = at.article_id)
WHERE MATCH (a.title) AGAINST (? IN BOOLEAN MODE) 
ORDER BY IF(t.name IS NOT NULL, 1.0, relevance) DESC;

Я предполагаю, что вы хотите, чтобы совпадения тегов совпадали с полной строкой, вместо использования полнотекстового поиска.

Также используется одно левое внешнее соединение вместо двух, потому что если соединение с article_tags выполняется , то тег наверняка есть. Поместите сравнение имен тегов в условие соединения, а не в предложение WHERE .

Логический режим заставляет MATCH () возвращать 1.0 при совпадении, что делает его бесполезным в качестве мера актуальности. Поэтому проведите дополнительное сравнение в списке выбора, чтобы вычислить релевантность. Это значение составляет от 0,0 до 1,0. Теперь мы можем повысить сортировку соответствия тегов, рассматривая его как имеющий релевантность 1.0.

2
ответ дан 14 December 2019 в 19:20
поделиться

Этот быстрый демонстрационный запрос далек от оптимизации, но должен стать хорошей отправной точкой

SELECT * FROM
(SELECT a.id, a.title, 
  MATCH (a.title) AGAINST ('$s_search_term') AS title_score,
  SUM(MATCH (t.name) AGAINST ('$s_search_term')
) AS tag_score
FROM articles AS a
LEFT JOIN articles_tags AS at
  ON a.id = at.article_id
LEFT JOIN tags AS t
  ON t.id = at.tag_id
WHERE MATCH (a.title) AGAINST ('$s_search_term') 
  OR MATCH (t.name) AGAINST ('$s_search_term')
GROUP BY a.id) AS table1
ORDER BY 2*tag_score + title_score DESC

Вы можете нормализовать tag_score, разделив его на COUNT (t.id). Извините, но легче задать вопрос, чем объяснить, как это сделать.

0
ответ дан 14 December 2019 в 19:20
поделиться

Вы можете захотеть посмотреть в SPHINX, http://www.sphinxsearch.com/

0
ответ дан 14 December 2019 в 19:20
поделиться

Вот как я сделал это в прошлом. Это выглядит медленно, но я думаю, что вы найдете это не так.

Я добавил немного сложности, чтобы показать, что еще можно легко сделать. В этом примере статья получит 1 точку для частичного матча заголовка, 2 балла для частичного матча тегов, 3 балла за точное совпадение тега и 4 точка для точного совпадения заголовка. Затем он добавляет те и сортировки по оценке.

SELECT
  a.*,
  SUM(
    CASE WHEN a.title LIKE '%keyword%' THEN 1 ELSE 0 END
    +
    CASE WHEN t.name LIKE '%keyword%' THEN 2 ELSE 0 END
    +
    CASE WHEN t.name = 'keyword' THEN 3 ELSE 0 END
    +
    CASE WHEN a.title = 'keyword' THEN 4 ELSE END
  ) AS score
FROM article a, articles_tags at, tags t
WHERE a.id = at.article_id
AND at.tag_id=t.id
AND (a.title LIKE '%keyword%' OR t.name LIKE '%keyword%')
GROUP BY a.id
ORDER BY score;

Примечания: Это не вернет статьи без тегов. Я использовал простые соединения, чтобы уменьшить шум в запросе и выделить только то, что делает счет. Чтобы включить статьи без тегов, просто сделайте присоединения оставленными присоединениями.

1
ответ дан 14 December 2019 в 19:20
поделиться

Стоит ли в данный момент смотреть на разгрузку поискового задания на что-то, что на самом деле написано именно для этой цели?

В наших продуктах мы используем MySQL для хранения данных, но индексируем все наши данные с помощью Lucene (через Solr - но это не относится к делу).

Стоит взглянуть на него, потому что он относительно прост в настройке, он очень мощный, и это намного проще, чем пытаться манипулировать базой данных, чтобы делать то, что вы хотите.

Извините, что это не прямой ответ на вопрос, я просто чувствую, что такие вещи всегда стоит упоминать в этом сценарии :)

.
2
ответ дан 14 December 2019 в 19:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: