GO 操作 Elasticsearch

官方库

https://github.com/elastic/go-elasticsearch

文档地址

Elasticsearch的文档 https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html

所有客户端入口 https://www.elastic.co/guide/en/elasticsearch/client/index.html

go 客户端文档 https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/index.html

环境说明

elasticsearch版本 GO版本
8.15.1 go1.23.0 windows/amd64

安装 go-elasticsearch 库

go get github.com/elastic/go-elasticsearch/v8@latest

连接 elasticsearch

先创建配置,然后创建客户端,剩下的操作都是通过客户端操作

通过用户名密码连接

package main

import (
	"crypto/tls"
	"github.com/elastic/go-elasticsearch/v8"
	"log"
	"net/http"
)

func main() {
	cfg := elasticsearch.Config{
		Addresses: []string{"https://10.1.0.200:9200"},
		Username: "elastic",
		Password: "111111",
		// 需要忽略证书
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		},
	}
	es, err := elasticsearch.NewClient(cfg)
	if err != nil {
		log.Fatalf("Error creating the client: %s", err)
	}
}

需要注意 es 进入8版本后,就默认开启了https了,也建议开启,所以,这里如果只有用户名密码,就需要设置忽略证书,否则会报错

tls: failed to verify certificate: x509: certificate signed by unknown authority

通过API 密钥连接

创建 API 密钥

找到 Stack Management

找到 安全 中的 API 密钥,选择创建 API 密钥

可以看到已经生成了密钥,一定要先保存下来,之后就无法再次查看密钥了

连接

package main

import (
	"crypto/tls"
	"github.com/elastic/go-elasticsearch/v8"
	"log"
	"net/http"
)

func main() {
	cfg := elasticsearch.Config{
		Addresses: []string{"https://10.1.0.200:9200"},
		APIKey:    "V2xmTDJaRUJfRFlxxxxxxxxxxxxxxxxxxxxxV2bUdUSC1qVDVZam9CRlVkZw==",
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		},
	}
    // 创建客户端
	es, err := elasticsearch.NewClient(cfg)
	if err != nil {
		log.Fatalf("Error creating the client: %s", err)
	}
}

通过证书连接

怎么获取这个ca证书,可以参考文档 https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/connecting.html#verifying-with-ca

package main

import (
	"github.com/elastic/go-elasticsearch/v8"
	"log"
	"os"
)

func main() {
	caCert, err := os.ReadFile("ca.crt")
	if err != nil {
		log.Fatalf("Error reading CA certificate: %s", err)
	}
	cfg := elasticsearch.Config{
		Addresses: []string{"https://10.1.0.200:9200"},
		APIKey:    "V2xmTDJaRUJfRFlxxxxxxxxxxxxxxxxxxxxxV2bUdUSC1qVDVZam9CRlVkZw==",
		CACert:    caCert,
	}
	es, err := elasticsearch.NewClient(cfg)
	if err != nil {
		log.Fatalf("Error creating the client: %s", err)
	}
}

创建客户端

低级的API创建客户端

使用 elasticsearch.NewClient() 方法创建

package main

import (
	"github.com/elastic/go-elasticsearch/v8"
	"log"
	"os"
)

func main() {
	caCert, err := os.ReadFile("ca.crt")
	if err != nil {
		log.Fatalf("Error reading CA certificate: %s", err)
	}
	cfg := elasticsearch.Config{
		Addresses: []string{"https://10.1.0.200:9200"},
		APIKey:    "V2xmTDJaRUJfRFlxxxxxxxxxxxxxxxxxxxxxV2bUdUSC1qVDVZam9CRlVkZw==",
		CACert:    caCert,
	}
	es, err := elasticsearch.NewClient(cfg)
	if err != nil {
		log.Fatalf("Error creating the client: %s", err)
	}
}

全类型API(常用)

使用方法 elasticsearch.NewTypedClient()

这种方式是链式访问,而且是有上下文控制的,用起来会更舒服一些

package main

import (
	"github.com/elastic/go-elasticsearch/v8"
	"log"
	"os"
)

func main() {
	caCert, err := os.ReadFile("ca.crt")
	if err != nil {
		log.Fatalf("Error reading CA certificate: %s", err)
	}
	cfg := elasticsearch.Config{
		Addresses: []string{"https://10.1.0.200:9200"},
		APIKey:    "V2xmTDJaRUJfRFlxxxxxxxxxxxxxxxxxxxxxV2bUdUSC1qVDVZam9CRlVkZw==",
		CACert:    caCert,
	}
	es, err := elasticsearch.NewTypedClient(cfg)
	if err != nil {
		log.Fatalf("Error creating the client: %s", err)
	}
}

