找回密码
 立即注册
首页 业界区 业界 Golang与Elasticsearch搭配检索运用

Golang与Elasticsearch搭配检索运用

筒霓暄 3 天前
一、简介下:

1.jpeg
Elasticsearch 是一个高性能、分布式、全文搜索与分析引擎,它的核心优势在于 对结构化和非结构化数据进行高效搜索、统计与分析,远远超出传统关系数据库(如 MySQL)的全文检索能力。
让你能在海量数据中,毫秒级地进行智能搜索和实时分析。
核心模块:全文检索、结构化查询、聚合分析、实时写入/搜索、分布式扩展、高可用性、可视化分析。
常见应用场景 :博客/文档搜索、电商搜索推荐、日志分析、指标分析、审计等
二、运用(举例博客系统中)
  1.       用户写博客
  2.           ↓
  3.      ➤ API Server (Golang)
  4.           ↓
  5.     数据写入 MySQL 数据库
  6.           ↓
  7.     同步写入 Elasticsearch
复制代码
1)Blog 模型(models/blog.go)
  1. type Blog struct {
  2.     ID        int64     `gorm:"primaryKey" json:"id"`
  3.     Title     string    `json:"title"`
  4.     Content   string    `json:"content"`
  5.     Tags      string    `json:"tags"` // JSON string
  6.     Author    string    `json:"author"`
  7.     CreatedAt time.Time `json:"created_at"`
  8.     UpdatedAt time.Time `json:"updated_at"`
  9. }
复制代码
2)写入博客(MySQL + Elasticsearch 同步)

⚡️services/blog_service.go
  1. func CreateBlog(blog *models.Blog) error {
  2. if err := db.Create(blog).Error; err != nil {
  3. return err
  4.     }
  5. return elastic.IndexBlog(blog) // 同步到 ES
  6. }
  7. func UpdateBlog(blog *models.Blog) error {
  8. if err := db.Save(blog).Error; err != nil {
  9. return err
  10.     }
  11. return elastic.IndexBlog(blog) // 重新索引
  12. }
  13. func DeleteBlog(blogID int64) error {
  14. if err := db.Delete(&models.Blog{}, blogID).Error; err != nil {
  15. return err
  16.     }
  17. return elastic.DeleteBlog(blogID)
  18. }
复制代码
⚡️elastic/client.go
  1. var es *elasticsearch.Client
  2. func InitES() {
  3.     cfg := elasticsearch.Config{Addresses: []string{"http://localhost:9200"}}
  4.        //搭配pwd使用 :
  5.        //cfg := elasticsearch.Config{Addresses: []string{eshost}, Username: esname,Password: espwd}
  6.     client, err := elasticsearch.NewClient(cfg)
  7. if err != nil {
  8.         log.Fatalf("ES init error: %v", err)
  9.     }
  10.     es = client
  11. }
  12. func IndexBlog(blog *models.Blog) error {
  13.     body, _ := json.Marshal(blog)
  14.     req := esapi.IndexRequest{
  15.         Index:      "blogs",
  16.         DocumentID: strconv.FormatInt(int64(blog.ID), 10),
  17.         Body:       bytes.NewReader(body),
  18.         Refresh:    "true",
  19.     }
  20.     res, err := req.Do(context.Background(), esct)
  21.     if err != nil {
  22.         return err
  23.     }
  24.     defer res.Body.Close()
  25.     return nil
  26. }
  27. func DeleteBlog(blogID int64) error {
  28.     req := esapi.DeleteRequest{
  29.         Index:      "blogs",
  30.         DocumentID: fmt.Sprintf("%d", blogID),
  31.         Refresh:    "true",
  32.     }
  33.     res, err := req.Do(context.Background(), esct)
  34.     if err != nil {
  35.         return err
  36.     }
  37.     defer res.Body.Close()
  38.     return nil
  39. }
复制代码
引入官方库
  1. go get github.com/elastic/go-elasticsearch/v8
