Golang与Elasticsearch搭配检索运用

一、简介下:

Elasticsearch 是一个高性能、分布式、全文搜索与分析引擎,它的核心优势在于 对结构化和非结构化数据进行高效搜索、统计与分析,远远超出传统关系数据库(如 MySQL)的全文检索能力。

让你能在海量数据中,毫秒级地进行智能搜索和实时分析。

核心模块:全文检索、结构化查询、聚合分析、实时写入/搜索、分布式扩展、高可用性、可视化分析。

常见应用场景 :博客/文档搜索、电商搜索推荐、日志分析、指标分析、审计等

二、运用(举例博客系统中)

text 复制代码
      用户写博客
          ↓
     ➤ https://zhida.zhihu.com/search?content_id=257857562&content_type=Article&match_order=1&q=API+Server&zhida_source=entity (https://zhida.zhihu.com/search?content_id=257857562&content_type=Article&match_order=1&q=Golang&zhida_source=entity)
          ↓
    数据写入 MySQL 数据库
          ↓
    同步写入 Elasticsearch

1)Blog 模型(models/blog.go)

复制代码
type Blog struct {
    ID        int64     `gorm:"primaryKey" json:"id"`
    Title     string    `json:"title"`
    Content   string    `json:"content"`
    Tags      string    `json:"tags"` // JSON string
    Author    string    `json:"author"`
    CreatedAt time.Time `json:"created_at"`
    UpdatedAt time.Time `json:"updated_at"`
}

2)写入博客(MySQL + Elasticsearch 同步)

⚡️services/blog_service.go

复制代码
func CreateBlog(blog *models.Blog) error {
if err := db.Create(blog).Error; err != nil {
return err
    }
return elastic.IndexBlog(blog) // 同步到 ES
}
func UpdateBlog(blog *models.Blog) error {
if err := db.Save(blog).Error; err != nil {
return err
    }
return elastic.IndexBlog(blog) // 重新索引
}
func DeleteBlog(blogID int64) error {
if err := db.Delete(&models.Blog{}, blogID).Error; err != nil {
return err
    }
return elastic.DeleteBlog(blogID)
}

⚡️elastic/client.go

复制代码
var es *elasticsearch.Client

func InitES() {
    cfg := elasticsearch.Config{Addresses: []string{"http://localhost:9200"}}
       //搭配pwd使用 :
       //cfg := elasticsearch.Config{Addresses: []string{eshost}, Username: esname,Password: espwd}
    client, err := elasticsearch.NewClient(cfg)
if err != nil {
        log.Fatalf("ES init error: %v", err)
    }
    es = client
}

func IndexBlog(blog *models.Blog) error {
    body, _ := json.Marshal(blog)
    req := esapi.IndexRequest{
        Index:      "blogs",
        DocumentID: strconv.FormatInt(int64(blog.ID), 10),
        Body:       bytes.NewReader(body),
        Refresh:    "true",
    }
    res, err := req.Do(context.Background(), esct)
    if err != nil {
        return err
    }
    defer res.Body.Close()
    return nil
}
func DeleteBlog(blogID int64) error {
    req := esapi.DeleteRequest{
        Index:      "blogs",
        DocumentID: fmt.Sprintf("%d", blogID),
        Refresh:    "true",
    }
    res, err := req.Do(context.Background(), esct)
    if err != nil {
        return err
    }
    defer res.Body.Close()
    return nil
}

引入官方库

复制代码
go get github.com/elastic/go-elasticsearch/v8

3)数据流转方式

text 复制代码
            用户访问 Web/前端
                  │
        ┌─────────▼──────────┐
        │      Golang 后端服务 │
        └─────────┬──────────┘
                  │
       ┌──────────┼────────────┐
       │                       │
       ▼                       ▼
MySQL 关系型数据库      Elasticsearch 搜索引擎
 ️ 存储结构化数据              存储可检索文档数据
- title                    - title(分词)
- content                  - content(分词 + 高亮)
- created_by               - 拼音/模糊匹配
- tag_id 等业务字段         - 自定义字段聚合、排序