简单测试访问

低级API

package main

import (
	"fmt"
	"github.com/elastic/go-elasticsearch/v8"
	"log"
	"os"
)

func main() {
	caCert, err := os.ReadFile("ca.crt")
	if err != nil {
		log.Fatalf("Error reading CA certificate: %s", err)
	}
	cfg := elasticsearch.Config{
		Addresses: []string{"https://10.1.0.200:9200"},
		APIKey:    "V2xmTDJaRUJfRFlxxxxxxxxxxxxxxxxxxxxxV2bUdUSC1qVDVZam9CRlVkZw==",
		CACert:    caCert,
	}
	es, err := elasticsearch.NewClient(cfg)
	if err != nil {
		log.Fatalf("Error creating the client: %s", err)
	}
	// API Key should have cluster monitoring rights
	infores, err := es.Info()
	if err != nil {
		log.Fatalf("Error getting response: %s", err)
	}
	//
	fmt.Println(infores)
}

结果

[200 OK] {
  "name" : "es01",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "VXMrg1BlRqqdjbkKoTfNeg",
  "version" : {
    "number" : "8.15.1",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "253e8544a65ad44581194068936f2a5d57c2c051",
    "build_date" : "2024-09-02T22:04:47.310170297Z",
    "build_snapshot" : false,
    "lucene_version" : "9.11.1",
    "minimum_wire_compatibility_version" : "7.17.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "You Know, for Search"
}

全类型API

package main

import (
	"context"
	"fmt"
	"github.com/elastic/go-elasticsearch/v8"
	"log"
	"os"
)

func main() {
	caCert, err := os.ReadFile("ca.crt")
	if err != nil {
		log.Fatalf("Error reading CA certificate: %s", err)
	}
	cfg := elasticsearch.Config{
		Addresses: []string{"https://10.1.0.200:9200"},
		APIKey:    "V2xmTDJaRUJfRFlxxxxxxxxxxxxxxxxxxxxxV2bUdUSC1qVDVZam9CRlVkZw==",
		CACert:    caCert,
	}
	es, err := elasticsearch.NewTypedClient(cfg)
	if err != nil {
		log.Fatalf("Error creating the client: %s", err)
	}
	// API Key should have cluster monitoring rights
	infores, err := es.Info().Do(context.TODO())
	if err != nil {
		log.Fatalf("Error getting response: %s", err)
	}

	fmt.Printf("%+++v\n", infores)
}

结果

&{ClusterName:docker-cluster ClusterUuid:VXMrg1BlRqqdjbkKoTfNeg Name:es01 Tagline:You Know, for Search Version:{BuildDate:2024-09-02T22:04:47.310170297Z BuildFlavor:default BuildHash
:253e8544a65ad44581194068936f2a5d57c2c051 BuildSnapshot:false BuildType:docker Int:8.15.1 LuceneVersion:9.11.1 MinimumIndexCompatibilityVersion:7.0.0 MinimumWireCompatibilityVersion:7.17.0}}

可以看到,通过全类型访问获得的Info相关的信息,是直接就是个对象

下面的代码将不再出现创建配置和客户端的部分,客户端的变量为 es

索引

创建索引

低级API

package main

import (
	"fmt"
	"github.com/elastic/go-elasticsearch/v8"
	"log"
	"os"
)

func main() {
	resp, err := es.Indices.Create("test_index")
	if err != nil {
		log.Fatalf("Error getting response: %s", err)
	}

	fmt.Println(resp)
}

结果

[200 OK] {"acknowledged":true,"shards_acknowledged":true,"index":"test_index"}

全类型API

package main

import (
	"context"
	"fmt"
	"github.com/elastic/go-elasticsearch/v8"
	"log"
	"os"
)

func main() {
	resp, err := es.Indices.Create("test_index").Do(context.TODO())
	if err != nil {
		log.Fatalf("Error getting response: %s", err)
	}

	fmt.Printf("%+++v\n", resp)
}

结果

&{Acknowledged:true Index:test_index ShardsAcknowledged:true}

查看索引

低级API

package main

import (
	"fmt"
	"github.com/elastic/go-elasticsearch/v8"
	"log"
	"os"
)

func main() {
	resp, err := es.Indices.Get([]string{"test_index"})
	if err != nil {
		log.Fatalf("Error getting response: %s", err)
	}
	fmt.Println(resp)
}

结果

[200 OK] {"test_index":{"aliases":{},"mappings":{},"settings":{"index":{"routing":{"allocation":{"include":{"_tier_preference":"data_content"}}},"number_of_shards":"1","provided_name":"test_index","creation_date":"1725939541276","number_of_replicas":"1","uuid":"Y5bvZZWdQ7ixskaSY4JMmA","version":{"created":"8512000"}}}}}

全类型API

package main

import (
	"context"
	"fmt"
	"github.com/elastic/go-elasticsearch/v8"
	"log"
	"os"
)


func main() {
	resp, err := es.Indices.Get("test_index").Do(context.TODO())
	if err != nil {
		log.Fatalf("Error getting response: %s", err)
	}

	fmt.Printf("%+++v\n", resp)
}

结果

map[test_index:{Aliases:map[] DataStream:<nil> Defaults:<nil> Lifecycle:<nil> Mappings:0xc0000d2580 Settings:0xc0000c2fc8}]

删除索引

package main

import (
	"context"
	"fmt"
	"github.com/elastic/go-elasticsearch/v8"
	"log"
	"os"
)

func main() {
	resp, err := es.Indices.Delete("test_index").Do(context.TODO())
	if err != nil {
		log.Fatalf("Error getting response: %s", err)
	}

	fmt.Printf("%+++v\n", resp)
}

结果

&{Acknowledged:true Shards_:<nil>}

文档

创建单个

低级API

package main

import (
	"bytes"
	"encoding/json"
	"github.com/elastic/go-elasticsearch/v8"
	"log"
	"os"
)

type Book struct {
	Name        string `json:"name"`
	Author      string `json:"author"`
	ReleaseDate string `json:"release_date"`
	PageCount   int    `json:"page_count"`
}

var es *elasticsearch.Client


func main() {
	book := Book{Name: "To Kill a Mockingbird1", Author: "Harper Lee", ReleaseDate: "1960-07-11", PageCount: 281}
	data, _ := json.Marshal(book)
	ingestResult, err := es.Index("test_index", bytes.NewReader(data))
	if err != nil {
		log.Fatalf("Error getting response: %s", err)
	}
	log.Printf("Bulk response: %s", ingestResult)
}

带Id的创建

package main

import (
	"bytes"
	"encoding/json"
	"github.com/elastic/go-elasticsearch/v8"
	"log"
	"os"
)

type Book struct {
	Name        string `json:"name"`
	Author      string `json:"author"`
	ReleaseDate string `json:"release_date"`
	PageCount   int    `json:"page_count"`
}

var es *elasticsearch.Client

func main() {
	book := Book{Name: "To Kill a Mockingbird1", Author: "Harper Lee", ReleaseDate: "1960-07-11", PageCount: 281}
	data, _ := json.Marshal(book)
    // 带上自定义的ID
	ingestResult, err := es.Index("test_index", bytes.NewReader(data), es.Index.WithDocumentID("1"))
	if err != nil {
		log.Fatalf("Error getting response: %s", err)
	}
	log.Printf("Bulk response: %s", ingestResult)
}

全类型API

通过字符串添加

package main

import (
	"context"
	"github.com/elastic/go-elasticsearch/v8"
	"log"
	"os"
	"strings"
)

var (
	index = "test_index"
)

var es *elasticsearch.TypedClient


func main() {
	res, err := es.Index(index).Raw(
		strings.NewReader(`{"name":"aaaaaaa","author":"Neal Stephenson","release_date":"1992-06-01","page_count": 470}`),
	).Do(context.TODO())
	if err != nil {
		log.Fatalf("Error getting response: %s", err)
	}
	log.Println(res)
}

通过对象添加

package main

import (
	"bytes"
	"context"
	"github.com/elastic/go-elasticsearch/v8"
	"log"
	"os"
)

var (
	index = "test_index"
)

type Book struct {
	Name        string `json:"name"`
	Author      string `json:"author"`
	ReleaseDate string `json:"release_date"`
	PageCount   int    `json:"page_count"`
}

var es *elasticsearch.TypedClient


func main() {
	book := Book{Name: "The Great Gatsby1", Author: "F. Scott Fitzgerald", ReleaseDate: "1925-04-10", PageCount: 180}
	res, err := es.Index(index).Request(book).Do(context.TODO())
	if err != nil {
		log.Fatalf("Error response: %s", err)
	}
	log.Println(res)
}

带ID的创建

package main

import (
	"bytes"
	"context"
	"github.com/elastic/go-elasticsearch/v8"
	"log"
	"os"
)

var (
	index = "test_index"
)

type Book struct {
	Name        string `json:"name"`
	Author      string `json:"author"`
	ReleaseDate string `json:"release_date"`
	PageCount   int    `json:"page_count"`
}

var es *elasticsearch.TypedClient


func main() {
	book := Book{Name: "The Great Gatsby1", Author: "F. Scott Fitzgerald", ReleaseDate: "1925-04-10", PageCount: 180}
	res, err := es.Index(index).Id("2").Request(book).Do(context.TODO())
	if err != nil {
		log.Fatalf("Error response: %s", err)
	}
	log.Println(res)
}

批量创建文档

低级API

import (
	"bytes"
	"github.com/elastic/go-elasticsearch/v8"
	"log"
	"os"
)

var es *elasticsearch.Client

func main() {
	buf := bytes.NewBufferString(
		`
	{"index":{"_id":"9780553351927"}}
	{"name":"Snow Crash","author":"Neal Stephenson","release_date":"1992-06-01","page_count": 470}
	{ "index": { "_id": "9780441017225"}}
	{"name": "Revelation Space", "author": "Alastair Reynolds", "release_date": "2000-03-15", "page_count": 585}
	{ "index": { "_id": "9780451524935"}}
	{"name": "1984", "author": "George Orwell", "release_date": "1985-06-01", "page_count": 328}
	{ "index": { "_id": "9781451673319"}}
	{"name": "Fahrenheit 451", "author": "Ray Bradbury", "release_date": "1953-10-15", "page_count": 227}
	{ "index": { "_id": "9780060850524"}}
	{"name": "Brave New World", "author": "Aldous Huxley", "release_date": "1932-06-01", "page_count": 268}
	{ "index": { "_id": "9780385490818"}}
	{"name": "The Handmaid's Tale", "author": "Margaret Atwood", "release_date": "1985-06-01", "page_count": 311}
	`,
	)
	// 添加换行符
	buf.WriteByte('\n')
	ingestResult, err := es.Bulk(
		bytes.NewReader(buf.Bytes()),
		es.Bulk.WithIndex("test_index"),
	)
	if err != nil {
		log.Fatalf("Error getting response: %s", err)
	}
	log.Printf("Bulk response: %s", ingestResult)
}

结果

2024/09/10 14:52:31 Bulk response: [200 OK] {"errors":false,"took":600,"items":[{"index":{"_index":"test_index","_id":"9780553351927","_version":1,"result":"created","_shards":{"total":2,"successful":2,"failed":0},"_seq_no":0,"_primary_term":1,"status":201}},{"index":{"_index":"test_index","_id":"9780441017225","_version":1,"result":"created","_shards":{"total":2,"successful":2,"failed":0},"_seq_no":1,"_primary_term":1,"status":201}},{"index":{"_index":"test_index","_id":"9780451524935","_version":1,"result":"created","_shards":{"total":2,"successful":2,"failed":0},"_seq_no":2,"_primary_term":1,"status":201}},{"index":{"_index":"test_index","_id":"9781451673319","_version":1,"result":"created","_shards":{"total":2,"successful":2,"failed":0},"_seq_no":3,"_primary_term":1,"status":201}},{"index":{"_index":"test_index","_id":"9780060850524","_version":1,"result":"created","_shards":{"total":2,"successful":2,"failed":0},"_seq_no":4,"_primary_term":1,"status":201}},{"index":{"_index":"test_index","_id":"9780385490818","_version":1,"result":"created","_shards":{"total":2,"successful":2,"failed":0},"_seq_no":5,"_primary_term":1,"status":201}}]}

全类型API

package main

import (
	"bytes"
	"context"
	"github.com/elastic/go-elasticsearch/v8"
	"log"
	"os"
)

var (
	index = "test_index"
)

var es *elasticsearch.TypedClient


func main() {
	buf := bytes.NewBufferString(
		`
	{"index":{"_id":"97805533519271"}}
	{"name":"Snow Crash1","author":"Neal Stephenson","release_date":"1992-06-01","page_count": 470}
	{ "index": { "_id": "97804410172251"}}
	{"name": "Revelation Space1", "author": "Alastair Reynolds", "release_date": "2000-03-15", "page_count": 585}
	{ "index": { "_id": "97804515249315"}}
	{"name": "19841", "author": "George Orwell", "release_date": "1985-06-01", "page_count": 328}
	{ "index": { "_id": "97814516733119"}}
	{"name": "Fahrenheit 4511", "author": "Ray Bradbury", "release_date": "1953-10-15", "page_count": 227}
	{ "index": { "_id": "97800608505214"}}
	{"name": "Brave New World1", "author": "Aldous Huxley", "release_date": "1932-06-01", "page_count": 268}
	{ "index": { "_id": "97803854908118"}}
	{"name": "The Handmaid's Tale1", "author": "Margaret Atwood", "release_date": "1985-06-01", "page_count": 311}
	`,
	)
	buf.WriteString("\n")
	res, err := es.Bulk().Index(index).Raw(buf).Do(context.TODO())
	if err != nil {
		log.Fatalf("Error response: %s", err)
	}
	log.Println(res)
}

结果

2024/09/10 15:14:26 &{false <nil> [map[index:{<nil> <nil> <nil> 0xc0002124a0 test_index 0xc000206a10 0xc0002124f0 0xc0002069c8 0xc000210140 201 0xc000206920}] map[index:{<nil> <nil> 
<nil> 0xc000212610 test_index 0xc000206c10 0xc000212660 0xc000206bc8 0xc000210180 201 0xc000206b18}] map[index:{<nil> <nil> <nil> 0xc000212770 test_index 0xc000206e10 0xc0002127c0 0x
c000206dc8 0xc0002101c0 201 0xc000206d18}] map[index:{<nil> <nil> <nil> 0xc0002128d0 test_index 0xc000207010 0xc000212920 0xc000206fc8 0xc000210200 201 0xc000206f18}] map[index:{<nil
> <nil> <nil> 0xc000212a40 test_index 0xc000207210 0xc000212a90 0xc0002071c8 0xc000210280 201 0xc000207118}] map[index:{<nil> <nil> <nil> 0xc000212ba0 test_index 0xc000207410 0xc000212bf0 0xc0002073c8 0xc0002102c0 201 0xc000207318}]] 0}

删除文档

通过ID 删除

低级API

res, err := es.Delete("test_index", "97804515249315")

全类型API

res, err := es.Delete("test_index", "yFfh2pEB_DYqwI8dnUlN").Do(context.TODO())

通过查询条件删除

低级API

package main

import (
	"github.com/elastic/go-elasticsearch/v8"
	"log"
	"os"
	"strings"
)

var es *elasticsearch.Client


func main() {
    // 创建查询条件
	q := `{
		"query": {
			"match": {
				"name": "Fahrenheit"
			}
		}
	}`
	res, err := es.DeleteByQuery([]string{"test_index"}, strings.NewReader(q))
	if err != nil {
		log.Fatalf("Error response: %s", err)
	}
	log.Printf("response: %s", res)
}

结果

[200 OK] {"took":34,"timed_out":false,"total":2,"deleted":2,"batches":1,"version_conflicts":0,"noops":0,"retries":{"bulk":0,"search":0},"throttled_millis":0,"requests_per_second":-1.0,"throttled_until_millis":0,"failures":[]}

会提示删除了2条记录

全类型API

package main

import (
	"context"
	"github.com/elastic/go-elasticsearch/v8"
	"github.com/elastic/go-elasticsearch/v8/typedapi/types"
	"log"
	"os"
)


var (
	index = "test_index"
)

var es *elasticsearch.TypedClient

func main() {
	q := types.NewQuery()
	q.Match = map[string]types.MatchQuery{
		"name": {Query: "snow"},
	}
	res, err := es.DeleteByQuery(index).Query(q).Do(context.TODO())
	if err != nil {
		log.Fatalf("Error response: %s", err)
	}
	log.Println(res)
}

更新文档

根据ID修改

低级API

package main

import (
	"github.com/elastic/go-elasticsearch/v8"
	"log"
	"os"
	"strings"
)

var es *elasticsearch.Client

func main() {
	res, err := es.Update(
		"test_index",
		"9780441017225",
		strings.NewReader(`{"doc": { "name": "bbbbbb" }}`),
	)
	if err != nil {
		log.Fatalf("Error response: %s", err)
	}
	log.Printf("response: %s", res)
}

这里要注意,更新的数据是 { "name": "bbbbbb" } 而不是 {"doc": { "name": "bbbbbb" }}
这个字段 {"doc": { "name": "bbbbbb" }} 必须是json格式的,所以各个字段都需要加上双引号
doc 是固定字段

全类型API

package main

import (
	"context"
	"encoding/json"
	"github.com/elastic/go-elasticsearch/v8"
	"github.com/elastic/go-elasticsearch/v8/typedapi/core/update"
	"log"
	"os"
)

var (
	index = "test_index"
)

var es *elasticsearch.TypedClient

func main() {
	res, err := es.Update(index, "9780441017225").
		Request(
			&update.Request{
				Doc: json.RawMessage(`{"name": "cccccc"}`),
			},
		).
		Do(context.TODO())
	if err != nil {
		log.Fatalf("Error response: %s", err)
	}
	log.Println(res)
}

根据条件修改

低级API

package main

import (
	"context"
	"github.com/elastic/go-elasticsearch/v8"
	"github.com/elastic/go-elasticsearch/v8/esapi"
	"log"
	"os"
	"strings"
)

var es *elasticsearch.Client


func main() {
	// 定义查询JSON,用于匹配"name"字段为"the"开头的文档,并将"author"更新为"aaaaaaaaa"
	q := `{
	"query": {
		"match": {
			"name": "the"
		}
	},
	"script": {
		"source": "ctx._source.author = 'aaaaaaaaa'"
	}
}`
	// 创建UpdateByQueryRequest实例,指定操作的索引为"test_index",请求体为更新脚本
	req := esapi.UpdateByQueryRequest{
		Index: []string{"test_index"},
		Body:  strings.NewReader(q),
	}

	// 执行更新请求,更新匹配条件的文档的作者字段
	res, err := req.Do(context.Background(), es)
	if err != nil {
		// 如果有错误发生,记录并处理错误
		log.Fatalf("Error response: %s", err)
	}
	// 记录响应内容
	log.Printf("response: %s", res)
}

注意:
更新脚本处的 ctx._source.author = 'aaaaaaaaa' 意思是把字段 author 的值设置成 aaaaaaaaa

全类型API

package main

import (
	"context"
	"github.com/elastic/go-elasticsearch/v8"
	"github.com/elastic/go-elasticsearch/v8/typedapi/some"
	"github.com/elastic/go-elasticsearch/v8/typedapi/types"
	"log"
	"os"
)

var es *elasticsearch.TypedClient

func main() {
	q := types.NewQuery()
	q.Match = map[string]types.MatchQuery{
		"name": {Query: "the"},
	}
	s := types.NewScript()
	s.Source = some.String("ctx._source.author = 'ddddd'")
	res, err := es.UpdateByQuery("test_index").Query(q).Script(s).Do(context.TODO())
	if err != nil {
		log.Fatalf("Error response: %s", err)
	}
	log.Println(res)
}

这里需要注意的是,在写 Script.Source 的时候,需要用 some.String 包一下,因为这里面传的是字符串指针

查找文档

简单查询

低级API

package main

import (
	"github.com/elastic/go-elasticsearch/v8"
	"log"
	"os"
)

var es *elasticsearch.Client


func main() {
	res, err := es.Get("test_index", "97803854908118")
	if err != nil {
		// 如果有错误发生,记录并处理错误
		log.Fatalf("Error response: %s", err)
	}
	// 记录响应内容
	log.Printf("response: %++v\n", res)
}

结果

response: [200 OK] {"_index":"test_index","_id":"97803854908118","_version":5,"_seq_no":35,"_primary_term":1,"found":true,"_source":{"release_date":"1985-06-01","author":"ddddd","name":"The Handmaid's Tale1","page_count":311}}

全类型API

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/elastic/go-elasticsearch/v8"
	"log"
	"os"
)

