golang使用redis實(shí)現(xiàn)全文搜索功能詳解
簡(jiǎn)介
使用redis實(shí)現(xiàn)全部文章精確到段落的搜索
實(shí)現(xiàn)思路
文章分段,使用一張表單獨(dú)記錄下段落信息
段落分詞,把段落劃分成詞
分詞后使用有序集合記錄到redis中,每個(gè)詞語(yǔ)后記錄含有該分詞的段落ID集
使用一個(gè)哈希鍵記錄下每個(gè)段落的分詞,用于分詞信息的刪除
查詢時(shí)先分詞,再根據(jù)分的詞把分詞查到的對(duì)應(yīng)的段落
返回結(jié)果
具體實(shí)現(xiàn)
文章分段
文章段落表結(jié)構(gòu)
type TextModel struct {
gorm.Model
ArticleID uint `json:"articleID"`
Head string `json:"head"`
Body string `json:"body"`
}
分段函數(shù)
//這里因?yàn)槲业捻?xiàng)目里出現(xiàn)了循環(huán)導(dǎo)包,所以沒(méi)有使用gorm的映射表進(jìn)行處理
type TextModel struct {
ArticleID uint `json:"article_id"`
Head string `json:"head"`
Body string `json:"body"`
}
func MdContentTransformation(id uint, title string, content string) (list []TextModel) {
lines := strings.Split(content, "\n")
var headList []string
var bodyList []string
var body string
headList = append(headList, title)
var flag bool
for _, line := range lines {
if strings.HasPrefix(line, "```") {
flag = !flag
}
if !flag && strings.HasPrefix(line, "#") {
// 標(biāo)題行
headList = append(headList, getHead(line))
if strings.TrimSpace(body) != "" {
bodyList = append(bodyList, getBody(body))
}
body = ""
continue
}
body += line
}
if body != "" {
bodyList = append(bodyList, getBody(body))
}
if len(headList) > len(bodyList) {
bodyList = append(bodyList, "")
}
if len(headList) != len(bodyList) {
log.Errorf("headList與bodyList 不一致 \n headList:%q %d\\\n bodyList: %q %d\n", headList, len(headList), bodyList, len(bodyList))
return
}
for i := 0; i < len(headList); i++ {
list = append(list, TextModel{
ArticleID: id,
Head: headList[i],
Body: bodyList[i],
})
}
return
}
func getHead(head string) string {
s := strings.TrimSpace(strings.Join(strings.Split(head, " ")[1:], " "))
return s
}
func getBody(body string) string {
body = strings.TrimSpace(body)
return body
}
段落分詞
使用第三方庫(kù)進(jìn)行分詞
第三方庫(kù)下載
go get -u github.com/go-ego/gse
庫(kù)初始化
func InitGse() {
newGse, _ := gse.New()
global_gse.Gse = newGse
}
分詞函數(shù)
func textParticiple(textList ...string) (words []string) {
for _, text := range textList {
word := global_gse.Gse.CutSearch(text, true)
words = append(words, word...)
}
return
}
把分過(guò)的詞保存到到redis中
使用redis集合每個(gè)詞對(duì)應(yīng)的段落ID
func SetTextSearchIndex(textID uint, words []string) {
for _, word := range words {
if word == "" {
continue
}
global.Redis.SAdd(fmt.Sprintf("text_%s", word), textID)
}
}
使用哈希鍵記錄每個(gè)文章對(duì)應(yīng)的段落和詞語(yǔ)信息,用于信息刪除
func SetTextSearchWords(articleID uint, textID uint, words []string) {
_words, _ := json.Marshal(words)
global.Redis.HSet(fmt.Sprintf("text_search_words_%d", articleID), strconv.Itoa(int(textID)), _words)
}
查詢操作
通過(guò)將文本分詞過(guò)后的查詢?cè)~語(yǔ)獲取一個(gè)段落集合
func GetTextSearchIndex(text string) []string {
//分詞
words := global_gse.Gse.CutSearch(text, true)
var _words []string
for _, word := range words {
_words = append(_words, fmt.Sprintf("text_%s", word))
}
vals, _ := global.Redis.SUnion(_words...).Result()
return vals
}
根據(jù)查到id列表查詢數(shù)據(jù)庫(kù)
idList := redis_article.GetTextSearchIndex(cr.Key)
query := global.DB.Where("id in ?", idList)
后續(xù)處理,使搜索的文字有高亮提示
可以將搜索的文字套在特定的標(biāo)簽中然后再返回信息
以上就是golang使用redis實(shí)現(xiàn)全文搜索功能詳解的詳細(xì)內(nèi)容,更多關(guān)于go redis全文搜索的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Golang特殊init函數(shù)的實(shí)現(xiàn)實(shí)例
本文介紹了Go語(yǔ)言中特殊函數(shù)init()的作用,如變量初始化、包初始化順序以及與main函數(shù)的關(guān)系,具有一定的參考價(jià)值,感興趣的可以了解一下2025-11-11
Go map底層實(shí)現(xiàn)與擴(kuò)容規(guī)則和特性分類詳細(xì)講解
這篇文章主要介紹了Go map底層實(shí)現(xiàn)與擴(kuò)容規(guī)則和特性,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2023-03-03
深入解析如何基于go-retry構(gòu)建靈活安全和高效的重試邏輯
本文將深入解析 sethvargo/go-retry 這個(gè)輕量且強(qiáng)大的 Go 重試庫(kù),帶大家從原理到實(shí)踐,構(gòu)建靈活、安全、高效的重試邏輯,感興趣的小伙伴可以了解下2025-11-11
go并發(fā)數(shù)據(jù)一致性事務(wù)的保障面試應(yīng)答
這篇文章主要為大家介紹了go并發(fā)數(shù)據(jù)一致性事務(wù)的保障面試應(yīng)答,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12
Go多文件調(diào)用與main函數(shù)踩坑及解決
本文介紹了在學(xué)習(xí)Go語(yǔ)言時(shí)常見(jiàn)的幾個(gè)錯(cuò)誤及其解決方法,包括多文件、main函數(shù)、包作用域以及gorun的使用方式,通過(guò)詳細(xì)的分析和示例,幫助讀者更好地理解和解決這些問(wèn)題2026-02-02
基于Go語(yǔ)言開(kāi)發(fā)一個(gè)JSON格式校驗(yàn)工具
在日常開(kāi)發(fā)中,經(jīng)常會(huì)遇到需要校驗(yàn) JSON 格式是否正確的場(chǎng)景,如果 JSON 格式不正確,系統(tǒng)往往會(huì)報(bào)錯(cuò)甚至崩潰,因此開(kāi)發(fā)一個(gè) 命令行 JSON 格式校驗(yàn)工具 非常實(shí)用,所以本文給大家介紹了如何基于Go語(yǔ)言開(kāi)發(fā)一個(gè)JSON格式校驗(yàn)工具,需要的朋友可以參考下2025-09-09

