likes
comments
collection
share

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

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

demo计划

  • 后续持续补充
工具说明
切词器gse
倒排索引字典树
测试网上下txt的小说

简单的demo初版问题

  • go学习写个简单的字典树 之前写的字典树需要优化,就是节点需要额外存储一些数据(索引
  • 索引如何构建类型 定义了一个简单的结构体,统计现在只有个词频
  • 索引保存磁盘、加载 没处理,暂且不知道怎么处理
  • 后续可以通过切词器提取提取词的位置 没处理

大概流程

读取文件
切词器去掉停词标点符号
载入字典树
关键字查找索引信息

字典树处理的遇到的问题

搞了很久,做测试的时候:家珍和家人一样的结果,我用rune取得长度直接取字符了,导致只判断了前两个字节,go字符串中unicode中文三个字节,所以前面两个字节相同的。

  go中中文的字符串根据下标的遍历的时候需要特殊处理下,如果是其他语言过来的需要注意下
  
 for _, str := range str1 {
		fmt.Printf("%c", str)
	}

	for index := 0; index < len([]rune(str2)); index++ {
		//fmt.Println(str2[index])
		fmt.Println([]rune(str2)[index])
	}

效果图

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

切词器和文本搜索有点出入但是差别不大

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

字典树结构定义

// 文档描述
type docDes struct {
	Id    uint32 //编号
	Type  uint8  //类型
	Path  string //路径
	Term  string //单词
	Count uint32 //词频 Term Frequency
	Desc  string //描述
	//位置
}

type dictTree struct {
	str    rune        //当前的字符
	isDict bool        //是否表示一个单词
	doc    []*docDes   //文档
	child  []*dictTree //子节点
}

文件加载,没分段直接加载到内存了


func fileLoad(strPath string) (string, error) {
	file, err := os.Open(strPath)
	if err != nil {
		fmt.Println("文件打开失败", err)
	}
	//及时关闭file句柄
	defer file.Close()

	fileinfo, err := file.Stat()
	if err != nil {
		fmt.Println(err)
		return "", err
	}

	filesize := fileinfo.Size()
	buffer := make([]byte, filesize)

	bytesread, err := file.Read(buffer)
	if err != nil {
		fmt.Println(err)
		return "", err
	}
	//转换 https://juejin.cn/post/7009826389851373605
	return byteSliceToString(buffer[:bytesread]), nil
}

切词

var seg gse.Segmenter

func init() {
	seg.LoadDict()
}

/**
 * 去除标点符号和停词
 */
func getSplicWord(str string) []string {
	return seg.Stop(seg.Trim(seg.Cut(str, true)))
}
转载自:https://juejin.cn/post/7240351482255671357
评论
请登录