type Book struct {
	Name        string `json:"name"`
	Author      string `json:"author"`
	ReleaseDate string `json:"release_date"`
	PageCount   int    `json:"page_count"`
}

var (
	index = "test_index"
)

var es *elasticsearch.TypedClient


func main() {
	res, err := es.Get(index, "97803854908118").Do(context.TODO())
	if err != nil {
		log.Fatalf(err.Error())
	}
	fmt.Println(string(res.Source_))
	var a *Book
	r, _ := json.Marshal(res.Source_)
	_ = json.Unmarshal(r, &a)
	fmt.Printf("%v", a.Name)
}

结果

{"release_date":"1985-06-01","author":"ddddd","name":"The Handmaid's Tale1","page_count":311}
The Handmaid's Tale1

条件查询

匹配 match

低级API

package main

import (
	"fmt"
	"github.com/elastic/go-elasticsearch/v8"
	"log"
	"os"
	"strings"
)


var es *elasticsearch.Client


func main() {
	q := `{
		"query": {
			"match": {
				"author": "ddddd"
			}
		}
	}`
	res, err := es.Search(
		es.Search.WithIndex("test_index"),
		es.Search.WithBody(strings.NewReader(q)),
		es.Search.WithPretty(),
		es.Search.WithSource("name, page_count"),
	)
	if err != nil {
		// 如果有错误发生,记录并处理错误
		log.Fatalf("Error response: %s", err)
	}
	// 记录响应内容
	fmt.Printf("response: %++v\n", res)
}

