golang使用redis实现全文搜索功能详解

 更新时间:2025年02月21日 10:09:38   作者:千年死缓  
这篇文章主要为大家详细介绍了golang如何使用redis实现全文搜索功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

简介

使用redis实现全部文章精确到段落的搜索

实现思路

文章分段,使用一张表单独记录下段落信息

段落分词,把段落划分成词

分词后使用有序集合记录到redis中,每个词语后记录含有该分词的段落ID集

使用一个哈希键记录下每个段落的分词,用于分词信息的删除

查询时先分词,再根据分的词把分词查到的对应的段落

返回结果

具体实现

文章分段

文章段落表结构

type TextModel struct {
    gorm.Model
    ArticleID uint   `json:"articleID"`
    Head      string `json:"head"`
    Body      string `json:"body"`
}

分段函数

//这里因为我的项目里出现了循环导包,所以没有使用gorm的映射表进行处理
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, "#") {
			// 标题行
			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
}

段落分词

使用第三方库进行分词

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

第三方库下载

go get -u github.com/go-ego/gse

库初始化

func InitGse() {
    newGse, _ := gse.New()
    global_gse.Gse = newGse
}

分词函数

func textParticiple(textList ...string) (words []string) {
    for _, text := range textList {
        word := global_gse.Gse.CutSearch(text, true)
        words = append(words, word...)
    }
    return
}

把分过的词保存到到redis中

使用redis集合每个词对应的段落ID

func SetTextSearchIndex(textID uint, words []string) {
    for _, word := range words {
        if word == "" {
            continue
        }
        global.Redis.SAdd(fmt.Sprintf("text_%s", word), textID)
    }
}

使用哈希键记录每个文章对应的段落和词语信息,用于信息删除

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)
}

查询操作

通过将文本分词过后的查询词语获取一个段落集合

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
}

根据查到id列表查询数据库

idList := redis_article.GetTextSearchIndex(cr.Key)
query := global.DB.Where("id in ?", idList)

后续处理,使搜索的文字有高亮提示

可以将搜索的文字套在特定的标签中然后再返回信息

以上就是golang使用redis实现全文搜索功能详解的详细内容,更多关于go redis全文搜索的资料请关注脚本之家其它相关文章!

相关文章

  • node-exporter被检测出来pprof调试信息泄露漏洞问题

    node-exporter被检测出来pprof调试信息泄露漏洞问题

    这篇文章主要介绍了node-exporter被检测出来pprof调试信息泄露漏洞问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-04-04
  • Go中strings的常用方法详解

    Go中strings的常用方法详解

    这篇文章主要介绍了Go中strings的常用方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • 解密Golang中Request对象的操作

    解密Golang中Request对象的操作

    这篇文章主要和大家深入探讨 Golang 中的 Request 对象,并从多个方面介绍其功能、结构和使用方法,文中的示例代码讲解详细,感兴趣的可以了解一下
    2023-05-05
  • Go语言中循环Loop的用法介绍

    Go语言中循环Loop的用法介绍

    这篇文章介绍了Go语言中循环Loop的用法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • goquery 入门(安装使用教程)

    goquery 入门(安装使用教程)

    这篇文章主要为大家介绍了goquery 入门(安装使用)教程示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • Golang观察者模式优化订单处理系统实例探究

    Golang观察者模式优化订单处理系统实例探究

    当涉及到订单处理系统时,观察者设计模式可以用于实现订单状态的变化和通知,在这篇文章中,我们将介绍如何使用Golang来实现观察者设计模式,并提供一个基于订单处理系统的代码示例
    2024-01-01
  • 一文详解Go语言中Mutex互斥锁

    一文详解Go语言中Mutex互斥锁

    Golang中的Mutex互斥锁是一种常用的并发控制机制,用于保护共享资源的访问,在本文中,我们将深入探讨Mutex互斥锁的原理、日常使用、锁结构以及运行机制,需要的朋友可以参考下
    2023-12-12
  • Go各时间字符串使用解析

    Go各时间字符串使用解析

    这篇文章主要介绍了Go各时间字符串使用解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • Gin框架中的GET和POST表单处理的实现

    Gin框架中的GET和POST表单处理的实现

    Gin框架提供了简单而强大的机制来处理GET和POST表单提交的数据,通过c.Query、c.PostForm、c.Bind和c.Request.FormFile等方法,可以轻松地获取和处理各种表单数据,感兴趣的可以了解一下
    2025-03-03
  • Go语言hello world实例

    Go语言hello world实例

    这篇文章主要介绍了Go语言hello world实例,本文先是给出了hello world的代码实例,然后对一些知识点和技巧做了解释,需要的朋友可以参考下
    2014-10-10

最新评论