创建项目
demogo mod init demo
安装包
go get github.com/elastic/go-elasticsearch/v7
连接到ES
package main
import (
"log"
"github.com/elastic/go-elasticsearch/v7"
)
func main() {
es, err := elasticsearch.NewDefaultClient()// 连接到es服务器
if err != nil {
panic(err)
}
log.Println(elasticsearch.Version)
log.Println(es.Info())
}
运行结果
[Running] go run "e:\golang开发学习\es\main.go"
2022/09/24 13:16:22 7.17.1
2022/09/24 13:16:22 [200 OK] {
"name" : "MORAX",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "HoU0Tw3WTiSMD2GRzezqnw",
"version" : {
"number" : "7.8.1",
"build_flavor" : "default",
"build_type" : "zip",
"build_hash" : "b5ca9c58fb664ca8bf9e4057fc229b3396bf3a89",
"build_date" : "2020-07-21T16:40:44.668009Z",
"build_snapshot" : false,
"lucene_version" : "8.5.1",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
<nil>
[Done] exited with code=0 in 2.516 seconds
Golang操作ES索引
es API
我们获得es客户端实例后,通过客户端实例可以获得es api,内容如下:
package esapi
// API contains the Elasticsearch APIs
//
type API struct {
Cat *Cat
Cluster *Cluster
Indices *Indices
Ingest *Ingest
Nodes *Nodes
Remote *Remote
Snapshot *Snapshot
Tasks *Tasks
AsyncSearch *AsyncSearch
CCR *CCR
ILM *ILM
License *License
Migration *Migration
ML *ML
Monitoring *Monitoring
Rollup *Rollup
Security *Security
SQL *SQL
SSL *SSL
Watcher *Watcher
XPack *XPack
AutoscalingDeleteAutoscalingPolicy AutoscalingDeleteAutoscalingPolicy
AutoscalingGetAutoscalingCapacity AutoscalingGetAutoscalingCapacity
AutoscalingGetAutoscalingDecision AutoscalingGetAutoscalingDecision
AutoscalingGetAutoscalingPolicy AutoscalingGetAutoscalingPolicy
AutoscalingPutAutoscalingPolicy AutoscalingPutAutoscalingPolicy
Bulk Bulk
ClearScroll ClearScroll
ClosePointInTime ClosePointInTime
Count Count
Create Create
DanglingIndicesDeleteDanglingIndex DanglingIndicesDeleteDanglingIndex
DanglingIndicesImportDanglingIndex DanglingIndicesImportDanglingIndex
DanglingIndicesListDanglingIndices DanglingIndicesListDanglingIndices
DataFrameTransformDeprecatedDeleteTransform DataFrameTransformDeprecatedDeleteTransform
DataFrameTransformDeprecatedGetTransform DataFrameTransformDeprecatedGetTransform
DataFrameTransformDeprecatedGetTransformStats DataFrameTransformDeprecatedGetTransformStats
DataFrameTransformDeprecatedPreviewTransform DataFrameTransformDeprecatedPreviewTransform
DataFrameTransformDeprecatedPutTransform DataFrameTransformDeprecatedPutTransform
DataFrameTransformDeprecatedStartTransform DataFrameTransformDeprecatedStartTransform
DataFrameTransformDeprecatedStopTransform DataFrameTransformDeprecatedStopTransform
DataFrameTransformDeprecatedUpdateTransform DataFrameTransformDeprecatedUpdateTransform
DeleteByQuery DeleteByQuery
DeleteByQueryRethrottle DeleteByQueryRethrottle
Delete Delete
DeleteScript DeleteScript
EnrichDeletePolicy EnrichDeletePolicy
EnrichExecutePolicy EnrichExecutePolicy
EnrichGetPolicy EnrichGetPolicy
EnrichPutPolicy EnrichPutPolicy
EnrichStats EnrichStats
EqlDelete EqlDelete
EqlGet EqlGet
EqlGetStatus EqlGetStatus
EqlSearch EqlSearch
Exists Exists
ExistsSource ExistsSource
Explain Explain
FeaturesGetFeatures FeaturesGetFeatures
FeaturesResetFeatures FeaturesResetFeatures
FieldCaps FieldCaps
FleetGlobalCheckpoints FleetGlobalCheckpoints
FleetMsearch FleetMsearch
FleetSearch FleetSearch
Get Get
GetScriptContext GetScriptContext
GetScriptLanguages GetScriptLanguages
GetScript GetScript
GetSource GetSource
GraphExplore GraphExplore
Index Index
Info Info
LogstashDeletePipeline LogstashDeletePipeline
LogstashGetPipeline LogstashGetPipeline
LogstashPutPipeline LogstashPutPipeline
Mget Mget
Msearch Msearch
MsearchTemplate MsearchTemplate
Mtermvectors Mtermvectors
OpenPointInTime OpenPointInTime
Ping Ping
PutScript PutScript
RankEval RankEval
Reindex Reindex
ReindexRethrottle ReindexRethrottle
RenderSearchTemplate RenderSearchTemplate
ScriptsPainlessExecute ScriptsPainlessExecute
Scroll Scroll
SearchMvt SearchMvt
Search Search
SearchShards SearchShards
SearchTemplate SearchTemplate
SearchableSnapshotsCacheStats SearchableSnapshotsCacheStats
SearchableSnapshotsClearCache SearchableSnapshotsClearCache
SearchableSnapshotsMount SearchableSnapshotsMount
SearchableSnapshotsRepositoryStats SearchableSnapshotsRepositoryStats
SearchableSnapshotsStats SearchableSnapshotsStats
ShutdownDeleteNode ShutdownDeleteNode
ShutdownGetNode ShutdownGetNode
ShutdownPutNode ShutdownPutNode
SlmDeleteLifecycle SlmDeleteLifecycle
SlmExecuteLifecycle SlmExecuteLifecycle
SlmExecuteRetention SlmExecuteRetention
SlmGetLifecycle SlmGetLifecycle
SlmGetStats SlmGetStats
SlmGetStatus SlmGetStatus
SlmPutLifecycle SlmPutLifecycle
SlmStart SlmStart
SlmStop SlmStop
TermsEnum TermsEnum
Termvectors Termvectors
TextStructureFindStructure TextStructureFindStructure
TransformDeleteTransform TransformDeleteTransform
TransformGetTransform TransformGetTransform
TransformGetTransformStats TransformGetTransformStats
TransformPreviewTransform TransformPreviewTransform
TransformPutTransform TransformPutTransform
TransformStartTransform TransformStartTransform
TransformStopTransform TransformStopTransform
TransformUpdateTransform TransformUpdateTransform
TransformUpgradeTransforms TransformUpgradeTransforms
UpdateByQuery UpdateByQuery
UpdateByQueryRethrottle UpdateByQueryRethrottle
Update Update
}
API结构体里面包含了Indices,内容如下:
// Indices contains the Indices APIs
type Indices struct {
AddBlock IndicesAddBlock
Analyze IndicesAnalyze
ClearCache IndicesClearCache
Clone IndicesClone
Close IndicesClose
CreateDataStream IndicesCreateDataStream
Create IndicesCreate
DataStreamsStats IndicesDataStreamsStats
DeleteAlias IndicesDeleteAlias
DeleteDataStream IndicesDeleteDataStream
DeleteIndexTemplate IndicesDeleteIndexTemplate
Delete IndicesDelete
DeleteTemplate IndicesDeleteTemplate
DiskUsage IndicesDiskUsage
ExistsAlias IndicesExistsAlias
ExistsDocumentType IndicesExistsDocumentType
ExistsIndexTemplate IndicesExistsIndexTemplate
Exists IndicesExists
ExistsTemplate IndicesExistsTemplate
FieldUsageStats IndicesFieldUsageStats
Flush IndicesFlush
FlushSynced IndicesFlushSynced
Forcemerge IndicesForcemerge
Freeze IndicesFreeze
GetAlias IndicesGetAlias
GetDataStream IndicesGetDataStream
GetFieldMapping IndicesGetFieldMapping
GetIndexTemplate IndicesGetIndexTemplate
GetMapping IndicesGetMapping
Get IndicesGet
GetSettings IndicesGetSettings
GetTemplate IndicesGetTemplate
GetUpgrade IndicesGetUpgrade
MigrateToDataStream IndicesMigrateToDataStream
ModifyDataStream IndicesModifyDataStream
Open IndicesOpen
PromoteDataStream IndicesPromoteDataStream
PutAlias IndicesPutAlias
PutIndexTemplate IndicesPutIndexTemplate
PutMapping IndicesPutMapping
PutSettings IndicesPutSettings
PutTemplate IndicesPutTemplate
Recovery IndicesRecovery
Refresh IndicesRefresh
ReloadSearchAnalyzers IndicesReloadSearchAnalyzers
ResolveIndex IndicesResolveIndex
Rollover IndicesRollover
Segments IndicesSegments
ShardStores IndicesShardStores
Shrink IndicesShrink
SimulateIndexTemplate IndicesSimulateIndexTemplate
SimulateTemplate IndicesSimulateTemplate
Split IndicesSplit
Stats IndicesStats
Unfreeze IndicesUnfreeze
UpdateAliases IndicesUpdateAliases
Upgrade IndicesUpgrade
ValidateQuery IndicesValidateQuery
}
CreateGetDelete
创建索引
创建索引函数如下:
type IndicesCreate func(index string, o ...func(*IndicesCreateRequest)) (*Response, error)
IndicesCreateRequest
实例演示:
package main
import (
"fmt"
"log"
"github.com/elastic/go-elasticsearch/v7"
)
// 创建索引
func CreatIndex(client *elasticsearch.Client, name string) {
r, _ := client.API.Indices.Create(name)
fmt.Printf("r: %v\n", r)
}
func main() {
es, err := elasticsearch.NewDefaultClient()
if err != nil {
log.Fatalf("获取es客户端错误: %s", err)
}
CreatIndex(es, "es_test")
}
运行结果:
[Running] go run "e:\golang开发学习\es\main.go"
r: [200 OK] {"acknowledged":true,"shards_acknowledged":true,"index":"es_test"}
[Done] exited with code=0 in 3.902 seconds
查询索引
查询索引函数如下:
type IndicesGet func(index []string, o ...func(*IndicesGetRequest)) (*Response, error)
传入需要查询的字符串切片即可
实例演示:
package main
import (
"fmt"
"log"
"github.com/elastic/go-elasticsearch/v7"
)
// 查询索引
func GetIndex(client *elasticsearch.Client, name string) {
r, _ := client.API.Indices.Get([]string{name})
fmt.Printf("r: %v\n", r)
}
func main() {
es, err := elasticsearch.NewDefaultClient()
if err != nil {
log.Fatalf("获取es客户端错误: %s", err)
}
GetIndex(es, "es_test")
}
运行结果:
[Running] go run "e:\golang开发学习\es\main.go"
r: [200 OK] {"es_test":{"aliases":{},"mappings":{},"settings":{"index":{"creation_date":"1663999135597","number_of_shards":"1","number_of_replicas":"1","uuid":"Mp9txec1R1Co4AONcoofGw","version":{"created":"7080199"},"provided_name":"es_test"}}}}
[Done] exited with code=0 in 1.751 seconds
删除索引
删除索引函数如下:
type IndicesDelete func(index []string, o ...func(*IndicesDeleteRequest)) (*Response, error)
传入需要删除的索引的字符串切片即可
实例演示:
package main
import (
"fmt"
"log"
"github.com/elastic/go-elasticsearch/v7"
)
// 删除索引
func DelIndex(client *elasticsearch.Client, name string) {
r, _ := client.API.Indices.Delete([]string{name})
fmt.Printf("r: %v\n", r)
}
func main() {
es, err := elasticsearch.NewDefaultClient()
if err != nil {
log.Fatalf("获取es客户端错误: %s", err)
}
DelIndex(es, "es_test")
}
运行结果:
[Running] go run "e:\golang开发学习\es\main.go"
r: [200 OK] {"acknowledged":true}
[Done] exited with code=0 in 1.95 seconds
Golang操作ES文档
插入文档
在这个章节中,我将一步一步地指导如何如何使用 go-elasticsearch 驱动来把文档导入到 Elasticsearch 中。
步骤一:导包
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"reflect"
"strconv"
"strings"
// Import the Elasticsearch library packages
"github.com/elastic/go-elasticsearch/v7"
"github.com/elastic/go-elasticsearch/v7/esapi"
)
在上面,我们使用 v7 版本,它对应于 Elastic Stack 7.x 版本的发布。
步骤二:为文档字段创捷结构体
使用 Golang struct 数据类型为要编制索引的 Elasticsearch 文档以及索引的相应字段创建框架:
// Declare a struct for Elasticsearch fields
type ElasticDocs struct {
SomeStr string
SomeInt int
SomeBool bool
}
步骤三:将结构体转换为JSON字符串
json.Marshal()
// structs to JSON
func jsonStruct(doc ElasticDocs) string {
// Create struct instance of the Elasticsearch fields struct object
docStruct := &ElasticDocs{
SomeStr: doc.SomeStr,
SomeInt: doc.SomeInt,
SomeBool: doc.SomeBool,
}
fmt.Println("\ndocStruct:", docStruct)
fmt.Println("docStruct TYPE:", reflect.TypeOf(docStruct))
// Marshal the struct to JSON and check for errors
b, err := json.Marshal(docStruct)
if err != nil {
fmt.Println("json.Marshal ERROR:", err)
return string(err.Error())
}
return string(b)
}
步骤四:创建 Elasticsearch Golang 客户端实例
为 API 调用创建一个新的上下文对象,并为 Elasticsearch 文档创建一个 map 对象:
func main() {
// 允许日志输出的自定义格式
log.SetFlags(0)
// 为API调用创建上下文对象
ctx := context.Background()
// 为Elasticsearch文档创建映射
var (
docMap map[string]interface{}
)
fmt.Println("docMap:", docMap)
fmt.Println("docMap TYPE:", reflect.TypeOf(docMap))
步骤五:实例化 Elasticsearch 客户端配置和 Golang 客户端实例
实例化一个新的 Elasticsearch 配置对象。 确保将正确的主机和端口信息以及任何用户名或密码传递给其 “Adressess” 属性。
// 声明Elasticsearch配置
cfg := elasticsearch.Config{
Addresses: []string{
"http://localhost:9200",
},
Username: "Psych",
Password: "666",
}
// 实例化新的Elasticsearch客户端对象实例
client, err := elasticsearch.NewClient(cfg)
if err != nil {
fmt.Println("Elasticsearch connection error:", err)
}
步骤六:检查与 Elasticsearch 的连接
// 让客户端实例返回响应
res, err := client.Info()
// 将响应反序列化为映射。
if err != nil {
log.Fatalf("client.Info() ERROR:", err)
} else {
log.Printf("client response:", res)
}
步骤七:创建 Elasticsearch 结构文档并将其放入数组
声明一个空字符串数组,以存储当前以 JSON 字符串表示的 Elasticsearch 文档。 以下代码显示了一些将用于索引的 Elasticsearch 文档示例。 要设置其字段的值,你需要做的就是修改结构实例的属性:
// 为文档字符串声明空数组
var docs []string
// 使用结构声明要索引的文档
doc1 := ElasticDocs{}
doc1.SomeStr = "Some Value"
doc1.SomeInt = 123456
doc1.SomeBool = true
doc2 := ElasticDocs{}
doc2.SomeStr = "Another Value"
doc2.SomeInt = 42
doc2.SomeBool = false
将这些文档实例传递给我们先前声明的 jsonStruct() 函数,并使它们返回代表每个文档的 JSON 字符串。 然后,我们将使用 Golang 的 append() 函数将 JSON 字符串添加到字符串数组中:
// document struct objects to JSON string
docStr1 := jsonStruct(doc1)
docStr2 := jsonStruct(doc2)
// Append the doc strings to an array
docs = append(docs, docStr1)
docs = append(docs, docStr2)
IndexRequest()
对已经建立好的文档数组进行迭代,并在进行过程中向 Elasticsearch 集群发出 API 请求。 这些API调用将通过调用 Golang 驱动程序的 esapi.IndexRequest() 方法来索引文档:
// 迭代文档数组
for i, bod := range docs {
fmt.Println("\nDOC _id:", i+1)
fmt.Println(bod)
// 实例化请求对象
req := esapi.IndexRequest {
Index: "some_index",
DocumentID: strconv.Itoa(i + 1),
Body: strings.NewReader(bod),
Refresh: "true",
}
fmt.Println(reflect.TypeOf(req))
Refreshrefresh
步骤九:检查 IndexRequest() 方法调用是否返回任何错误
在文档数组上进行迭代的最后一步是从 API 调用中获取响应,并检查是否存在错误:
// 从请求返回API响应对象
res, err := req.Do(ctx, client)
if err != nil {
log.Fatalf("IndexRequest ERROR: %s", err)
}
defer res.Body.Close()
在下面显示的代码中,如果没有错误返回,我们将解析 API 响应返回的结果对象:
if res.IsError() {
log.Printf("%s ERROR indexing document ID=%d", res.Status(), i+1)
} else {
// 将响应反序列化为映射。
var resMap map[string]interface{}
if err := json.NewDecoder(res.Body).Decode(&resMap); err != nil {
log.Printf("Error parsing the response body: %s", err)
} else {
log.Printf("\nIndexRequest() RESPONSE:")
// 打印响应状态和索引文档版本。
fmt.Println("Status:", res.Status())
fmt.Println("Result:", resMap["result"])
fmt.Println("Version:", int(resMap["_version"].(float64)))
fmt.Println("resMap:", resMap)
fmt.Println("\n")
}
}
}
}
map[string] interface{}
resMap: map[_id:2 _index:some_index _primary_term:1 _seq_no:1 _shards:map[failed:0 successful:1 total:2] _type:_doc _version:1 forced_refresh:true result:created]
代码总结
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"reflect"
"strconv"
"strings"
// Import the Elasticsearch library packages
"github.com/elastic/go-elasticsearch/v7"
"github.com/elastic/go-elasticsearch/v7/esapi"
)
// Declare a struct for Elasticsearch fields
type ElasticDocs struct {
SomeStr string
SomeInt int
SomeBool bool
}
// A function for marshaling structs to JSON string
func jsonStruct(doc ElasticDocs) string {
// Create struct instance of the Elasticsearch fields struct object
docStruct := &ElasticDocs{
SomeStr: doc.SomeStr,
SomeInt: doc.SomeInt,
SomeBool: doc.SomeBool,
}
fmt.Println("\ndocStruct:", docStruct)
fmt.Println("docStruct TYPE:", reflect.TypeOf(docStruct))
// Marshal the struct to JSON and check for errors
b, err := json.Marshal(docStruct)
if err != nil {
fmt.Println("json.Marshal ERROR:", err)
return string(err.Error())
}
return string(b)
}
func main() {
// Allow for custom formatting of log output
log.SetFlags(0)
// Create a context object for the API calls
ctx := context.Background()
// Create a mapping for the Elasticsearch documents
var (
docMap map[string]interface{}
)
fmt.Println("docMap:", docMap)
fmt.Println("docMap TYPE:", reflect.TypeOf(docMap))
// Declare an Elasticsearch configuration
cfg := elasticsearch.Config{
Addresses: []string{
"http://localhost:9200",
},
Username: "user",
Password: "pass",
}
// Instantiate a new Elasticsearch client object instance
client, err := elasticsearch.NewClient(cfg)
if err != nil {
fmt.Println("Elasticsearch connection error:", err)
}
// Have the client instance return a response
res, err := client.Info()
// Deserialize the response into a map.
if err != nil {
log.Fatalf("client.Info() ERROR:", err)
} else {
log.Printf("client response:", res)
}
// Declare empty array for the document strings
var docs []string
// Declare documents to be indexed using struct
doc1 := ElasticDocs{}
doc1.SomeStr = "Some Value"
doc1.SomeInt = 123456
doc1.SomeBool = true
doc2 := ElasticDocs{}
doc2.SomeStr = "Another Value"
doc2.SomeInt = 42
doc2.SomeBool = false
// Marshal Elasticsearch document struct objects to JSON string
docStr1 := jsonStruct(doc1)
docStr2 := jsonStruct(doc2)
// Append the doc strings to an array
docs = append(docs, docStr1)
docs = append(docs, docStr2)
// Iterate the array of string documents
for i, bod := range docs {
fmt.Println("\nDOC _id:", i+1)
fmt.Println(bod)
// Instantiate a request object
req := esapi.IndexRequest {
Index: "some_index",
DocumentID: strconv.Itoa(i + 1),
Body: strings.NewReader(bod),
Refresh: "true",
}
fmt.Println(reflect.TypeOf(req))
// Return an API response object from request
res, err := req.Do(ctx, client)
if err != nil {
log.Fatalf("IndexRequest ERROR: %s", err)
}
defer res.Body.Close()
if res.IsError() {
log.Printf("%s ERROR indexing document ID=%d", res.Status(), i+1)
} else {
// Deserialize the response into a map.
var resMap map[string]interface{}
if err := json.NewDecoder(res.Body).Decode(&resMap); err != nil {
log.Printf("Error parsing the response body: %s", err)
} else {
log.Printf("\nIndexRequest() RESPONSE:")
// Print the response status and indexed document version.
fmt.Println("Status:", res.Status())
fmt.Println("Result:", resMap["result"])
fmt.Println("Version:", int(resMap["_version"].(float64)))
fmt.Println("resMap:", resMap)
fmt.Println("\n")
}
}
}
}
运行结果
[Running] go run "e:\golang开发学习\es\document\main.go"
docMap: map[]
docMap TYPE: map[string]interface {}
client response:%!(EXTRA *esapi.Response=[200 OK] {
"name" : "MORAX",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "HoU0Tw3WTiSMD2GRzezqnw",
"version" : {
"number" : "7.8.1",
"build_flavor" : "default",
"build_type" : "zip",
"build_hash" : "b5ca9c58fb664ca8bf9e4057fc229b3396bf3a89",
"build_date" : "2020-07-21T16:40:44.668009Z",
"build_snapshot" : false,
"lucene_version" : "8.5.1",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
)
docStruct: &{Some Value 123456 true}
docStruct TYPE: *main.ElasticDocs
docStruct: &{Another Value 42 false}
docStruct TYPE: *main.ElasticDocs
DOC _id: 1
{"SomeStr":"Some Value","SomeInt":123456,"SomeBool":true}
esapi.IndexRequest
IndexRequest() RESPONSE:
Status: 201 Created
Result: created
Version: 1
resMap: map[_id:1 _index:some_index _primary_term:1 _seq_no:0 _shards:map[failed:0 successful:1 total:2] _type:_doc _version:1 forced_refresh:true result:created]
DOC _id: 2
{"SomeStr":"Another Value","SomeInt":42,"SomeBool":false}
esapi.IndexRequest
IndexRequest() RESPONSE:
Status: 201 Created
Result: created
Version: 1
resMap: map[_id:2 _index:some_index _primary_term:1 _seq_no:1 _shards:map[failed:0 successful:1 total:2] _type:_doc _version:1 forced_refresh:true result:created]
[Done] exited with code=0 in 3.3 seconds
postman中查看插入的数据
查询文档
查询在 SomeStr 这个字段含有 Another 的文档,在 main.go 里添加如下的代码:
// Search for the indexed document
// Build the request body
var buf bytes.Buffer
query := map[string]interface{}{
"query": map[string]interface{}{
"match": map[string]interface{}{
"SomeStr": "Another",
},
},
}
if err := json.NewEncoder(&buf).Encode(query); err != nil {
log.Fatalf("Error encoding query: %s", err)
}
// Perform the search request.
res, err = client.Search(
client.Search.WithContext(context.Background()),
client.Search.WithIndex("some_index"),
client.Search.WithBody(&buf),
client.Search.WithTrackTotalHits(true),
client.Search.WithPretty(),
)
if err != nil {
log.Fatalf("Error getting response: %s", err)
}
defer res.Body.Close()
if res.IsError() {
var e map[string]interface{}
if err := json.NewDecoder(res.Body).Decode(&e); err != nil {
log.Fatalf("Error parsing the response body: %s", err)
} else {
// Print the response status and error information.
log.Fatalf("[%s] %s: %s",
res.Status(),
e["error"].(map[string]interface{})["type"],
e["error"].(map[string]interface{})["reason"],
)
}
}
var r map[string]interface{}
if err := json.NewDecoder(res.Body).Decode(&r); err != nil {
log.Fatalf("Error parsing the response body: %s", err)
}
// Print the response status, number of results, and request duration.
log.Printf(
"[%s] %d hits; took: %dms",
res.Status(),
int(r["hits"].(map[string]interface{})["total"].(map[string]interface{})["value"].(float64)),
int(r["took"].(float64)),
)
// Print the ID and document source for each hit.
for _, hit := range r["hits"].(map[string]interface{})["hits"].([]interface{}) {
log.Printf(" * ID=%s, %s", hit.(map[string]interface{})["_id"], hit.(map[string]interface{})["_source"])
}
运行代码后,可以看到如下新添加的结果:
[200 OK] 1 hits; took: 10ms
* ID=2, map[SomeBool:%!s(bool=false) SomeInt:%!s(float64=42) SomeStr:Another Value]
删除文档
在 main.go 文件中,我们添加如下的代码来删除文档 id 为 1 的文档:
// Set up the request object.
req := esapi.DeleteRequest{
Index: "some_index",
DocumentID: strconv.Itoa(1),
}
res, err = req.Do(context.Background(), client)
if err != nil {
log.Fatalf("Error getting response: %s", err)
}
重新运行 main.go 应用。我们再到 postman 中去查询一下:
查询结果显示删除成功。
Gin集成ES创建一个项目gin_es
mkdir gin_es
cd gin_es
code .
go mod init gin_es
go get github.com/elastic/go-elasticsearch/v7
go get github.com/gin-gonic/gin
创建两个页面
创建一个目录templates,在该目录下创建两个页面,一个用来查询,一个用拉显示结果
templates\query.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>gin集成es</title>
</head>
<body>
<form action="/query" method="post">
keyword:<input type="text" name="keyword">
<input type="submit" value="查询">
</form>
</body>
</html>
templates\result.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>查询结果</title>
</head>
<body>
结果:{{.result}}
</body>
</html>
处理集成逻辑
package main
import (
"context"
"fmt"
"log"
"strings"
"github.com/elastic/go-elasticsearch/v7"
"github.com/elastic/go-elasticsearch/v7/esapi"
"github.com/gin-gonic/gin"
)
func Query(c *gin.Context) {
c.HTML(200, "query.html", nil)
}
func ESQuery(keyword string) *esapi.Response {
client, err := elasticsearch.NewDefaultClient()
if err != nil {
log.Fatalf("获取es客户端错误: %s", err)
}
// 查询条件
query := `{"query":{"match":{"category":"` + keyword + `"}},"size":3}`
fmt.Printf("query: %v\n", query)
var b strings.Builder
b.WriteString(query)
read := strings.NewReader(b.String())
// 查询请求
sr := &esapi.SearchRequest{
Index: []string{"golang"},
Body: read,
}
// 执行查询
r, err := sr.Do(context.Background(), client)
if err != nil {
log.Fatalf("查询错误: %s", err)
}
return r
}
func DoQuery(c *gin.Context) {
keyword := c.PostForm("keyword")
r := ESQuery(keyword)
c.HTML(200, "result.html", gin.H{
"result": r,
})
}
func main() {
e := gin.Default()
e.LoadHTMLGlob("templates/*")
e.GET("/query", Query)
e.POST("/query", DoQuery)
e.Run()
}
测试
护肤品
点击查询获取查询结果:
在postman中查看shopping索引中的文档:
全查询结果如下:
{
"took": 599,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 4,
"relation": "eq"
},
"max_score": 1.0,
"hits": [
{
"_index": "shopping",
"_type": "_doc",
"_id": "1",
"_score": 1.0,
"_source": {
"title": "sk2爽肤水",
"category": "护肤品",
"image": "https://www.tb.com",
"price": 899.0
}
},
{
"_index": "shopping",
"_type": "_doc",
"_id": "2",
"_score": 1.0,
"_source": {
"title": "眼霜",
"category": "化妆品",
"image": "https://www.tb.com",
"price": 249.0
}
},
{
"_index": "shopping",
"_type": "_doc",
"_id": "3",
"_score": 1.0,
"_source": {
"title": "拍立得",
"category": "数码产品",
"image": "https://www.tb.com",
"price": 299.0
}
},
{
"_index": "shopping",
"_type": "_doc",
"_id": "4",
"_score": 1.0,
"_source": {
"title": "科研洗面奶",
"category": "护肤品",
"image": "https://www.tb.com",
"price": 119.0
}
}
]
}
}
护肤品