建立倒排索引,快速搜索匹配数据
上篇文章我已经实现了对中英文、数字基本的分词,相关的处理逻辑还有非常多可优化的空间,我在这里先不扩展了,感兴趣的朋友可从这里翻看”利用Go语言编写一个搜索引擎“。
完成了基本的分词之后,我们这篇文章开始进入下一步,建立倒排索引。
建立倒排索引一定要有相关的索引库,特别是中文、英文、字母、数字,这需要相当长的时间去收集。
我们先通过这个循环将所有中文汉字输出来,总共有20902个字:
var i rune
// 19968即对应unicode码\u4e00
// 40869即对应unicode码\u9fa5
for i = 19968; i <= 40869; i++ {
fmt.Println(string(i))
}
除了单个的汉字,我们还需要收集大量的中文词语、也包括英文单词,例如:“语言”、“编程”、“搜索引擎”等等等等,我在这里不做扩展,只需要重点确保倒排索引的数据表结构。
建表,保存倒排索引
CREATE TABLE `index` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`gid` int unsigned NOT NULL default 0 comment '组id',
`type` tinyint(1) NOT NULL DEFAULT 0 COMMENT '1.纯中文; 2.纯字母; 3.纯数字; 4.中文+字母; 5.中文+数字; 6.字母+数字; 0.其他',
`name` varchar(30) NOT NULL DEFAULT '' COMMENT '关键字名称',
`py` varchar(60) NOT NULL DEFAULT '' COMMENT '拼音 仅中文汉字时不为空',
`created_ts` int unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
`updated_ts` int unsigned NOT NULL DEFAULT '0' COMMENT '修改时间',
`deleted_ts` int unsigned NOT NULL DEFAULT '0' COMMENT '删除时间',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3 COMMENT='倒排索引';
这个数据表尤其要注意 gid 这个字段,对于同意词用这个字段来做区分即可,举个例子:当爬虫爬行的时候,发现一个标题叫作“为什么要编程”。
如果对这个标题进行分词,匹配倒排索引之后则会得出这样的数据:[为什么 要 编程]
而倒排索引的数据表里面保存有这样的索引数据:
id | gid | name |
---|---|---|
1 | 1 | 为什么 |
2 | 1 | 为啥 |
3 | 1 | 为何 |
4 | 2 | 要 |
5 | 3 | 编程 |
我将“为什么”、“为何”、“为啥”分为了一组。因此,当用户搜索“为啥要编程”的时候,通过相同的 gid 来匹配便能得出标题为“为什么要编程”的文章了。
另外,在上面的数据表中,我还增加了一个拼音字段,针对中文汉字,可以做拼音转换,可以在这里查看中文汉字转拼音的方式。
现在,先将中文单个汉字全部导入到这张索引表。
func main() {
var (
i rune
py string
err error
)
// 19968即对应unicode码\u4e00
// 40869即对应unicode码\u9fa5
for i = 19968; i <= 40869; i++ {
if py, err = pinyin.New(string(i)).Mode(pinyin.WithoutTone).Convert(); err != nil {
println(err.Error())
} else {
fmt.Println(py)
}
// 数据库写入操作
// ..
}
}
另外还有导入所有字母、数字、英文单词,对于英文单词和字母的处理,全部用小写就好了,在匹配的时候先提前转为小写字母。
考虑到英文单词数量非常多,如果索引数据比较大的情况下,可以分成几张数据表,如中文和英文分开保存,查询的时候自己做匹配就好了。
以上就是我建立简单的倒排索引的方式。对于中文词语、成语、短语等,就需要自己去找了,特别是一些关于编程的技术名词。这是一项长期的工作,一般由专门的运营去进行增改。
声明: 因编程语言版本更新较快,当前文章所涉及的语法或某些特性相关的信息并不一定完全适用于您当前所使用的版本,请仔细甄别。文章内容仅作为学习和参考,若有错误,欢迎指正。