一、简介下:
Elasticsearch 是一个高性能、分布式、全文搜索与分析引擎,它的核心优势在于 对结构化和非结构化数据进行高效搜索、统计与分析,远远超出传统关系数据库(如 MySQL)的全文检索能力。
让你能在海量数据中,毫秒级地进行智能搜索和实时分析。 核心模块:全文检索、结构化查询、聚合分析、实时写入/搜索、分布式扩展、高可用性、可视化分析。
常见应用场景 :博客/文档搜索、电商搜索推荐、日志分析、指标分析、审计等
二、运用(举例博客系统中)
- 用户写博客
- ↓
- ➤ API Server (Golang)
- ↓
- 数据写入 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)数据流转方式
- 用户访问 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做异步同步
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |