欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang使用redis實(shí)現(xiàn)全文搜索功能詳解

 更新時(shí)間:2025年02月21日 10:09:38   作者:千年死緩  
這篇文章主要為大家詳細(xì)介紹了golang如何使用redis實(shí)現(xiàn)全文搜索功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

簡(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)包,所以沒有使用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)行分詞

https://github.com/go-ego/gse

第三方庫(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
}

把分過的詞保存到到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)
}

查詢操作

通過將文本分詞過后的查詢?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)文章

  • node-exporter被檢測(cè)出來pprof調(diào)試信息泄露漏洞問題

    node-exporter被檢測(cè)出來pprof調(diào)試信息泄露漏洞問題

    這篇文章主要介紹了node-exporter被檢測(cè)出來pprof調(diào)試信息泄露漏洞問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • Go中strings的常用方法詳解

    Go中strings的常用方法詳解

    這篇文章主要介紹了Go中strings的常用方法詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • 解密Golang中Request對(duì)象的操作

    解密Golang中Request對(duì)象的操作

    這篇文章主要和大家深入探討?Golang?中的?Request?對(duì)象,并從多個(gè)方面介紹其功能、結(jié)構(gòu)和使用方法,文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2023-05-05
  • Go語(yǔ)言中循環(huán)Loop的用法介紹

    Go語(yǔ)言中循環(huán)Loop的用法介紹

    這篇文章介紹了Go語(yǔ)言中循環(huán)Loop的用法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • goquery 入門(安裝使用教程)

    goquery 入門(安裝使用教程)

    這篇文章主要為大家介紹了goquery 入門(安裝使用)教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • Golang觀察者模式優(yōu)化訂單處理系統(tǒng)實(shí)例探究

    Golang觀察者模式優(yōu)化訂單處理系統(tǒng)實(shí)例探究

    當(dāng)涉及到訂單處理系統(tǒng)時(shí),觀察者設(shè)計(jì)模式可以用于實(shí)現(xiàn)訂單狀態(tài)的變化和通知,在這篇文章中,我們將介紹如何使用Golang來實(shí)現(xiàn)觀察者設(shè)計(jì)模式,并提供一個(gè)基于訂單處理系統(tǒng)的代碼示例
    2024-01-01
  • 一文詳解Go語(yǔ)言中Mutex互斥鎖

    一文詳解Go語(yǔ)言中Mutex互斥鎖

    Golang中的Mutex互斥鎖是一種常用的并發(fā)控制機(jī)制,用于保護(hù)共享資源的訪問,在本文中,我們將深入探討Mutex互斥鎖的原理、日常使用、鎖結(jié)構(gòu)以及運(yùn)行機(jī)制,需要的朋友可以參考下
    2023-12-12
  • Go各時(shí)間字符串使用解析

    Go各時(shí)間字符串使用解析

    這篇文章主要介紹了Go各時(shí)間字符串使用解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Gin框架中的GET和POST表單處理的實(shí)現(xiàn)

    Gin框架中的GET和POST表單處理的實(shí)現(xiàn)

    Gin框架提供了簡(jiǎn)單而強(qiáng)大的機(jī)制來處理GET和POST表單提交的數(shù)據(jù),通過c.Query、c.PostForm、c.Bind和c.Request.FormFile等方法,可以輕松地獲取和處理各種表單數(shù)據(jù),感興趣的可以了解一下
    2025-03-03
  • Go語(yǔ)言hello world實(shí)例

    Go語(yǔ)言hello world實(shí)例

    這篇文章主要介紹了Go語(yǔ)言hello world實(shí)例,本文先是給出了hello world的代碼實(shí)例,然后對(duì)一些知識(shí)點(diǎn)和技巧做了解釋,需要的朋友可以參考下
    2014-10-10

最新評(píng)論