复制代码
3)数据流转方式
  1.             用户访问 Web/前端
  2.                   │
  3.         ┌─────────▼──────────┐
  4.         │      Golang 后端服务 │
  5.         └─────────┬──────────┘
  6.                   │
  7.        ┌──────────┼────────────┐
  8.        │                       │
  9.        ▼                       ▼
  10. MySQL 关系型数据库      Elasticsearch 搜索引擎
  11. ️ 存储结构化数据              存储可检索文档数据
  12. - title                    - title(分词)
  13. - content                  - content(分词 + 高亮)
  14. - created_by               - 拼音/模糊匹配
  15. - tag_id 等业务字段         - 自定义字段聚合、排序
复制代码
4)搜索实现
  1. type BlogHit struct {
  2.     ID     string                 `json:"id"`
  3.     Source map[string]interface{} `json:"source"`
  4. }
  5. // 搜索博客(支持标题和内容)
  6. func SearchBlogs(keyword string) ([]BlogHit, error) {
  7.     query := fmt.Sprintf(`
  8.     {
  9.       "query": {
  10.         "multi_match": {
  11.           "query": "%s",
  12.           "fields": ["title", "content"]
  13.         }
  14.       },
  15.       "highlight": {
  16.         "fields": {
  17.           "title": {},
  18.           "content": {}
  19.         }
  20.       }
  21.     }`, keyword)
  22.     res, err := es.Search(
  23.         esct.Search.WithContext(context.Background()),
  24.         esct.Search.WithIndex("blogs"),
  25.         esct.Search.WithBody(strings.NewReader(query)),
  26.         esct.Search.WithTrackTotalHits(true),
  27.         esct.Search.WithPretty(),
  28.     )
  29.     if err != nil {
  30.         return nil, err
  31.     }
  32.     defer res.Body.Close()
  33.     if res.IsError() {
  34.         return nil, fmt.Errorf("error response from ES: %s", res.String())
  35.     }
  36.     var r struct {
  37.         Hits struct {
  38.             Hits []struct {
  39.                 ID     string                 `json:"_id"`
  40.                 Source map[string]interface{} `json:"_source"`
  41.             } `json:"hits"`
  42.         } `json:"hits"`
  43.     }
  44.     if err := json.NewDecoder(res.Body).Decode(&r); err != nil {
  45.         return nil, err
  46.     }
  47.     var results []BlogHit
  48.     for _, hit := range r.Hits.Hits {
  49.         results = append(results, BlogHit{
  50.             ID:     hit.ID,
  51.             Source: hit.Source,
  52.         })
  53.     }
  54.     return results, nil
  55. }
复制代码
 
IKSSr">可视化执行逻辑图如下
  1. [ 用户输入关键词 "golang" ]
  2.           ↓
  3.      [ Vue 前端 ]
  4.           ↓
  5.    /search/blog?q=golang
  6.           ↓
  7. [ Golang 后端调用 ES 查询 + 高亮]
  8.           ↓
  9. [ Elasticsearch 返回文档列表 ]
  10.           ↓
  11. [ Vue 展示博客标题 + 摘要 + 图片 ]
复制代码
 
前端调取方式如下
  1. //vue调用golang api
  2. axios({
  3.          method: "get",
  4.          url: "http://127.0.0.1:2023/GetSearchBlogs?title="+event,
  5.         })
  6.         .then((res) => {
  7.           if(res.data.data.lists==null){
  8.             //ElMessage.error("没有相关记录")
  9.             searchcount.value=0
  10.             blogData.values=[]
  11.             return
  12.           }else{
  13.              searchcount.value=res.data.lists.length
  14.              blogData.values=res.data.lists
  15.           }
  16.     })
复制代码
三、效果演

 
2.gif
 
四、更多可扩展性


  • 搜索智能:模糊匹配、同义词、拼写纠错、词根分析
  • 实时统计:统计聚合性能强(如 PV、UV、热词排行)
  • 多语言支持:内置中文、英文、日文等分词器(可使用 IK、jieba 等)
  • 高并发场景:使用 Kafka 或rabbitmq做异步同步

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册