欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

只需五行代码即可实现全文数据库搜索

最编程 2024-05-27 08:53:10
...

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

search.gif

想要建一个自己的博客或者知识wiki都离不开内容的全文搜索功能,但是就自己那写文章和文档就让我上ES好像又太重了。

下面我要为大家介绍一个轻便的全文搜索框架wukong

先上代码

这个全文搜索框架哦超好用,5行代码就能搞定 中文分词、索引和搜索

1. searcher := engine.Engine{} //初始化
2. searcher.Init(types.EngineInitOptions{SegmenterDictionaries: config.App.BasePath + "dictionary.txt"}) //分词在这里
3. searcher.IndexDocument(uint64(这里是文章的ID), types.DocumentIndexData{Content:"文本文本,把你的内容都放这里吧"}, false) //导入文本和对应的
4. searcher.FlushIndex()  //刷新索引
5. resp := searcher.Search(types.SearchRequest{Text: keywords}) //通过关键字搜索吧

是不是超级简单

wukong简介

wukong,是一款golang实现的高性能、支持中文分词的全文搜索引擎。

第一次知道wukong,其实是在今年做个人网站的时候遇到需要做全文搜索,然后了解到了wukong的作者陈辉。 他是作为第一个演讲嘉宾,在google 2016大会上分享了“Go与人工智能”。在这个presentation中,陈辉详细讲解了wukong搜索引擎以及其他几个关联的开源项目,比如:sego等。

在golang世界中,做full text search的可不止wukong一个。另外一个比较知名的是bleve

但默认情况下,bleve并不支持中文分词和搜索,需要结合中文分词插件才能支持,比如:gojieba。

wukong基本上是陈辉一个人打造的项目,在陈辉在阿里任职期间,他将其用于阿里内部的一些项目中,但总体来说,wukong的应用还是很小众的,相关资料也不多,基本都集中在其github站点上。

关于wukong源码的分析,倒是在国外站点上发现一篇:《Code reading: wukong full-text search engine》。

不过我个人觉得它最大的特点恰恰是不像ElasticSearch那样庞大和功能完备,而是可以以一个Library的形式快速集成到你的应用或服务中去。小而美,简直就是优秀!

完整例子

给一个能跑的例子吧,

package main

import (
    "fmt"

    "github.com/huichen/wukong/engine"
    "github.com/huichen/wukong/types"
)

var (
	docId uint64
	text1 = "中国内地和澳门地区约有5.15亿人在2月10日之前,通过*电视台收看了北京冬奥会。估计有5亿人收看了冬奥会的开幕式。在香港,冬奥会由TVB独家转播,近300万人收看了开幕式"
	text2 = "在欧洲,探索频道转播了这些赛事。比赛开始仅4天,流媒体观众人数就超过了2018年平昌冬奥会观众的总人数。澳大利亚人也对冬奥会表现出了兴趣,官方的第七频道网16日吸引了1170万观众。"
)

func main() {
	searcher := engine.Engine{} //初始化
	searcher.Init(types.EngineInitOptions{
		SegmenterDictionaries: "../../webapp/dist/dictionary.txt", //分词字典,这个可以去作者的git仓库里面找到
	})
	docId++
	searcher.IndexDocument(uint64(docId), types.DocumentIndexData{Content: text1}, false)
	docId++
	searcher.IndexDocument(uint64(docId), types.DocumentIndexData{Content: text2}, false)

	searcher.FlushIndex()
	fmt.Printf("%#v\n", searcher.Search(types.SearchRequest{Text: "欧洲"}))
	fmt.Printf("%#v\n", searcher.Search(types.SearchRequest{Text: "中国"}))

	searcher.Close()
}

执行结果:

2022/02/18 19:03:45 载入sego词典 ../../webapp/dist/dictionary.txt
2022/02/18 19:03:46 sego词典载入完毕
types.SearchResponse{Tokens:[]string{"欧洲"}, Docs:[]types.ScoredDocument{types.ScoredDocument{DocId:0x2, Scores:[]float32{1}, TokenSnippetLocations:[]int(nil), TokenLocations:[][]int(nil)}}, Timeout:false, NumDocs:1}
types.SearchResponse{Tokens:[]string{"中国"}, Docs:[]types.ScoredDocument{types.ScoredDocument{DocId:0x1, Scores:[]float32{1}, TokenSnippetLocations:[]int(nil), TokenLocations:[][]int(nil)}}, Timeout:false, NumDocs:1}

持久化索引和启动恢复

wukong引擎建立的文档索引都是存放在内存中的,程序退出后,这些数据也就随之消失了。 每次都创建索引显然是不合理的,好在wukong支持将已建立的索引持久化到磁盘文件中,并在程序重启时从文件中间索引数据恢复出来, 并在后续的关键词搜索时使用。wukong底层支持两种持久化引擎,一个是boltdb,另外一个是cznic/kv。默认采用boltdb。

// index_create.go
... ...
func main() {
    searcher.Init(types.EngineInitOptions{
        IndexerInitOptions: &types.IndexerInitOptions{
            IndexType: types.DocIdsIndex,
        },
        UsePersistentStorage:    true,
        PersistentStorageFolder: "./index",
        SegmenterDictionaries:   "./dict/dictionary.txt",
        StopTokenFile:           "./dict/stop_tokens.txt",
    })
    defer searcher.Close()

    os.MkdirAll("./index", 0777)

    docId++
    searcher.IndexDocument(docId, types.DocumentIndexData{Content: text1}, false)
    docId++
    searcher.IndexDocument(docId, types.DocumentIndexData{Content: text2}, false)
    docId++
    searcher.IndexDocument(docId, types.DocumentIndexData{Content: text3}, false)

    searcher.FlushIndex()
    log.Println("Created index number:", searcher.NumDocumentsIndexed())
}

分布式索引和搜索

当文档数量较多无法在一台机器内存中索引时,可以将文档按照文本内容的hash值裂分(sharding),不同块交由不同服务器索引。 在查找时同一请求分发到所有裂分服务器上,然后将所有服务器返回的结果归并重排序作为最终搜索结果输出。

为了保证裂分的均匀性,建议使用Go语言实现的Murmur3 hash函数

按照上面的原理很容易用悟空引擎实现分布式搜索(每个裂分服务器运行一个悟空引擎),但这样的分布式系统多数是高度定制的,比如任务的调度依赖于分布式环境,有时需要添加额外层的服务器来实现均衡负载。

小结

wukong是一个轻量级的全文搜索引擎,简单易用,虽然没有ES强大,不过小而美的它很适合使用到我们的个人博客或者是wik搜索中。 文章主要介绍了wukong的使用,并在最后探讨了wukong在大规模搜索方案中的分布式索引方案。虽然wukong很优秀,但是它的缺点也是很明显的 由于wukong引擎基本上是作者一个人的项目,社区参与度不高,资料很少;查询功能简单,仅支持关键词的AND查询;wukong的索引建立和搜索精确度一定程度上 取决于分词引擎的分词精确性。

but 如果你只是要一个简单的搜素功能,wukong绝对超你预期!

推荐阅读