作者carylorrk (Cary)
看板Database
标题[系统] SQLite fts tokenizer 结合 porter + 中文 unigram
时间Fri Nov 7 07:09:57 2014
资料库名称:
SQLite
资料库版本:
3.8.6
作业平台:
Gentoo Linux
问题描述:
最近在用 SQLite 的 fts(full-text search) 实作简单的 search function,
搜寻主要内容是数字、中文和英文。
fts 的资料可能如下:
pacakgeId |title
-------------------------------------
1 |"horse 马"
-------------------------------------
2 |"cute dogs 超级可爱的狗狗"
-------------------------------------
3 |"Roman 罗马"
-------------------------------------
4 |"Purin dog 布丁狗"
其实还会有其他国的 title(像是日、韩、德等),
不过目前使用者主要是使用中、英文。
目前尝试内建的 tokenizer,其中
porter 可以对英文做 stemming,(像是搜寻「dog」可以找到 2, 4)
但是中文就只会把整句当成一个 token,搜寻时必须搜寻整句或是开头+wildcard 才可以。
icu 可以对中英文或其他国语言分词,但是有两个问题
1. 没有办法像 porter 做 stemming,所以搜寻「dog」只会出现 4
2. 分词太「聪明」,会把「罗马」辨认成一个 token。
所以当搜寻「马」时只会出现 1,没有 3
简单来说,我希望
1. 英文 stemming,可以搜寻 dog 就找到 2, 4
2. 中文 unigram,搜寻「马」时找到 1, 3
3. 搜寻「罗马」时找到「罗 AND 马」(ex: 3,两字分开也没关系),「罗 马」时找「罗 OR 马」到 1, 3
(第三点似乎是内建的行为?不太确定。目前 icu 可以达到。例如:「可爱狗」可以找到 2,不会找到4)
4. (option)其他语言按照 icu 来分词。
我对 custom tokenizer 并不是很熟,文件和程式码看起来都不太友善XD
自己从头学习+实作是下下策,希望可以先找到有经验的前辈,看有没有类似功能的实作或是其他意见。
PS. 我也有在寻找 database 以外的解决办法,譬如把资料转移到 Lucene 上。
相关提案暂时还在摸索,所以这里还是以可以用现有 SQLite 解决的方法为主。
--
最後我发现是 ICU 的 word boundary 演算法让 break iterator 会判断多个汉字为一个单字,
而改中文 word boundary analysis 演算法可能没有比较简单
加上除非把 column 分成不同 virtual table 不然无法每个 column 用不同的 tokenizer
所以我最後是把 CJK 字元之间都加上空格(实作上不是,但大概是这个意思)然後用 porter
这样除了第四点以外都 OK 了
还有第三点是我的误会,他的每个 token 本来就是 AND 的关系,所以「罗 马」也是找到「罗 AND 马」。
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 1.34.244.41
※ 文章网址: http://webptt.com/cn.aspx?n=bbs/Database/M.1415315399.A.97C.html
※ 编辑: carylorrk (1.34.244.41), 11/07/2014 09:06:02
※ 编辑: carylorrk (1.34.244.41), 11/10/2014 04:23:58