输出

response: [200 OK] {
  "took" : 6,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.3771044,
    "hits" : [
      {
        "_index" : "test_index",
        "_id" : "I1fZ2pEB_DYqwI8dY0ke",
        "_score" : 1.3771044,
        "_source" : {
          "name" : "The Great Gatsby1",
          "page_count" : 180
        }
      },
      {
        "_index" : "test_index",
        "_id" : "9780385490818",
        "_score" : 1.3771044,
        "_source" : {
          "name" : "The Handmaid's Tale",
          "page_count" : 311
        }
      },
      {
        "_index" : "test_index",
        "_id" : "97803854908118",
        "_score" : 1.3771044,
        "_source" : {
          "name" : "The Handmaid's Tale1",
          "page_count" : 311
        }
      }
    ]
  }
}

可以看到,直接使用的原生的查询语句,所以,其他类似的,也是这么做

全类型API

import (
	"context"
	"fmt"
	"github.com/elastic/go-elasticsearch/v8"
	"github.com/elastic/go-elasticsearch/v8/typedapi/types"
	"log"
	"os"
)

var (
	index = "test_index"
)

var es *elasticsearch.TypedClient



func main() {
	q := types.NewQuery()
	q.Match = map[string]types.MatchQuery{
		"author": {Query: "ddddd"},
	}
	res, err := es.Search().Index(index).Query(q).Source_([]string{"name", "author"}).Do(context.TODO())
	if err != nil {
		log.Fatalf(err.Error())
	}
	for _, hit := range res.Hits.Hits {
		fmt.Printf("%++v\n", string(hit.Source_))
	}
}

