GO 操作 Elasticsearch
<h1 id="官方库">官方库</h1><p>https://github.com/elastic/go-elasticsearch</p>
<h1 id="文档地址">文档地址</h1>
<p>Elasticsearch的文档https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html</p>
<p>所有客户端入口 https://www.elastic.co/guide/en/elasticsearch/client/index.html</p>
<p>go 客户端文档 https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/index.html</p>
<h1 id="环境说明">环境说明</h1>
<table>
<thead>
<tr>
<th>elasticsearch版本</th>
<th>GO版本</th>
</tr>
</thead>
<tbody>
<tr>
<td>8.15.1</td>
<td>go1.23.0 windows/amd64</td>
</tr>
</tbody>
</table>
<h1 id="安装-go-elasticsearch-库">安装 go-elasticsearch 库</h1>
<pre><code class="language-bash">go get github.com/elastic/go-elasticsearch/v8@latest
</code></pre>
<h1 id="连接-elasticsearch">连接 elasticsearch</h1>
<p>先创建配置,然后创建客户端,剩下的操作都是通过客户端操作</p>
<h2 id="通过用户名密码连接">通过用户名密码连接</h2>
<pre><code class="language-go">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)
}
}
</code></pre>
<p>需要注意 es 进入8版本后,就默认开启了https了,也建议开启,所以,这里如果只有用户名密码,就需要设置忽略证书,否则会报错</p>
<pre><code class="language-bash">tls: failed to verify certificate: x509: certificate signed by unknown authority
</code></pre>
<h2 id="通过api-密钥连接">通过API 密钥连接</h2>
<h3 id="创建-api-密钥">创建 API 密钥</h3>
<p>找到 <code>Stack Management</code><br>
<img src="https://img2024.cnblogs.com/blog/2908207/202409/2908207-20240910103506608-1595009298.png" alt="" loading="lazy"><br>
找到 安全 中的 API 密钥,选择创建 API 密钥<br>
<img src="https://img2024.cnblogs.com/blog/2908207/202409/2908207-20240910103624564-282844853.png" alt="" loading="lazy"></p>
<p><img src="https://img2024.cnblogs.com/blog/2908207/202409/2908207-20240910103738429-45694025.png" alt="" loading="lazy"></p>
<p>可以看到已经生成了密钥,一定要先保存下来,之后就无法再次查看密钥了</p>
<p><img src="https://img2024.cnblogs.com/blog/2908207/202409/2908207-20240910103854392-1349854561.png" alt="" loading="lazy"></p>
<h3 id="连接">连接</h3>
<pre><code class="language-go">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)
}
}
</code></pre>
<h2 id="通过证书连接">通过证书连接</h2>
<p>怎么获取这个ca证书,可以参考文档https://www.elastic.co/guide/en/elasticsearch/client/go-api/current/connecting.html#verifying-with-ca</p>
<pre><code class="language-go">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)
}
}
</code></pre>
<h1 id="创建客户端">创建客户端</h1>
<h2 id="低级的api创建客户端">低级的API创建客户端</h2>
<p>使用 <code>elasticsearch.NewClient()</code> 方法创建</p>
<pre><code class="language-go">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)
}
}
</code></pre>
<h2 id="全类型api常用">全类型API(常用)</h2>
<p>使用方法 <code>elasticsearch.NewTypedClient()</code></p>
<p>这种方式是链式访问,而且是有上下文控制的,用起来会更舒服一些</p>
<pre><code class="language-go">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)
}
}
</code></pre>
<h1 id="简单测试访问">简单测试访问</h1>
<h2 id="低级api">低级API</h2>
<pre><code class="language-go">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)
}
</code></pre>
<p>结果</p>
<pre><code class="language-bash"> {
"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"
}
</code></pre>
<h2 id="全类型api">全类型API</h2>
<pre><code class="language-go">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)
}
</code></pre>
<p>结果</p>
<pre><code class="language-bash">&{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}}
</code></pre>
<p>可以看到,通过全类型访问获得的Info相关的信息,是直接就是个对象</p>
<blockquote>
<p>下面的代码将不再出现创建配置和客户端的部分,客户端的变量为 <code>es</code></p>
</blockquote>
<h1 id="索引">索引</h1>
<h2 id="创建索引">创建索引</h2>
<h3 id="低级api-1">低级API</h3>
<pre><code class="language-go">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)
}
</code></pre>
<p>结果</p>
<pre><code class="language-bash"> {"acknowledged":true,"shards_acknowledged":true,"index":"test_index"}
</code></pre>
<h3 id="全类型api-1">全类型API</h3>
<pre><code class="language-go">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)
}
</code></pre>
<p>结果</p>
<pre><code class="language-bash">&{Acknowledged:true Index:test_index ShardsAcknowledged:true}
</code></pre>
<h2 id="查看索引">查看索引</h2>
<h3 id="低级api-2">低级API</h3>
<pre><code class="language-go">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)
}
</code></pre>
<p>结果</p>
<pre><code class="language-bash"> {"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"}}}}}
</code></pre>
<h3 id="全类型api-2">全类型API</h3>
<pre><code class="language-go">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)
}
</code></pre>
<p>结果</p>
<pre><code class="language-bash">map DataStream:<nil> Defaults:<nil> Lifecycle:<nil> Mappings:0xc0000d2580 Settings:0xc0000c2fc8}]
</code></pre>
<h2 id="删除索引">删除索引</h2>
<pre><code class="language-go">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)
}
</code></pre>
<p>结果</p>
<pre><code class="language-bash">&{Acknowledged:true Shards_:<nil>}
</code></pre>
<h1 id="文档">文档</h1>
<h2 id="创建单个">创建单个</h2>
<h3 id="低级api-3">低级API</h3>
<pre><code class="language-go">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)
}
</code></pre>
<h4 id="带id的创建">带Id的创建</h4>
<pre><code class="language-go">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)
}
</code></pre>
<h3 id="全类型api-3">全类型API</h3>
<h4 id="通过字符串添加">通过字符串添加</h4>
<pre><code class="language-go">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)
}
</code></pre>
<h4 id="通过对象添加">通过对象添加</h4>
<pre><code class="language-go">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)
}
</code></pre>
<h4 id="带id的创建-1">带ID的创建</h4>
<pre><code class="language-go">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)
}
</code></pre>
<h2 id="批量创建文档">批量创建文档</h2>
<h3 id="低级api-4">低级API</h3>
<pre><code class="language-go">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)
}
</code></pre>
<p>结果</p>
<pre><code class="language-bash">2024/09/10 14:52:31 Bulk response: {"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}}]}
</code></pre>
<h3 id="全类型api-4">全类型API</h3>
<pre><code class="language-go">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)
}
</code></pre>
<p>结果</p>
<pre><code class="language-bash">2024/09/10 15:14:26 &{false <nil> 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 map[index:{<nil
> <nil> <nil> 0xc000212a40 test_index 0xc000207210 0xc000212a90 0xc0002071c8 0xc000210280 201 0xc000207118}] map] 0}
</code></pre>
<h2 id="删除文档">删除文档</h2>
<h3 id="通过id-删除">通过ID 删除</h3>
<h4 id="低级api-5">低级API</h4>
<pre><code class="language-go">res, err := es.Delete("test_index", "97804515249315")
</code></pre>
<h4 id="全类型api-5">全类型API</h4>
<pre><code class="language-go">res, err := es.Delete("test_index", "yFfh2pEB_DYqwI8dnUlN").Do(context.TODO())
</code></pre>
<h3 id="通过查询条件删除">通过查询条件删除</h3>
<h4 id="低级api-6">低级API</h4>
<pre><code class="language-go">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)
}
</code></pre>
<p>结果</p>
<pre><code class="language-go"> {"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":[]}
</code></pre>
<p>会提示删除了2条记录</p>
<h4 id="全类型api-6">全类型API</h4>
<pre><code class="language-go">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 = maptypes.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)
}
</code></pre>
<h2 id="更新文档">更新文档</h2>
<h3 id="根据id修改">根据ID修改</h3>
<h4 id="低级api-7">低级API</h4>
<pre><code class="language-go">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)
}
</code></pre>
<blockquote>
<p>这里要注意,更新的数据是 <code>{ "name": "bbbbbb" }</code> 而不是 <code>{"doc": { "name": "bbbbbb" }}</code><br>
这个字段 <code>{"doc": { "name": "bbbbbb" }}</code> 必须是json格式的,所以各个字段都需要加上双引号<br>
doc 是固定字段</p>
</blockquote>
<h4 id="全类型api-7">全类型API</h4>
<pre><code class="language-go">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)
}
</code></pre>
<h3 id="根据条件修改">根据条件修改</h3>
<h4 id="低级api-8">低级API</h4>
<pre><code class="language-go">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)
}
</code></pre>
<blockquote>
<p>注意:<br>
更新脚本处的 ctx._source.author = 'aaaaaaaaa' 意思是把字段 author 的值设置成 aaaaaaaaa</p>
</blockquote>
<h4 id="全类型api-8">全类型API</h4>
<pre><code class="language-go">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 = maptypes.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)
}
</code></pre>
<blockquote>
<p>这里需要注意的是,在写 <code>Script.Source</code> 的时候,需要用 <code>some.String</code> 包一下,因为这里面传的是字符串指针</p>
</blockquote>
<h2 id="查找文档">查找文档</h2>
<h3 id="简单查询">简单查询</h3>
<h4 id="低级api-9">低级API</h4>
<pre><code class="language-go">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)
}
</code></pre>
<p>结果</p>
<pre><code class="language-bash">response: {"_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}}
</code></pre>
<h4 id="全类型api-9">全类型API</h4>
<pre><code class="language-go">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)
}
</code></pre>
<p>结果</p>
<pre><code class="language-go">{"release_date":"1985-06-01","author":"ddddd","name":"The Handmaid's Tale1","page_count":311}
The Handmaid's Tale1
</code></pre>
<h2 id="条件查询">条件查询</h2>
<h3 id="匹配-match">匹配 match</h3>
<h4 id="低级api-10">低级API</h4>
<pre><code class="language-go">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)
}
</code></pre>
<p>输出</p>
<pre><code class="language-bash">response: {
"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
}
}
]
}
}
</code></pre>
<p>可以看到,直接使用的原生的查询语句,所以,其他类似的,也是这么做</p>
<h4 id="全类型api-10">全类型API</h4>
<pre><code class="language-go">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 = maptypes.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_))
}
}
</code></pre>
<p>输出</p>
<pre><code class="language-bash">{"author":"ddddd","name":"The Great Gatsby1"}
{"author":"ddddd","name":"The Handmaid's Tale"}
{"author":"ddddd","name":"The Handmaid's Tale1"}
</code></pre>
<h3 id="多字段匹配">多字段匹配</h3>
<pre><code class="language-go">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_))
}
}
</code></pre>
<p>查找name或者author为bbbbb的</p>
<h3 id="精确快速匹配-term">精确快速匹配 term</h3>
<pre><code class="language-go">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 = maptypes.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_))
}
}
</code></pre>
<p>结果</p>
<pre><code class="language-bash">{"name":"bbbbbb","author":"bbbbbb","release_date":"2000-03-15","page_count":585}
{"release_date":"1985-06-01","author":"ddddd","name":"bbbbbb","page_count":311}
</code></pre>
<h3 id="范围-range">范围 range</h3>
<pre><code class="language-go">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 = maptypes.RangeQuery{
"page_count": mapany{
"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_))
}
}
</code></pre>
<p>结果</p>
<pre><code class="language-bash">{"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}
</code></pre>
<h3 id="正则表达式-regexp">正则表达式 regexp</h3>
<pre><code class="language-go">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 = maptypes.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_))
}
}
</code></pre>
<p>结果</p>
<pre><code class="language-bash">{"name": "1984", "author": "George Orwell", "release_date": "1985-06-01", "page_count": 328}
</code></pre>
<h3 id="前缀查询-prefix">前缀查询 prefix</h3>
<pre><code class="language-go">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 = maptypes.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_))
}
}
</code></pre>
<p>结果</p>
<pre><code class="language-bash">{"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}
</code></pre>
<h3 id="查字段存在">查字段存在</h3>
<pre><code class="language-go">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_))
}
}
</code></pre>
<p>结果</p>
<pre><code class="language-bash">{"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}
</code></pre>
<h3 id="分页">分页</h3>
<pre><code class="language-go">q := types.NewQuery()
q.MatchAll = &types.MatchAllQuery{}
res, err := es.Search().Index(index).Query(q).From(2).Size(2).Do(context.TODO())
</code></pre>
</div>
<div id="MySignature" role="contentinfo">
<p>本文来自博客园,作者:厚礼蝎,转载请注明原文链接:https://www.cnblogs.com/guangdelw/p/18406142</p><br><br>
来源:https://www.cnblogs.com/guangdelw/p/18406142
頁:
[1]