1、GO学习之Hello World
2、GO学习之入门语法
3、GO学习之切片操作
4、GO学习之 Map 操作
5、GO学习之 结构体 操作
6、GO学习之 通道(Channel)
7、GO学习之 多线程(goroutine)
8、GO学习之 函数(Function)
9、GO学习之 接口(Interface)
10、GO学习之 网络通信(Net/Http)
11、GO学习之 微框架(Gin)
12、GO学习之 数据库(mysql)
13、GO学习之 数据库(Redis)
14、GO学习之 搜索引擎(ElasticSearch)
按照公司目前的任务,go 学习是必经之路了,虽然行业卷,不过技多不压身,依旧努力!!!
一个网站或者一个平台好不了模糊检索,传统的SQL检索无法满足,而且效率也地下,所以目前大多数项目中搜索都用的是搜索引擎(ElasticSearch较多,简称 ES
),那什么是 ES呢?请移步 ElasticSearch学习随笔之基础介绍 等系列文章,项目中客户端使用也是 JAVA
的实现的。
此篇就来聊聊如何用 Go
对 ES
进行检索等各种常用操作。
ElasticSearch
是一个开源的分布式搜索和分析引擎,基于 Apache Lucene
开发的。被广泛用于实时检索、数据分析和数据可视化等领域,具有高性能、可扩展和强大的全文检索
能力。
在进行 ES 操作之前,我们首先要将操作ES的包拉取:
go get github.com/olivere/elastic/v7
下面的示例中,我们创建了一个 ES 链接,用来操作ES,在 common 包中,并且 函数名(
GetESClient()
)是大写的,表示外部包可访问。
package common
import (
"fmt"
"log"
"github.com/olivere/elastic/v7"
)
func GetESClient() *elastic.Client {
// 建立 ElasticSearch 连接
client, err := elastic.NewClient(elastic.SetURL("http://192.168.1.8:9200"))
if err != nil {
log.Fatal(err)
}
fmt.Println("ES链接创建成功!")
return client
}
下面示例是利用
Bulk
批量新增操作,获取到 ES 的链接后,通过esClient.Bulk()
创建批量操作 Bulk,然后再通过Add(doc)
把文档添加到批量操作里面,最后Do()
执行操作。
package main
import (
"context"
"fmt"
"log"
"github.com/olivere/elastic/v7"
"gotest.com/test/src/common"
)
// 创建结构体
type Content struct {
Product string `json:"product"`
Color string `json:"color"`
Release_date string `json:"release_date"`
Price float32 `json:"price"`
Product_agency []string `json:"product_agency"`
Types string `json:"types"`
Title string `json:"title"`
Brand string `json:"brand"`
Desc string `json:"desc"`
}
func main() {
// 建立 ElasticSearch 连接
esClient := common.GetESClient()
// 创建文档
contents := []Content{
{
Product: "Xbox Series 10", Color: "black", Release_date: "2023-08-27", Price: 500.25, Product_agency: []string{"玩游戏", "看电影"}, Types: "gaming console",
Title: "微软 Xbox Y", Brand: "Microsoft", Desc: "这是一款拥有强大性能和兼容性的游戏机, 能看电影,红色的",
},
{
Product: "Xbox Series 10", Color: "green", Release_date: "2023-08-27", Price: 500.25, Product_agency: []string{"玩游戏", "看电影"}, Types: "gaming console",
Title: "微软 Xbox Y", Brand: "Microsoft", Desc: "这是一款拥有强大性能和兼容性的游戏机, 能看电影,绿色的",
},
}
// 批量操作
bulkRequest := esClient.Bulk()
// 批量添加文档
for _, content := range contents {
doc := elastic.NewBulkCreateRequest().Index("electronics").UseEasyJSON(true).Doc(&content)
bulkRequest.Add(doc)
}
// 执行批量添加操作
result, err := bulkRequest.Do(context.Background())
if err != nil {
log.Fatal(err)
}
fmt.Printf("成功添加 %v 个文档", len(result.Succeeded()))
}
此示例通过 ID 删除文档。
package main
import (
"context"
"fmt"
"log"
"gotest.com/test/src/common"
)
func main() {
// 建立 ElasticSearch 连接
esClient := common.GetESClient()
_, err := esClient.Delete().Index("electronics").Id("n72VNooB2xU2Yn1oN-Bc").Do(context.Background())
if err != nil {
log.Fatal(err)
}
fmt.Println("删除成功!")
}
此案例按照 ID 修改。
package main
import (
"context"
"fmt"
"log"
"gotest.com/test/src/common"
)
func main() {
// 建立 ElasticSearch 连接
esClient := common.GetESClient()
_, err := esClient.Update().Index("electronics").Id("nr2VNooB2xU2Yn1oN-Bc").Doc(map[string]interface{}{"title": "微软 Xbox Z"}).Do(context.Background())
if err != nil {
log.Fatal(err)
}
fmt.Println("文档已更新!")
}
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"github.com/olivere/elastic/v7"
"gotest.com/test/src/common"
)
func main() {
// 建立 ElasticSearch 连接
esClient := common.GetESClient()
// match all 数据匹配
query := elastic.NewMatchAllQuery()
// 检索 从 0 到 10 条数据
result, err := esClient.Search().Index("electronics").Query(query).From(0).Size(10).Do(context.Background())
if err != nil {
log.Fatal(err)
}
// 定一个 结构体,结构化数据
type product struct {
Product string
Color string
Title string
}
// 处理数据结果
fmt.Printf("总条数:%+v\n", result.Hits.TotalHits.Value)
for index, hit := range result.Hits.Hits {
p := &product{}
// hit.Source 获取到的数据,经过 json 反序列化转换成 product 结构体
pErr := json.Unmarshal(hit.Source, p)
if pErr != nil {
log.Fatal(pErr)
}
fmt.Println(index, p)
}
}
运行结果:
PS D:\workspaceGo\src\elasticSearch> go run .\query.go
ES链接创建成功!
总条数:22
0 &{Galaxy S21 white 三星 Galaxy S21}
1 &{Galaxy S21 white 三星 Galaxy S21}
2 &{Canon EOS 5D Mark IV black 佳能 EOS 5D Mark IV}
3 &{Sony A7 III black 索尼 A7 III}
4 &{GoPro HERO10 Black black GoPro HERO10 Black}
5 &{Apple Watch Series 7 space gray 苹果 Watch Series 7}
6 &{Samsung Galaxy Watch 4 black 三星 Galaxy Watch 4}
7 &{Nintendo Switch OLED red/blue 任天堂 Switch OLED}
8 &{PlayStation 5 white 索尼 PlayStation 5}
9 &{Xbox Series X black 微软 Xbox Series X}
query := elastic.NewMatchQuery("brand", "Apple")
query := elastic.NewMatchBoolPrefixQuery("title", "三")
query := elastic.NewMatchPhrasePrefixQuery("desc", "时尚与智能")
query := elastic.NewMatchPhraseQuery("desc", "时尚与智能")
query := elastic.NewMultiMatchQuery("苹果", "title", "brand", "product")
query := elastic.NewTermQuery("type", "mobile")
query := elastic.NewTermsQuery("color", "white", "black")
// Fuzziness 检索模糊距离
query := elastic.NewFuzzyQuery("desc", "手机").Fuzziness(5)
query := elastic.NewBoolQuery().Should(elastic.NewMatchQuery("title", "手机"), elastic.NewTermQuery("type", "mobile"))
query := elastic.NewDisMaxQuery().Query(elastic.NewMatchQuery("title", "苹果"), elastic.NewMatchQuery("desc", "苹果"))
package main
import (
"context"
"fmt"
"log"
"github.com/olivere/elastic/v7"
"gotest.com/test/src/common"
)
func main() {
// 建立 ElasticSearch 连接
esClient := common.GetESClient()
// 构建统计
agg := elastic.NewTermsAggregation().Field("color.keyword")
// 执行搜索和聚合操作
result, err := esClient.Search().Index("electronics").Aggregation("by_color", agg).Do(context.Background())
if err != nil {
log.Fatal(err)
}
// 处理聚合结果
aggResult, found := result.Aggregations.Terms("by_color")
if found {
for _, bucket := range aggResult.Buckets {
fmt.Printf("color: %v, count: %v \n", bucket.Key, bucket.DocCount)
}
}
}
运行结果:
PS D:\workspaceGo\src\elasticSearch> go run .\aggregation.go
ES链接创建成功!
color: black, count: 9
color: white, count: 6
color: silver, count: 3
color: red/blue, count: 1
color: space gray, count: 1
color: stainless steel, count: 1
github.com/olivere/elastic/v7
github.com/elastic/go-elasticsearch/v7
优点:
缺点:
总的来说,使用 Go 语言操作 ElasticSearch 具有高性能、并发性和易维护性等优势,适用于需要快速、高效处理大量数据的场景。不过,也需要根据项目需求和团队技术栈的考量来决定是否选择 Go 语言来操作 ElasticSearch。
现阶段还是对 Go 语言的学习阶段,想必有一些地方考虑的不全面,本文示例全部是亲自手敲代码并且执行通过。
如有问题,还请指教。
评论去告诉我哦!!!一起学习一起进步!!!