Зависит от размера набора данных. Если мы говорим о сотнях тысяч строк, я бы, наверное, взглянул на одно из превосходных доступных независимых решений для полнотекстового поиска. На самом деле мне никогда не приходилось сталкиваться с этой проблемой mysqlf, поэтому я не уверен, какие решения включают поддержку азиатских языков.
Однако я знаю, что lucene оснащен анализатором для китайского, японского и корейского языков, поэтому я предполагаю, что он имеет некоторую поддержку для того, что вы делаете. Обычно, когда мне нужно интегрировать lucene с php, я использую lucene как сервер сокетов и подключаюсь к нему с php.
Если набор данных достаточно мал, возможно, вам будет предложено применить собственный подход. Эта проблема состоит из двух частей: поиск документов для оценки и фактическое ранжирование. Есть несколько способов сделать поиск. Можно использовать LIKE, если набор данных достаточно мал. Другим может быть накатить собственную схему индексации на диске, хотя это будет довольно сложно и отнимает много времени. Вы также можете использовать MySQL в качестве промежуточного пути, как описано ниже.
Чтобы реализовать схему индексирования с использованием MySQL, вам необходимо создать несколько таблиц со следующей структурой:
document
document_id
document_text
document_tokencount
document_token
document_id
token_id
token_docfrequency
index (token_id, document_id)
token
token_id
token_unicode
token_globalfrequency
index (token_unicode)
Затем я обрабатываю каждый документ и вставляю строку в таблицу document_token для каждого символа (токена) в документе. Поле token_unicode будет содержать целочисленную последовательность Unicode, используемую для ссылки на этот символ. Поле token_docfrequency содержит целое число, соответствующее количеству раз, которое документ содержит токен, в то время как поле token_globalfrequency содержит общее количество раз, когда термин используется во всех документах.
Это позволит вам быстро искать токены:
SELECT * FROM document_token WHERE token_id = 1
UNION
SELECT * FROM document_token WHERE token_id = 2
UNION
SELECT * FROM document_token WHERE token_id = 3
(объединенный подход - это хак, который позволяет mysql использовать индексы для всех выборок и, скорее всего, будет быстрее, чем соответствующий запрос, использующий один выбор и несколько операторов или)
Это оставляет нам рейтинг релевантности в качестве остающейся проблемы, о которой вы действительно просили. :) Это можно сделать с довольно хорошими результатами, используя Vector Space Model (VSM) .
После выполнения поиска первое, что вам нужно сделать, - это вычислить оценку tf-idf для этого токена. Это делается по формуле:
tf-idf = tf(t,d) / tf(d) * log(D / d(t))
where:
tf(t,d) = token frequency in current document
tf(d) = total number of tokens in current document
D = total number of documents
d(t) = number of document that contains the token
Сначала вычислите эту оценку для каждого термина в поисковом запросе и сохраните результат в хэш-карте или в чем-то подобном. Это ваш первый вектор, называемый v_1. Затем перейдите к первому документу. Рассчитайте оценку tf-idf для каждого термина в документе и сохраните его как v_2. Теперь вы можете рассчитать оценку для этого документа, используя косинус similiarity :
score = arccos(v_1 * v_2 / (|v_1| * |v_2|))
Результатом является значение, которое можно использовать для ранжирования документа. Продолжайте и делайте это для каждого документа. Сортируйте их в порядке убывания. Первый документ в списке будет наиболее релевантным.
Все это может показаться немного сложным, но если у вас есть некоторое базовое понимание линейной алгебры, вы, вероятно, могли бы найти рабочее решение за несколько часов. Тем не менее, если это вообще возможно, используйте существующее решение, такое как lucene.