输出

{"author":"ddddd","name":"The Great Gatsby1"}
{"author":"ddddd","name":"The Handmaid's Tale"}
{"author":"ddddd","name":"The Handmaid's Tale1"}

多字段匹配

package main

import (
	"context"
	"fmt"
	"github.com/elastic/go-elasticsearch/v8"
	"github.com/elastic/go-elasticsearch/v8/typedapi/types"
	"log"
	"os"
)

var (
	index = "test_index"
)

var es *elasticsearch.TypedClient


func main() {
	q := types.NewQuery()
	q.MultiMatch = &types.MultiMatchQuery{
		Query:  "bbbbb",
		Fields: []string{"name", "author"},
	}
	res, err := es.Search().Index(index).Query(q).Do(context.TODO())
	if err != nil {
		log.Fatalf(err.Error())
	}
	for _, hit := range res.Hits.Hits {
		fmt.Printf("%++v\n", string(hit.Source_))
	}
}

查找name或者author为bbbbb的

精确快速匹配 term

package main

import (
	"context"
	"fmt"
	"github.com/elastic/go-elasticsearch/v8"
	"github.com/elastic/go-elasticsearch/v8/typedapi/types"
	"log"
	"os"
)

var (
	index = "test_index"
)

var es *elasticsearch.TypedClient


