Полнотекстовый поиск по сайту — бич современного интернета
Реализация хорошего поиска по сайту — часто сильно недооцененная по сложности задача. Поиск является слабым местом сайтов настолько часто, что когда я вижу строку поиска, у меня сразу же возникает предвзятое ощущение предстоящего фиаско. И чтобы лишний раз не расстраиваться, я сразу переадресую свой вопрос гуглу или яндексу и быстро нахожу то, что требовалось. Что же делать, чтобы как-то улучшить эту ситуацию?
Форма поиска по сайту от Яндекса и Гугла
Качество поиска
Для начала нужно понять, из чего вообще складывается понятие качества поиска. Качество поиска зависит от многих факторов. О многих из них можно прочитать в книге известного поискового оптимизатора кандидата технических наук Игоря Ашманова. (Скажу по секрету, что недавно видел её на torrents.ru). Все факторы условно можно разбить на три категории: полнота, точность и ранжирование.
Полнота
Причина этого чаще всего в том, что на большинстве сайтов реализован поиск только по динамическим данным из-за того, что поисковая программа получает данные из базы данных. Более того, обычно вебмастер (или создатель CMS) решает, какие таблицы в БД самые важные, а какие недостойны внимания. В результате «за бортом» поиска остаются некоторые «малозначимые» динамические данные и все статические страницы.
С другой стороны, если поставить целью обеспечение максимальной полноты поиска, то в результатах может оказаться много «мусорных» и дублирующихся страниц, что тоже негативно сказывается на лояльность пользователей.
Точность
Точность поиска — это характеристика соответствия найденных страниц поисковому запросу. В неё входят учет морфологии, снятие омонимии, учет опечаток, поиск по синонимам и др. Например, если пользователь ищет «количество голов Аршавина», то ясно, что головы тут ни при чем, и нужно показывать только информацию про забитые голы. Вот еще один интересный пример омонимии. Но это высший пилотаж, а самое простое, что хочет увидеть пользователь — это поиск по всем возможным словоформам.
Полнотекстовый поиск в 1С (что это и пример использования)
Полнотекстовый поиск предоставляет следующие возможности:
Полнотекстовый поиск можно осуществлять в любой конфигурации на платформе 1С:Предприятие 8
Для того чтобы открыть окно управления полнотекстовым поиском необходимо выполнить следующее:

