為了將帖子顯示到關(guān)注點相同的用戶面前,打算根據(jù)關(guān)注點相關(guān)的關(guān)鍵詞對帖子進行分類。
考慮關(guān)注點不是很多,在發(fā)帖時就對關(guān)鍵詞進行檢索分類,然后將分類關(guān)系保存在 DB 里。
具體實現(xiàn)上偷懶通過自定義詞典配置關(guān)鍵詞,采用 PostgreSQL 的全文檢索功能對帖子內(nèi)容分詞識別。
安裝 zhparser 中文分詞擴展
1.安裝SCWS
2.下載zhparser源碼
3.編譯和安裝zhparser
5.創(chuàng)建extension
具體可參照官網(wǎng),不過由于年久失修的緣故給出的命令遺漏了部分字符(比如 http: 后的 //),參考 GitHub反而更方便。
創(chuàng)建詞典
- 分詞詞典
默認(rèn)的分詞有時不能滿足需求,所以需要將自己的專有詞匯以擴展詞典的方式加入postgresql.conf(具體參考 zhparser 說明)
zhparser.extra_dicts = 'dict_extra.txt,mydict.xdb'
- 未添加自定義分詞詞典
=> select * from ts_debug('testzhcfg', '約翰惠特沃斯');
alias | description | token | dictionaries | dictionary | lexemes
-------+-------------+-------+-------------------------+------------+---------
n | noun | 約翰 | {thesaurus_test,simple} | simple | {約翰}
n | noun | 惠特 | {thesaurus_test,simple} | simple | {惠特}
n | noun | 沃斯 | {thesaurus_test,simple} | simple | {沃斯}
(3 rows)
- 添加自定義分詞詞典后
=> select * from ts_debug('testzhcfg', '約翰惠特沃斯');
alias | description | token | dictionaries | dictionary | lexemes
-------+-------------+--------------+-------------------------+------------+----------------
n | noun | 約翰惠特沃斯 | {thesaurus_test,simple} | simple | {約翰惠特沃斯}
(1 row)
- 同義詞詞庫
雖然自定義分詞詞典優(yōu)先度比系統(tǒng)的高,但遇到 中文+英文+數(shù)字 的復(fù)合詞匯時仍然無法作為一個整體正常解析為一個詞,而是會分成多個詞。這樣就用同義詞詞庫將多個詞構(gòu)成的 短語 重新定義為目標(biāo)詞。
/*
* 中文環(huán)境為主,英文單詞均精確匹配,未使用 Ispell 及 Snowball 詞典
* 為減少大寫寫差異導(dǎo)致同義詞庫條目增加,使用 Simple 詞典
*/
CREATE TEXT SEARCH DICTIONARY thesaurus_test (
TEMPLATE = thesaurus,
DictFile = thesaurus_test,
Dictionary = pg_catalog.simple
);
- 未添加同義詞詞典(同義詞庫用 ts_debug 調(diào)試可能不準(zhǔn),具體參見文檔)
=> select * from to_tsvector('testzhcfg', '毛瑟g98');
to_tsvector
------------------
'g98':2 '毛瑟':1
(1 row)
- 添加同義詞詞庫后
=> select * from to_tsvector('testzhcfg', '毛瑟g98');
to_tsvector
-------------
'毛瑟g98':1
(1 row)
配置解析
CREATE TEXT SEARCH CONFIGURATION testzhcfg (PARSER = zhparser);
/*
* 為防止遺漏造成同義詞庫匹配失敗,將所有詞性全部映射
* 為保留同義詞庫未匹配項,增加 Simple 字典的映射
*/
ALTER TEXT SEARCH CONFIGURATION testzhcfg ADD MAPPING FOR a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z WITH thesaurus_test,simple;
代碼邏輯
- 在分類表中增加 TSQUERY 類型字段指定關(guān)鍵詞
- 提交帖子時將帖子內(nèi)容分詞后和關(guān)鍵詞進行匹配
to_tsvector('testzhcfg', '帖子內(nèi)容') @@ TSQUERY字段
- 保存帖子和匹配到分類間的關(guān)系
至此成功達到目的。
附注:
其他參考
SCWS 中文分詞詞性標(biāo)注
PostgreSQL 官方文檔 概念相關(guān)
PostgreSQL 官方文檔 命令相關(guān)-
常用調(diào)試命令
- 調(diào)試 dictionary
由于輸入被當(dāng)做單獨標(biāo)記,所以沒法針對 thesaurus 的 phrase 進行調(diào)試
- 調(diào)試 dictionary
select ts_lexize(dictionary, text)
- 調(diào)試 parser
select * from ts_debug(config, text)
- 調(diào)試 config
select to_tsvector(config, text)
select plainto_tsquery(config, text)
- 查看 parser 支持的詞性
select * from ts_token_type(parser);