func main() {
	q := types.NewQuery()
	q.Term = map[string]types.TermQuery{
		"name": {Value: "bbbbbb"},
	}
	res, err := es.Search().Index(index).Query(q).Do(context.TODO())
	if err != nil {
		log.Fatalf(err.Error())
	}
	for _, hit := range res.Hits.Hits {
		fmt.Printf("%++v\n", string(hit.Source_))
	}
}

结果

{"name":"bbbbbb","author":"bbbbbb","release_date":"2000-03-15","page_count":585}
{"release_date":"1985-06-01","author":"ddddd","name":"bbbbbb","page_count":311}

范围 range

package main

import (
	"context"
	"fmt"
	"github.com/elastic/go-elasticsearch/v8"
	"github.com/elastic/go-elasticsearch/v8/typedapi/types"
	"log"
	"os"
)

var (
	index = "test_index"
)

var es *elasticsearch.TypedClient



func main() {
	q := types.NewQuery()
	q.Range = map[string]types.RangeQuery{
		"page_count": map[string]any{
			"gte": 300,
			"lt":  400,
		},
	}
	res, err := es.Search().Index(index).Query(q).Do(context.TODO())
	if err != nil {
		log.Fatalf(err.Error())
	}
	for _, hit := range res.Hits.Hits {
		fmt.Printf("%++v\n", string(hit.Source_))
	}
}

