2026-02-27 20:54:43
在Golang中实现文章搜索功能需根据项目规模和需求选择合适方案,以下是具体实现方式及核心思路:
一、小规模场景:内存+字符串匹配适用于数据量小(如几百篇文章)、无需持久化的场景,通过内存结构存储文章并直接进行字符串匹配。
定义结构体:存储文章ID、标题、内容等字段。
type Article struct { ID int Title string Content string}加载数据:将文章存入切片或map。
var articles []Articlearticles = append(articles, Article{ID: 1, Title: "Go入门", Content: "Go是静态编译型语言..."})模糊匹配:使用strings.Contains或正则表达式遍历数据。
func searchByKeyword(keyword string) []Article { var results []Article lowerKeyword := strings.ToLower(keyword) for _, a := range articles { if strings.Contains(strings.ToLower(a.Title), lowerKeyword) || strings.Contains(strings.ToLower(a.Content), lowerKeyword) { results = append(results, a) } } return results}当文章数量增至数千或数万篇时,推荐使用数据库的全文检索功能,如MySQL的FULLTEXT或PostgreSQL的tsvector。
创建全文索引:在标题和内容字段上建立索引。
-- MySQL示例CREATE TABLE articles ( id INT PRIMARY KEY, title VARCHAR(255), content TEXT, FULLTEXT(title, content));执行查询:使用SQL的MATCH AGAINST(MySQL)或to_tsquery(PostgreSQL)。
// MySQL查询示例(使用database/sql)func searchInMySQL(db *sql.DB, keyword string) ([]Article, error) { query := "SELECT id, title, content FROM articles WHERE MATCH(title, content) AGAINST(? IN BOOLEAN MODE)" rows, err := db.Query(query, keyword) // 扫描结果并返回}ORM支持:若使用GORM,可通过原生SQL或插件(如gorm-mysql-fulltext)实现。
对搜索质量要求高(如支持分词、相关性排序、拼音纠错)时,推荐集成Elasticsearch(ES)。
同步数据:使用ES的Go客户端(如olivere/elastic)将文章数据写入索引。
import "github.com/olivere/elastic/v7"func syncToES(client *elastic.Client, article Article) error { _, err := client.Index(). Index("articles"). Id(strconv.Itoa(article.ID)). BodyJson(article). Do(context.Background()) return err}构造查询DSL:使用match或multi_match查询。
func searchInES(client *elastic.Client, keyword string) ([]Article, error) { query := elastic.NewMultiMatchQuery(keyword, "title", "content") result, err := client.Search(). Index("articles"). Query(query). Do(context.Background()) // 解析结果并返回}无论采用哪种方案,均可通过以下方式提升实用性:
通过以上方法,可灵活实现从简易到高级的文章搜索功能,满足不同场景需求。