4)搜索实现

复制代码
type BlogHit struct {
    ID     string                 `json:"id"`
    Source map[string]interface{} `json:"source"`
}
// 搜索博客(支持标题和内容)
func SearchBlogs(keyword string) ([]BlogHit, error) {
    query := fmt.Sprintf(`
    {
      "query": {
        "multi_match": {
          "query": "%s",
          "fields": ["title", "content"]
        }
      },
      "highlight": {
        "fields": {
          "title": {},
          "content": {}
        }
      }
    }`, keyword)
    res, err := es.Search(
        esct.Search.WithContext(context.Background()),
        esct.Search.WithIndex("blogs"),
        esct.Search.WithBody(strings.NewReader(query)),
        esct.Search.WithTrackTotalHits(true),
        esct.Search.WithPretty(),
    )
    if err != nil {
        return nil, err
    }
    defer res.Body.Close()
    if res.IsError() {
        return nil, fmt.Errorf("error response from ES: %s", res.String())
    }
    var r struct {
        Hits struct {
            Hits []struct {
                ID     string                 `json:"_id"`
                Source map[string]interface{} `json:"_source"`
            } `json:"hits"`
        } `json:"hits"`
    }
    if err := json.NewDecoder(res.Body).Decode(&r); err != nil {
        return nil, err
    }
    var results []BlogHit
    for _, hit := range r.Hits.Hits {
        results = append(results, BlogHit{
            ID:     hit.ID,
            Source: hit.Source,
        })
    }
    return results, nil
}

IKSSr">可视化执行逻辑图如下

复制代码
[ 用户输入关键词 "golang" ]
          ↓
     [ Vue 前端 ]
          ↓
   /search/blog?q=golang
          ↓
[ Golang 后端调用 ES 查询 + 高亮]
          ↓
[ Elasticsearch 返回文档列表 ]
          ↓
[ Vue 展示博客标题 + 摘要 + 图片 ]

前端调取方式如下

复制代码
//vue调用golang api
axios({
         method: "get",
         url: "http://127.0.0.1:2023/GetSearchBlogs?title="+event,
        })
        .then((res) => {
          if(res.data.data.lists==null){
            //ElMessage.error("没有相关记录")
            searchcount.value=0
            blogData.values=[]
            return
          }else{
             searchcount.value=res.data.lists.length
             blogData.values=res.data.lists
          } 
    })

三、效果演示

四、更多可扩展性

  • 搜索智能:模糊匹配、同义词、拼写纠错、词根分析
  • 实时统计:统计聚合性能强(如 PV、UV、热词排行)
  • 多语言支持:内置中文、英文、日文等分词器(可使用 IK、jieba 等)
  • 高并发场景:使用 Kafka 或rabbitmq做异步同步
相关推荐
小二·2 小时前
Go 语言系统编程与云原生开发实战(第4篇):数据持久化深度实战 —— PostgreSQL、GORM 与 Repository 模式
postgresql·云原生·golang
女王大人万岁3 小时前
Go标准库 path 详解
服务器·开发语言·后端·golang
LuminescenceJ4 小时前
RPC通信中的Context上下文如何跨进程传递消息,gRPC为例分析
开发语言·网络·后端·网络协议·rpc·golang
码界奇点4 小时前
基于Beego v2与Go语言的网站管理后台系统设计与实现
开发语言·golang·毕业设计·go语言·源代码管理·beego
蒸蒸yyyyzwd4 小时前
go语言学习
开发语言·学习·golang
源代码•宸4 小时前
分布式理论基础——Raft算法
经验分享·分布式·后端·算法·golang·集群·raft
沈雅馨1 天前
SQL语言的云计算
开发语言·后端·golang
chillxiaohan1 天前
GO学习记录——动态创建测试http接口
学习·http·golang
小二·1 天前
Go 语言系统编程与云原生开发实战(第2篇):并发编程深度实战 —— Goroutine、Channel 与 Context 构建高并发 API 网关
开发语言·云原生·golang
闲谈共视1 天前
Go语言与区块链技术的渊源
开发语言·golang·区块链