结果

{"name": "1984", "author": "George Orwell", "release_date": "1985-06-01", "page_count": 328}
{"release_date":"1985-06-01","author":"ddddd","name":"The Handmaid's Tale","page_count":311}
{"release_date":"1985-06-01","author":"ddddd","name":"The Handmaid's Tale1","page_count":311}

正则表达式 regexp

package main

import (
	"context"
	"fmt"
	"github.com/elastic/go-elasticsearch/v8"
	"github.com/elastic/go-elasticsearch/v8/typedapi/types"
	"log"
	"os"
)

var (
	index = "test_index"
)

var es *elasticsearch.TypedClient

func main() {
	q := types.NewQuery()
	q.Regexp = map[string]types.RegexpQuery{
		"name": types.RegexpQuery{
			Value: `\d{4}`,
		},
	}
	res, err := es.Search().Index(index).Query(q).Do(context.TODO())
	if err != nil {
		log.Fatalf(err.Error())
	}
	for _, hit := range res.Hits.Hits {
		fmt.Printf("%++v\n", string(hit.Source_))
	}
}

结果

{"name": "1984", "author": "George Orwell", "release_date": "1985-06-01", "page_count": 328}

前缀查询 prefix

package main

import (
	"context"
	"fmt"
	"github.com/elastic/go-elasticsearch/v8"
	"github.com/elastic/go-elasticsearch/v8/typedapi/types"
	"log"
	"os"
)

