Golang操作ES进行交互的实现实例

作者:

文章目录
  • 创建一个项目demo,初始化项目go mod init demo
  • go get github.com/elastic/go-elasticsearch/v7
  • 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()) }
  • 目录
    • 创建项目
    • 安装包
    • 连接到ES
      • 运行结果
    • Golang操作ES索引
      • es API
      • 创建索引
      • 查询索引
      • 删除索引
    • Golang操作ES文档
      • 插入文档
        • 步骤一:导包
        • 步骤二:为文档字段创捷结构体
        • 步骤三:将结构体转换为JSON字符串
        • 步骤四:创建 Elasticsearch Golang 客户端实例
        • 步骤五:实例化 Elasticsearch 客户端配置和 Golang 客户端实例
        • 步骤六:检查与 Elasticsearch 的连接
        • 步骤七:创建 Elasticsearch 结构文档并将其放入数组
        • 步骤八:迭代文档数组并调用 Golang 客户端的IndexRequest()方法
        • 步骤九:检查 IndexRequest() 方法调用是否返回任何错误
        • 代码总结
        • 运行结果
        • postman中查看插入的数据
      • 查询文档
        • 删除文档
        • Gin集成ES
          • 创建一个项目gin_es
            • 创建两个页面
              • 处理集成逻辑
                • 测试

                创建一个项目demo,初始化项目go mod init demo

                go get github.com/elastic/go-elasticsearch/v7
                

                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开发学习esmain.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
                

                我们获得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
                }
                

                该结构体包含了操作索引的一些方法,例如:创建索引Create、查询索引Get、删除索引Delete

                创建索引函数如下:

                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: %vn", r)
                }
                
                func main() {
                	es, err := elasticsearch.NewDefaultClient()
                	if err != nil {
                		log.Fatalf("获取es客户端错误: %s", err)
                	}
                	CreatIndex(es, "es_test")
                }
                

                运行结果:

                [Running] go run "e:golang开发学习esmain.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: %vn", r)
                }
                
                func main() {
                	es, err := elasticsearch.NewDefaultClient()
                	if err != nil {
                		log.Fatalf("获取es客户端错误: %s", err)
                	}
                	GetIndex(es, "es_test")
                }
                

                运行结果:

                [Running] go run "e:golang开发学习esmain.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: %vn", r)
                }
                
                func main() {
                	es, err := elasticsearch.NewDefaultClient()
                	if err != nil {
                		log.Fatalf("获取es客户端错误: %s", err)
                	}
                
                	DelIndex(es, "es_test")
                }
                

                运行结果:

                [Running] go run "e:golang开发学习esmain.go"
                r: [200 OK] {"acknowledged":true}
                
                [Done] exited with code=0 in 1.95 seconds
                

                在这个章节中,我将一步一步地指导如何如何使用 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
                }
                

                接下来,让我们看一个简单的函数,它将 Elasticsearch struct 文档实例转换为 JSON 字符串。 下面显示的代码可能看起来有些复杂,但是实际上发生的事情很简单–所有功能所做的就是将结构转换为字符串文字,然后将该字符串传递给 Golang 的 json.Marshal() 方法以使其返回字符串的JSON编码:

                // 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)
                }
                

                为 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 配置对象。 确保将正确的主机和端口信息以及任何用户名或密码传递给其 “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)
                	}
                

                	// 让客户端实例返回响应
                	res, err := client.Info()
                 
                	// 将响应反序列化为映射。
                	if err != nil {
                		log.Fatalf("client.Info() ERROR:", err)
                	} else {
                		log.Printf("client response:", res)
                	}
                

                声明一个空字符串数组,以存储当前以 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)
                

                对已经建立好的文档数组进行迭代,并在进行过程中向 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))
                

                在上面一定要注意的是:我们设置 Refresh 为 true。这在实际的使用中并不建议,原因是每次写入的时候都会 refresh。当我们面对大量的数据时,这样的操作会造成效率的底下。

                在文档数组上进行迭代的最后一步是从 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开发学习esdocumentmain.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
                

                查询在 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 中去查询一下:

                查询结果显示删除成功。

                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,在该目录下创建两个页面,一个用来查询,一个用拉显示结果

                templatesquery.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>
                

                templatesresult.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: %vn", 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()
                }
                

                浏览器输入:http://localhost:8080/query进入查询页面输入护肤品进行查询:

                点击查询获取查询结果:

                在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
                                }
                            }
                        ]
                    }
                }
                

                可以看出查询护肤品结果正确。

                到此这篇关于Golang操作ES进行交互的实现实例的文章就介绍到这了,更多相关Golang操作ES内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!

                您可能感兴趣的文章:

                • Go整合ElasticSearch的示例代码
                • GO语言操作Elasticsearch示例分享
                • go语言实现Elasticsearches批量修改查询及发送MQ操作示例
                • golang操作elasticsearch的实现

                站内搜索