MySQL Fulltext Поиск идеографических (азиатских) символов
-
03-07-2019 - |
Вопрос
У меня есть база данных, заполненная записями, заполненными азиатскими символами (на китайском, японском и корейском языках), а также база данных, заполненная записями на латинских символах (английская, французская, вы ее называете), и я хочу выполнить полный текст ищет их.
MySQL говорит:
Идеографические языки, такие как китайский и японцы не имеют слова разделители. Таким образом, FULLTEXT парсер не может определить где слова начинаться и заканчиваться в этих и других подобных языки. Последствия этого и некоторые обходные пути для проблемы описаны в разделе 11.8, & # 8220; Функции полнотекстового поиска & # 8221;.
Раздел 11.8 фактически не предлагает обходных путей и даже не упоминает проблему.
Итак, как бы вы отсортировали поиск по одному китайскому символу в базе данных со смешанными символами ? % LIKE%
будет работать, но у него нет отличных оценок релевантности. Должен ли я просто посчитать, сколько раз персонаж появляется в записи, и оценить по этому показателю? Я ценю любые ваши советы. Спасибо! Р>
Решение
Это зависит от размера набора данных. Если мы говорим о сотнях тысяч строк, я бы, наверное, взглянул на одно из превосходных доступных независимых решений для полнотекстового поиска. На самом деле мне никогда не приходилось сталкиваться с этой проблемой 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 использовать индексы для всех выборок, и, скорее всего, будет быстрее, чем соответствующий запрос, использующий один выбор и несколько операторов или)
Это оставляет нам рейтинг релевантности в качестве остающейся проблемы, о которой вы действительно просили. :) Это можно сделать с довольно хорошими результатами, используя Модель векторного пространства (VSM) а>. р>
После выполнения поиска первое, что вам нужно сделать, - это рассчитать tf-idf. оценка за этот токен. Это делается по формуле: Сначала рассчитайте эту оценку для каждого термина в поисковом запросе и сохраните результат в хэш-карте или в чем-то подобном. Это ваш первый вектор, называемый v_1. Затем перейдите к первому документу. Рассчитайте оценку tf-idf для каждого термина в документе и сохраните его как v_2. Теперь вы можете рассчитать оценку для этого документа, используя косинус сходства : Результатом является значение, которое можно использовать для ранжирования документа. Продолжайте и делайте это для каждого документа. Сортируйте их в порядке убывания. Первый документ в списке будет наиболее релевантным. Все это может показаться немного сложным, но если у вас есть некоторое базовое понимание линейной алгебры, вы, вероятно, сможете найти рабочее решение за несколько часов. Тем не менее, если это вообще возможно, используйте существующее решение, такое как lucene. 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
score = arccos(v_1 * v_2 / (|v_1| * |v_2|))