likes
comments
collection
share

用go构建个简单的搜索(三)对上篇索引文件优化

作者站长头像
站长
· 阅读数 101

用go构建个简单的搜索(一)

用go构建个简单的搜索(二)最简单的索引文件

问题

上篇介绍了简单的索引文件结构,但是有个缺点是索引文件比源文件大太多了。所以这里想了些办法做了些尝试,最根本的原因是数据的位置信息越多越在后面占的数据量越多。

问题原因:

急忙|1|9|244916 244922|239419 239425|229922 229928|194147 194153|183813 183819|167921 167927|133701 133707|94319 94325|62012 62018

词|文档ID|词频|位置开始和结束1|位置开始和结束2|位置开始和结束3

急忙:本身的字节长度是6位,但是后面用了两个6位数的数字去去表示它的位置,并且还是多个位置

尝试的一些解决办法

首先想到的是位图但场景不合适

我想那么多坐标位置能不能用位图?然后在网上找了个代码还测出来个bug。最后失败告终。单个词位置信息量太少,但位图适合海量数据。举例上面急忙 总的9个位置18标识 需要244916/8=30,614.5 多个字节表示。如果数据量有244916么多倒是可以用,但是这里的6位数坐标需要6个字节就可以了。

再看这个索引的结构

  • 发现单词的位置开始和结束之间都是当前切词的长度,(go中中文是3个字节需要注意),那直接保存开始坐标不就可以了,结束坐标可以根据当前字符串算出来,哈哈试了下有效果!

用go构建个简单的搜索(三)对上篇索引文件优化

  • 后面又做了点小的优化就是开始第一个坐标保存,后面的开始坐标保存的是第一个的差值,这个差值分布均匀后可能效果明显
func (doc *docDes) getPosStr() string {
	if !doc.IsEmpty() {
		//return fmt.Sprintf("%s|%d|%d|%s\n", doc.Term, doc.Id, doc.Count, doc.Position)
		posArray := strings.Split(doc.Position, "|")
		star := strings.Split(posArray[len(posArray)-1], " ")[0]
		starNum, _ := strconv.Atoi(star)
		postion := star + "|"//只保存开始坐标
		for i := len(posArray) - 2; i >= 0; i-- {
		  currnt, _ := strconv.Atoi(strings.Split(posArray[i], " ")[0])
		  postion += fmt.Sprintf("%d", (currnt-starNum)) + "|" //计算差值保存
		}
		return fmt.Sprintf("%s|%d|%d|%s\n", doc.Term, doc.Id, doc.Count, postion)
	} else {
		return ""
	}
}

转载自:https://juejin.cn/post/7241492331953356861
评论
请登录