var (
	index = "test_index"
)

var es *elasticsearch.TypedClient

func main() {
	q := types.NewQuery()
	q.Prefix = map[string]types.PrefixQuery{
		"name": types.PrefixQuery{
			Value: "the",
		},
	}
	res, err := es.Search().Index(index).Query(q).Do(context.TODO())
	if err != nil {
		log.Fatalf(err.Error())
	}
	for _, hit := range res.Hits.Hits {
		fmt.Printf("%++v\n", string(hit.Source_))
	}
}

结果

{"release_date":"1925-04-10","author":"ddddd","name":"The Great Gatsby1","page_count":180}
{"release_date":"1985-06-01","author":"ddddd","name":"The Handmaid's Tale","page_count":311}

查字段存在

package main

import (
	"context"
	"fmt"
	"github.com/elastic/go-elasticsearch/v8"
	"github.com/elastic/go-elasticsearch/v8/typedapi/types"
	"log"
	"os"
)

var (
	index = "test_index"
)

var es *elasticsearch.TypedClient

func main() {
	q := types.NewQuery()
	q.Exists = &types.ExistsQuery{
		Field: "name",
	}
	res, err := es.Search().Index(index).Query(q).Do(context.TODO())
	if err != nil {
		log.Fatalf(err.Error())
	}
	for _, hit := range res.Hits.Hits {
		fmt.Printf("%++v\n", string(hit.Source_))
	}
}

结果

{"name":"aaaaaaa","author":"Neal Stephenson","release_date":"1992-06-01","page_count": 470}
{"name":"To Kill a Mockingbird1","author":"Harper Lee","release_date":"1960-07-11","page_count":281}
{"name": "1984", "author": "George Orwell", "release_date": "1985-06-01", "page_count": 328}
{"name": "Brave New World", "author": "Aldous Huxley", "release_date": "1932-06-01", "page_count": 268}
{"name": "Revelation Space1", "author": "Alastair Reynolds", "release_date": "2000-03-15", "page_count": 585}
{"name": "Brave New World1", "author": "Aldous Huxley", "release_date": "1932-06-01", "page_count": 268}
{"release_date":"1925-04-10","author":"ddddd","name":"The Great Gatsby1","page_count":180}
{"release_date":"1985-06-01","author":"ddddd","name":"The Handmaid's Tale","page_count":311}
{"name":"bbbbbb","author":"bbbbbb","release_date":"2000-03-15","page_count":585}
{"release_date":"1985-06-01","author":"ddddd","name":"bbbbbb","page_count":311}

分页

q := types.NewQuery()
q.MatchAll = &types.MatchAllQuery{}
res, err := es.Search().Index(index).Query(q).From(2).Size(2).Do(context.TODO())
posted @ 2024-09-10 22:01  厚礼蝎  阅读(177)  评论(0编辑  收藏  举报