MySQL Fulltext搜索表意文字(亚洲)字符

我有一个充满亚洲字符填充记录(中文,日文和韩文)的数据库以及带有拉丁字符填充记录的数据库(英文,Français,你的名字),我想对它们进行全文搜索.

MySQL说:

Ideographic languages such as Chinese
and Japanese do not have word
delimiters. Therefore, the FULLTEXT
parser cannot determine where words
begin and end in these and other such
languages. The implications of this
and some workarounds for the problem
are described in Section 11.8,
“Full-Text Search Functions”.

第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

(union方法是一个hack,允许mysql为所有选择使用索引,并且很可能比使用单个select和几个或语句的相应查询更快)

这使得我们将相关性排名作为剩下的问题,这就是您真正要求的. :)这可以通过利用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.现在,您可以使用cosine similiarity计算此文档的分数:

score = arccos(v_1 * v_2 / (|v_1| * |v_2|))

结果是一个可用于对文档进行排名的值.继续并为每个文档执行此操作.它们按降序排序.列表中的第一个文档将是最相关的文档.

这可能听起来有点复杂,但如果你对线性代数有一些基本的了解,你可能会在几个小时内产生一个有效的解决方案.尽管如此,如果可能的话,使用现有的解决方案,如lucene.

点赞