Как вы можете заметить свойство Использовать установлено для всего справочника Контрагенты, но сделать это можно и для каждого его реквизита соответствующего типа.
Рассмотрим более подробно полнотекстовый индекс, который состоит из двух частей (индексов): основного индекса и дополнительного. Высокая скорость поиска данных обеспечивается за счет основного индекса, но обновление его происходит относительно медленно, в зависимости от объема данных. Дополнительный индекс ему противоположен. Данные добавляются в него намного быстрее, но поиск осуществляется медленнее. Система осуществляет поиск одновременно в обоих индексах. Большая часть данных находится в основном индексе, а данные добавляемые в систему попадают в дополнительный индекс. Пока объем данных в дополнительном индексе небольшой, поиск по нему происходит относительно быстро. В тот момент, когда нагрузка на систему невелика, происходит операция слияния индексов, в результате чего дополнительный индекс очищается, а все данные помещаются в основной индекс. Слияние индексов предпочтительнее выполнять в тот момент времени, когда нагрузка на систему минимальна. С этой целью можно создавать регламентированные задания и задания по расписанию.
Специальные операторы, допустимые при задании поискового выражения
Механизм полнотекстового поиска допускает написание части символов русского слова одноклавишными латинскими символами. Результат поиска при этом не измениться.
Два оператора РЯДОМ
Групповой символ «*» может использоваться только в качестве замены конца слова
Оператор нечеткости «#». Если неизвестно точное написание названия, имени.
Программными средствами и средствами 1с: программирование.
Оператор синонимов «!». Позволяет найти слово и его синонимы
Как программно обновить индекс полнотекстового поиска?
Пример полнотекстового поиска данных
Определение переменной СписокПоиска
Кроме этого в процедуре обработки события ПриОткрыии формы определим, что эта переменная будет содержать список полнотекстового поиска, с помощью которого мы и будем осуществлять поиск в данных
Теперь для события нажатия на кнопку Найти напишем код, который позволит нам выполнять поиск в соответствии с тем выражением, которое задано в поле ПоисковоеВыражение
Сначала в этой процедуре мы устанавливаем поисковое выражение, введенное пользователем, в качестве строки поиска для полнотекстового поиска. Затем выполняем метод ПерваяЧасть(), который собственно запускает полнотекстовый поиск и возвращает первую порцию результатов. По умолчанию порция содержит 20 элементов. После этого мы анализируем количество элементов в списке поиска. Если он не содержит ни одного элемента, то мы выводим в форму соответствующее сообщение. В противном случае вызывается процедура ВывестиРезультатПоиска(), которая отображает полученные результаты пользователю.
Создадим в модуле формы процедуру с таким именем и напишем в ней код,
Действия, выполняемые в этой процедуре, просты. Сначала мы формируем сообщение о том, какие элементы отображены и сколько всего элементов найдено. Затем получаем результат полнотекстового поиска в виде HTML-текста и выводим этот текст в поле HTML-документа, расположенное в форме.
В заключение передаем управление в процедуру ДоступностьКнопок() для того, чтобы сделать доступными или, наоборот, запретить доступ к кнопкам Предыдущая порция и Следующая порция (в зависимости от того, какая порция полученных результатов отображена). Текст этой процедуры представлен в Коде
Теперь необходимо создать обработчики событий нажатия на кнопки ПредыдущаяПорция() и СледующаяПорция().
Заключительным «штрихом» будет создание обработчика события onclick поля HTML-документа, расположенного в форме. Дело в том, что результат полнотекстового поиска, представленный в виде HTML-текста, содержит гиперссылки на номера элементов списка поиска. И нам хотелось бы, чтобы при переходе пользователя на эту ссылку система открывала бы форму того объекта, который содержится в этом элементе списка. Для этого мы будем перехватывать событие onclick HTML-документа, содержащегося в поле HTML-документа, получать номер элемента списка из гиперссылки и открывать форму соответствующего объекта. Текст обработчика события onclick поля HTML-документа представлен в коде
Что такое полнотекстовый поиск?
Вы вряд ли получите какие-либо результаты поиска, если поисковые системы будут искать записи данных по точному совпадению. Например, приведенный ниже оператор SQL вряд ли вернет какие-либо записи, потому что, вероятно, не существует такого продукта с названием или описанием, точно таким же, как текстовая фраза «canned food with fish and tomato» в названии или описании.
Это может немного помочь, если мы будем использовать подстановочный знак «LIKE%», но вы будете получать только те записи, которые содержат точную текстовую фразу в полях данных.
Идея полнотекстового поиска состоит в том, чтобы разбивать текстовые фразы на токены. Текстовая фраза в приведенном выше примере разбита на следующие токены: «консервы», «еда», «с», «рыба», «и» и «помидоры». Затем поисковые системы ищут все записи, соответствующие любому из токенов. Чем больше токенов соответствует записи, тем больше она релевантна текстовой фразе. Следовательно, поисковые системы указывают на релевантность, выставляя оценку в результатах поиска. Вы можете получить результат поиска с огромным количеством записей, если токены в строке запроса содержат общие слова, такие как «еда», и многие продукты могут соответствовать одному или нескольким токенам. Однако вы всегда можете отфильтровать результат по баллам, чтобы получить наиболее релевантные записи.
Короче говоря, и MySQL, и Elasticsearch разделяют схожие идеи полнотекстового поиска. Он предназначен для создания индексов путем разложения текстового содержимого на токены. Затем запрос разбивает текст запроса на токены и сопоставляет его с индексами. На основе результата сопоставления поисковые системы вычисляют оценку и присваивают результату поиска, который представляет релевантность.
Напротив, дизайн Elasticsearch легко настраивается. Процесс декомпозиции токена и выполнения запроса выполняется на основе набора анализаторов, токенизаторов и фильтров. Эти компоненты можно настроить и собрать вместе, чтобы реализовать более сложные функции.
У меня будет пошаговое руководство по использованию полнотекстового поиска в MySQL и Elasticsearch.
Образец набора данных
Демонстрация функций полнотекстового поиска основана на образце набора данных, который представляет собой набор записей библиотечной книги. Схема довольно проста со следующими столбцами: id, title и publishingPlace.
MySQL
Выполните приведенные ниже операторы SQL, чтобы создать таблицу библиотечной книги и импортировать образцы данных.
MySQL нуждается в настройке индекса для полнотекстового поиска, выполните приведенную ниже инструкцию, чтобы создать полнотекстовый индекс для ‘title’ и ‘publishingPlace’, предполагая, что читатели заинтересованы в поиске книг на основе этих двух полей данных.
Elasticsearch
Все операции CRUD в Elasticsearch выполняются с помощью вызовов REST API. Чтобы загрузить тот же набор записей образцов книги в Elasticsearch, запустите команду curl ниже, которая отправляет запрос POST для массовой вставки данных.
Простой поиск по ключевым словам
Начнем с простого поиска, допустим, мы ищем одно ключевое слово «edinburgh».
MySQL
Чтобы найти все записи, соответствующие этому ключевому слову, используйте match() в MySQL для выполнения полнотекстового запроса в логическом режиме. Запустите этот оператор SQL, чтобы найти «edinburgh».
Результат поиска присваивает каждой записи оценку, чтобы показать актуальность. Чем выше оценка, тем больше запись релевантна ключевому слову. Есть 3 записи с оценкой > 0 как название и публикация, которые соответствуют ключевому слову «edinburgh», в то время как другие записи не соответствуют ключевому слову, поэтому присваивается НУЛЕВОЙ балл.
Elasticsearch
Результат совпадает с результатом MySQL. 3 записи соответствуют ключевому слову «edinburgh», но присвоенные оценки не совпадают из-за другого механизма расчета релевантности в Elasticsearch.
Оценка точной настройки на основе указанных полей данных
Для некоторых случаев использования определенные поля данных более важны, и совпадениям ключевых слов в этих полях следует давать более высокий балл. Хотя MySQL не предлагает такой гибкости, ее можно достичь в Elasticsearch, добавив в поле данных символ вставки «^». В приведенном здесь примере показано, что поле «заголовок» в 3 раза важнее.
Поскольку «заголовок» более важен, записи с полем «заголовок», совпадающим с ключевым словом, получают более высокий балл.
Поиск с логическими условиями
Вы можете указать определенные критерии поиска, такие как И / ИЛИ / НЕ. Скажем, мы хотим найти книги, которые соответствуют ключевым словам «life» и «live». Для этого мы добавляем символ «+» перед каждым ключевым словом, чтобы указать, что это условие «И».
MySQL
BOOLEAN режим, предоставляемый MySQL, поддерживает запросы с логическими условиями. Давайте искать книги по ключевым словам «life» и «live».
Сейчас актуальна только книга «A life to live» с оценкой > 0, а все остальные книги с оценкой = 0.
Логический режим поддерживает не только оператор AND (+), но и другие символы, такие как NOT (
), более высокую релевантность (>), более низкую релевантность (
Поиск текстовой фразы
Каков результат поиска текстовой фразы, скажем, «Recipes Of A Delicious And Tasty Meal»? Поскольку текстовая фраза разбита на лексемы в нижнем регистре «recipes», «of», «a», «delicious», «and», «tasty» и «meal». Записи соответствуют большему количеству токенов, что означает, что они более релевантны текстовой фразе.
Люди обычно набирают текстовые фразы для запросов на человеческом языке. Принимая во внимание человеческий язык, для получения точных результатов необходимо особое внимание. Например, сопоставление тех слов, которые часто встречаются в английском языке, таких как «a», «an», «of», «the» и т.д., вряд ли приведет к значимым результатам. Эти слова называются «стоп-словами», поисковые системы должны игнорировать их в запросах текстовых фраз.
MySQL
MySQL поддерживает режим естественного языка, который игнорирует «стоп-слова» и выполняет поиск без учета регистра. Запустите этот оператор запроса, чтобы найти текстовую фразу.
Первые 3 записи с наибольшим количеством очков соответствуют большинству токенов во фразе поискового текста.
Elasticsearch
Настройки индекса по умолчанию Elasticsearch не содержат таких функций, как режим естественного языка, предлагаемых MySQL.
Вы увидите другой результат, когда отправите этот POST-запрос в Elasticsearch для поиска той же текстовой фразы.
Настройки по умолчанию учитывают стоп-слова при сопоставлении и подсчете очков. В результате результат поиска с наивысшим баллом, совпадающим с большинством стоп-слов, таких как «of» и «and», по-видимому, не имеет отношения к делу.
Не беспокойтесь, Elasticsearch на самом деле является очень мощной поисковой системой, поддержка поиска на естественном языке может быть осуществлена путем настройки фильтров токенов для стоп-слов в настройках индекса.
Elasticsearch предлагает 15 токензеров и более 50 фильтров токенов, которые подходят для различных сценариев использования. Чтобы добиться полнотекстового поиска, аналогичного MySQL, достаточно просто добавить в анализатор фильтр маркеров стоп-слов. На схеме ниже показано, что анализатор состоит из следующих компонентов:
Анализатор настраивается в настройках индекса и сопоставляется с полями данных «title» и «publishingPlace».
Отправьте этот запрос PUT, чтобы создать новый индекс с названием «library-book-text-phrase» (т.е. База данных в Elasticsearch) с новой конфигурацией анализатора и сопоставлением полей.
Затем отправьте этот запрос POST для копирования данных из исходного индекса «library-book» во вновь созданный индекс «library-book-text-phrase».
Давайте запустим тот же запрос по новому индексу «library-book-text-phrase». Теперь результат имеет больше смысла.
Мощная поисковая система способна не только выполнять поиск по соответствию токенов, но также понимать ключевые слова и расширять поиск других ключевых слов с аналогичным значением. Например, ожидается, что поисковые системы должны искать записи, которые соответствуют другим аналогичным ключевым словам, таким как «timber», «lumber» и «trees», при поиске по ключевому слову «woods».
MySQL может угадать, что вы ищете, используя режим «QUERY EXPANSION».
Когда мы ищем ключевое слово «зеленый». Будут возвращены 3 записи. Поле заголовка 2-й и 3-й записи на самом деле не содержит ключевого слова «green», но поисковая система каким-то образом предполагает, что содержание этой записи имеет отношение к ключевому слову «green».
Однако результаты поиска будут содержать больше «шума», если мы добавим больше ключевых слов в критерии поиска. Практически все книжные записи попадают в текстовую фразу «a good life» при поиске в режиме расширения запроса.
Невозможно точно настроить результат поиска, если вас не устраивает точность.
Elasticsearch предлагает несколько способов выполнить расширенный поиск, аналогичный режиму расширения, поддерживаемому MySQL. Вместо того, чтобы предоставлять фиксированное решение, использование токен-фильтров позволяет реализовать расширенный полнотекстовый поиск.
Давайте посмотрим на поддержку поиска по синонимам. Мы настраиваем фильтр токенов так, чтобы он расширял поиск до синонимов. Мы используем бесплатную лексическую базу данных WordNet. В целом в нем хранится более 20 тыс. слов и сопоставление с синонимами.
Конфигурация заключается в добавлении нового фильтра токенов для синонимов, и фильтр считывает сопоставления синонимов из файла WordNet.
Чтобы включить новые настройки индекса, загрузите файл WordNet и скопируйте его в elasticsearch/config/analysis, затем отправьте этот запрос PUT, чтобы создать новый индекс под названием «library-book-synonym-wordnet».
Затем отправьте этот запрос POST для копирования данных из исходного индекса «library-book» во вновь созданный индекс «library-book-synonym-wordnet».
Теперь найдите ключевое слово «green» в новом индексе. Затем вы получите список записей, который соответствует синониму «green».
Фильтр синонимов токенов Elasticsearch с настраиваемыми сопоставлениями слов
Отправьте этот запрос PUT, чтобы создать новый индекс и настраиваемый анализатор с фильтром токенов «synonym_filter».
После копирования данных во вновь созданный индекс отправьте этот запрос POST для поиска по ключевому слову «banana». Затем вы увидите, что результат содержит все записи, соответствующие ключевому слову «fruit».
Последние мысли
И MySQL, и Elasticsearch предоставляют мощные возможности полнотекстового поиска. Если ваша система использует MySQL в качестве хранилища данных, функцию полнотекстового поиска можно быстро включить, создав полнотекстовые индексы для целевых полей данных. Решение отлично работает для большинства случаев использования, поскольку оно предлагает пользователям быстрый способ поиска ключевых слов и текстовых фраз в нескольких полях данных. Однако, когда дело доходит до точной настройки и настройки результатов поиска, в MySQL доступны ограниченные возможности. Следовательно, Elasticsearch, вероятно, является лучшим вариантом для расширенных функций и индивидуального поведения поиска, поскольку решение легко настраивается и гораздо более гибкое.
Полнотекстовый поиск и его возможности
Многие СУБД поддерживают методы полнотекстового поиска (Fulltext search), которые позволяют очень быстро находить нужную информацию в больших объемах текста.
В отличие от оператора LIKE, такой тип поиска предусматривает создание соответствующего полнотекстового индекса, который представляет собой своеобразный словарь упоминаний слов в полях. Под словом обычно понимается совокупность из не менее 3-х не пробельных символов (но это может быть изменено). В зависимости от данных словаря может быть вычислена релевантность – сравнительная мера соответствия запроса найденной информации.
В статье рассказывается как работать с полнотекстовым поиском на примере БД MySQL, а так же приведу примеры «нестандартного» использования данного механизма.
В MySQL возможности полнотекстового поиска (только для MyISAM-таблиц) поддерживаются начиная с версии 3.23.23. В последующих версиях механизм потерпел существенные доработки и расширения, в тоге превратившись в мощное средство для создания поисковых механизмов веб-приложений. Главная особенность – быстрый поиск слов в очень больших объемах текстовой информации.
Индекс FULLTEXT
Итак, чтобы работать с полнотекстовым поиском, сначала нам нужно создать соответствующий индекс. Он называется FULLTEXT, и может быть наложен на поля CHAR, VARCHAR и TEXT. Причем, как и в случае с обычным индексом – если происходит поиск по 2-м полям, то нужен объединенный индекс 2-х полей, используйте поиск по одному полю – нужен индекс только этого поля. Например:
CREATE TABLE `articles` (
`id` int(10) unsigned NOT NULL auto_increment,
`title` varchar(200) default NULL,
`body` text,
PRIMARY KEY (`id`),
FULLTEXT KEY `ft1` (`title`,`body`),
FULLTEXT KEY `ft2` (`body`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
В этом примере создается таблица с 2-мя полнотекстовыми индексами: ft1 и ft2, которые можно использовать для поиска в полях title и body, или только в body. Только в поле title искать не получится.
Конструкция MATCH-AGAINST
Собственно для самого полнотекстового поиска в MySQL используется конструкция MATCH(filelds)… AGAINST(words). Она может работать в различных режимах, которые достаточно сильно между собой отличаются. Для всех действует следующее правило: данная конструкция возвращает условную релевантность, но способ вычисления которой может быть разным в зависимости от режима. Еще стоит добавить что во всех режимах поиск всегда регистрозависимый. Далее более подробно о каждом из них.
MATCH-AGAINST IN NATURAL LANGUAGE MODE
— это основной вид поиска, который используется по умолчанию, т.е. если режим не указан:
SELECT * FROM `articles` WHERE MATCH (title,body) AGAINST (‘database’);
В этом примере мы ищем слово database в полях title и body таблицы articles на основе индекса ft1 (см. пример создания таблицы выше). Выборка будет автоматически отсортирована по релевантности – это происходит в случае указания конструкции MATCH-AGAINST внутри блока WHERE и не задано условие сортировки ORDER BY.
Кстати, несмотря на возможности алиасов, при запросах конструкцию приходится повторять в разных местах, что усложняет запросы. Вот например нельзя написать так:
SELECT *, MATCH (title,body) AGAINST (‘database’) as REL
FROM `articles`
WHERE REL > 0;
— этот запрос выдаст ошибку: поле Rel не определено. Что бы работало, придется продублировать данную конструкцию:
SELECT *, MATCH (title,body) AGAINST (‘database’) as REL
FROM `articles`
WHERE MATCH (title,body) AGAINST (‘database’) > 0;
Однако, сколько бы вы не использовали одну и туже конструкцию (разумеется с одинаковыми параметрами) она будет вычислена только один раз.
В примере выше в переменной REL будет вычислена релевантность. Эта величина зависит прежде всего от количества слов в полях tilte и body, того насколько близко данное слово встречается к началу текста, отношения количества встретившихся слов к количеству всех слов в поле и др.
Например, релевантность будет не нулевая, если слово database встретится либо в title, либо body, но если оно встретится и там и там, значение релевантности будет выше, нежели если оно два раза встретится в body.
Сама по себе релевантность ничего не определяет. Это лишь сравнительная характеристика, по которой можно сортировать результат выборки, не более того.
Еще следует заметить что для IN NATURAL LANGUAGE MODE действует так называемое «50% threshold». Это означает, что если слово встречается более чем в 50% всех просматриваемых полей, то оно не будет учитываться, и поиск по этому слову не даст результатов.
MATCH-AGAINST IN BOOLEAN MODE
В бинарном режиме, в отличие от других режимов, релевантность вычисляется несколько иначе — как условная мера совпадения заданного шаблона. Положение искомого шаблона в тексте, количество встретившихся вариантов роли не играют.
Самая важная особенность бинарного режима – возможность указания логических операторов. Сами операторы я приводить не буду, о них хорошо рассказано в оригинальной документации по MySQL.
Еще особенностями бинарного режима является отсутствие автоматической сортировки в случае указания условия WHERE, однако для сортировки можно использовать алиас:
SELECT *,
MATCH (title,body) AGAINST (‘+database MySQL’ IN BOOLEAN MODE) as REL
FROM `articles`
WHERE MATCH (title,body) AGAINST (‘+database MySQL’ IN BOOLEAN MODE)
ORDER BY REL;
Пример выведет все записи содержащие слово database, но если в записи присутствует слово MySQL, то его релевантность будет выше. Записи будут отсортированы по релевантности.
В бинарном режиме отсутствует ограничение «50% threshold». Бинарный режим можно использовать и без создания полнотекстового индекса, однако это будет работать очень медленно.
MATCH-AGAINST IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION
Или просто «WITH QUERY EXPANSION». Работает примерно также, как NATURAL LANGUAGE MODE, с той лишь разницей, то в результат поиска попадают не только совпадения с шаблоном, но и возможные логические совпадения. Это работает примерно так:
Сначала MySQL выполняет запрос аналогичный NATURAL LANGUAGE MODE и формирует результат. По этому результату производится попытка вычислить слова, которые так же имеют высокую релевантность для полученной выборки. В случае, если эти слова присутствуют производится поиск и по ним тоже, но значение их на релевантность будет существенно ниже. Отдается смешанная выборка – сначала те результаты, где слово присутствует, а потом те, которые были получены в результате «повторного» поиска.
WITH QUERY EXPANSION не рекомендуется использовать для больших объемов информации, так как в результат может попасть очень много лишнего.
Использование FULLTEXT SEARCH
Пара слов об алгоритмах поиска
Соответственно, с поисковым запросом надо сделать тоже самое. Режим поиска используется любой – как удобнее… А вообще поиск – это отдельная тема, про которую нужна отдельная статья.
Раскрытие связок многое-ко-многим
В некоторых случаях – не во всех – с помощью полнотекстового поиска можно раскрывать соотношения многое-ко-многим без привлечения третьей таблицы.
Допустим, у нас есть две большие таблицы: с пользователями и группами пользователей. Причем, каждый пользователь имеет отношение к большому количеству различных групп, в свою очередь группы включают в себя большое количество пользователей. При нормальном соотношении (т.е. раскрытии через 3-ю таблицу), что бы выбрать все группы, которые принадлежат к некоторому пользователю понадобиться сделать запрос, объединяющий 2 или 3 таблицы, что даже при присутствии индексов очень накладно.
Однако можно выполнить денормализацию по следующей схеме:
Теперь, что бы выбрать группы, принадлежащие к пользователю 2 можно сделать:
SELECT *
FROM `groups`
WHERE MATCH (groups) AGAINST (‘+user2’ IN BOOLEAN MODE);
Это будет работать намного быстрее, чем исходный вариант (с 3-ей таблицей). Аналогично с группами, но если подобные выборки нам в принципе не нужны, то можно обойтись без соответствующего поля в таблице групп. Тогда получится что-то вроде «односторонней» связи M:N. То есть можно вычислить все M, которые принадлежат к N, не нельзя сделать обратного.
В этом случае, как правило, используется IN BOOLEAN MODE.
— Кстати, на эту схему очень хорошо ложится тегирование информации, но там не все так просто и это опять же отдельная тема.
Использование релевантности как меры отношения одного объекта к другому
Один из алгоритмов для вычисления статей, «похожих» на данную статью. Всё просто: берутся теги данной статьи, и делается полнотекстовый запрос по полю с тегами всех остальных статей с сортировкой по релевантности (если она нужна). Естественно, сначала вылезут те, которые содержат максимальное совпадение по тегам.
Можно и без учета тегов. Если статьи индексированы для полнотекстового поиска, из индекса выбираются с десяток наиболее употребляемых слов, после чего делается поиск по ним.
Или вот еще пример – интересы пользователей. Используя точно такую же схему можно легко найти других пользователей, у которых интересы наиболее соответствуют вашим.












