天天看點

go-elasticsearch 官方包操作合集導包連接配接用戶端索引操作 CRUD文檔操作查詢操作聚合查詢

導包

require (
	github.com/elastic/go-elasticsearch/v7 v7.12.0
	)
           

連接配接用戶端

var (
	client *es.Client
)

func init() {
	var err error
	client, err = es.NewClient(es.Config{
		Addresses: []string{"http://192.168.6.39:9201"},
		// 配置HTTP傳輸對象
		Transport: &http.Transport{
			//MaxIdleConnsPerHost 如果非零,控制每個主機保持的最大空閑(keep-alive)連接配接。如果為零,則使用預設配置2。
			MaxIdleConnsPerHost: 10,
			//ResponseHeaderTimeout 如果非零,則指定在寫完請求(包括請求體,如果有)後等待伺服器響應頭的時間。
			ResponseHeaderTimeout: time.Second,
			//DialContext 指定撥号功能,用于建立不加密的TCP連接配接。如果DialContext為nil(下面已棄用的Dial也為nil),那麼傳輸撥号使用包網絡。
			DialContext: (&net.Dialer{Timeout: time.Second}).DialContext,
			// TLSClientConfig指定TLS.client使用的TLS配置。
			//如果為空,則使用預設配置。
			//如果非nil,預設情況下可能不啟用HTTP/2支援。
			TLSClientConfig: &tls.Config{
				MaxVersion: tls.VersionTLS11,
				//InsecureSkipVerify 控制用戶端是否驗證伺服器的證書鍊和主機名。
				InsecureSkipVerify: true,
			},
		},
	})
	if err != nil {
		log.Fatal(err)
	}
}
           

索引操作 CRUD

添加索引

// es-官方包 添加索引操作
func TestAddIndex(t *testing.T) {
	// type IndicesCreate func(index string, o ...func(*IndicesCreateRequest)) (*Response, error)  官方函數
	response, _ := client.API.Indices.Create("es_test")
	fmt.Printf("response: %v\n", response)
}
           

查詢索引

// 查詢索引
func TestGetIndex(t *testing.T) {
	// type IndicesGet func(index []string, o ...func(*IndicesGetRequest)) (*Response, error)
	response, _ := client.API.Indices.Get([]string{"es_test"})
	fmt.Printf("response: %v\n", response)
}
           

删除索引

// 删除索引
func TestDelIndex(t *testing.T) {
	//	type IndicesDelete func(index []string, o ...func(*IndicesDeleteRequest)) (*Response, error)
	response, _ := client.API.Indices.Delete([]string{"es_test_book"})
	fmt.Printf("response: %v\n", response)
}
           

文檔操作

建立索引

// 建立文檔
type Book struct {
	ID      string     `json:"id"`
	Author  string     `json:"author"`
	Name    string     `json:"name"`
	Pages   int        `json:"pages"`
	Price   float64    `json:"price"`
	PubDate *time.Time `json:"pubDate"`
	Summary string     `json:"summary"`
}

func TestAddDoc(t *testing.T) {
	assertions := assert.New(t)
	body := &bytes.Buffer{}
	pubDate := time.Now()
	err := json.NewEncoder(body).Encode(&Book{
		Author:  "金庸",
		Price:   96.0,
		Name:    "天龍八部",
		Pages:   1978,
		PubDate: &pubDate,
		Summary: "...",
	})
	assertions.Nil(err)
	// 建立
	response, err := client.Create("es_test_book", "1", body)
	assertions.Nil(err)
	t.Log(response)
}

           

覆寫性更新文檔

func TestIndexDocument(t *testing.T) {
	a := assert.New(t)
	body := &bytes.Buffer{}
	pubDate := time.Now()
	err := json.NewEncoder(body).Encode(&Book{
		Author:  "金庸",
		Price:   96.0,
		Name:    "天龍八部",
		Pages:   1978,
		PubDate: &pubDate,
		Summary: "...",
	})
	a.Nil(err)
	response, err := client.Index("es_book", body, client.Index.WithDocumentID("1"))
	a.Nil(err)
	t.Log(response)
}
           

局部性更新文檔,

// 下面的代碼借助go json的omitempty,在将更新資料對象序列化成json,
// 可以隻序列化非零值字段,實作局部更新。 實際項目采用這種方式時,需要注意某個字段的零值具有業務意義時,可以采用對應的指針類型實作。
type doc struct {
	Doc interface{} `json:"doc"`
}
type Book1 struct {
	Author  string     `json:"author,omitempty"`
	Name    string     `json:"name,omitempty"`
	Pages   int        `json:"pages,omitempty"`
	Price   float64    `json:"price,omitempty"`
	PubDate *time.Time `json:"pubDate,omitempty"`
	Summary string     `json:"summary,omitempty"`
}

func TestPartialUpdateDocument(t *testing.T) {
	a := assert.New(t)
	body := &bytes.Buffer{}
	err := json.NewEncoder(body).Encode(&doc{
		Doc: &Book1{
			Name: "《天龍八部》",
		},
	})
	a.Nil(err)
	response, err := client.Update("es_book", "1", body)

	a.Nil(err)
	t.Log(response)
}
           

删除文檔

func TestDeleteDocument(t *testing.T) {
	a := assert.New(t)
	response, err := client.Delete("es_book", "1")
	a.Nil(err)
	t.Log(response)
}
           

擷取文檔

func TestGetDocument(t *testing.T) {
	assertions := assert.New(t)
	response, err := client.Get("es_book", "1")
	assertions.Nil(err)
	t.Log(response)
}
           

文檔的批量操作添加跟删除

/ 批量操作對應ES的REST API是:
// POST /<target>/_bulk
// { "index" : { "_id" : "1" } }
// { "field1" : "value1" }
// { "delete" : { "_id" : "2" } }
// { "create" : { "_id" : "3" } }
// { "field1" : "value3" }
// { "update" : {"_id" : "1" } }
// { "doc" : {"field2" : "value2"} }
// 對應index, create, update操作,
// 送出的資料都是由兩行組成,第一行是meta資料,描述操作資訊
// ,第二行是具體送出的資料,對于delete操作隻有一行meta資料。 對照REST API
func TestBulk(t *testing.T) {
	createBooks := []*Book{
		{
			ID:     "10002",
			Name:   "神雕俠侶",
			Author: "金庸",
		},
		{
			ID:     "10003",
			Name:   "射雕英雄傳",
			Author: "金庸",
		},
	}
	deleteBookIds := []string{"1"}

	a := assert.New(t)
	body := &bytes.Buffer{}
	for _, book := range createBooks {
		meta := []byte(fmt.Sprintf(`{ "index" : { "_id" : "%s" } }%s`, book.ID, "\n"))
		data, err := json.Marshal(book)
		a.Nil(err)
		data = append(data, "\n"...)
		body.Grow(len(meta) + len(data))
		body.Write(meta)
		body.Write(data)
	}
	for _, id := range deleteBookIds {
		meta := []byte(fmt.Sprintf(`{ "delete" : { "_id" : "%s" } }%s`, id, "\n"))
		body.Grow(len(meta))
		body.Write(meta)
	}
	t.Log(body.String())

	response, err := client.Bulk(body, client.Bulk.WithIndex("book"))
	a.Nil(err)
	t.Log(response)
}

           

文檔搜尋 單個字段

// 文檔搜尋 單個字段
func TestSearchByOneDoc(t *testing.T) {
	a := assert.New(t)

	query := map[string]interface{}{
		"query": map[string]interface{}{
			"match": map[string]interface{}{
				"name": "神雕俠侶",
			},
		},
		"highlight": map[string]interface{}{
			"pre_tags":  []string{"<font color='red'>"},
			"post_tags": []string{"</font>"},
			"fields": map[string]interface{}{
				"title": map[string]interface{}{},
			},
		},
	}
	marshal, _ := json.Marshal(query)
	response, err := client.Search(client.Search.WithIndex("book"), client.Search.WithBody(bytes.NewReader(marshal)))
	a.Nil(err)
	t.Log(response)
}
           

查詢操作

提高某個字段權重,可以使用 ^ 字元文法為單個字段提升權重,在字段名稱的末尾添加 ^boost ,其中 boost 是一個浮點數:

func TestSearchBy(t *testing.T) {
	a := assert.New(t)
	query := map[string]interface{}{
		"query": map[string]interface{}{
			"multi_match": map[string]interface{}{
				"query":  "《天龍八部》",
				"fields": []string{"name", "author^2"},
			},
		},
		"highlight": map[string]interface{}{
			"pre_tags":  []string{"<font color='red'>"},
			"post_tags": []string{"</font>"},
			"fields": map[string]interface{}{
				"title": map[string]interface{}{},
			},
		},
	}
	marshal, _ := json.Marshal(query)
	t.Log(string(marshal))
	response, err := client.Search(client.Search.WithIndex("book"), client.Search.WithBody(bytes.NewReader(marshal)))
	a.Nil(err)
	t.Log(response)
}
           

// 顯示所有的

func TestSearchByAll(t *testing.T) {
	a := assert.New(t)
	query := map[string]interface{}{
		"query": map[string]interface{}{
			"match_all": map[string]interface{}{},
		},
	}
	marshal, _ := json.Marshal(query)
	t.Log(string(marshal))
	response, err := client.Search(client.Search.WithIndex("book"), client.Search.WithBody(bytes.NewReader(marshal)))
	a.Nil(err)
	t.Log(response)
}
           

// 範圍查詢通過range實作範圍查詢,類似SQL語句中的>, >=, <, <=表達式。 gte範圍參數 - 等價于>= lte範圍參數 - 等價于 <= 範圍參數可以隻寫一個,例如:僅保留 “gte”: 10, 則代表 FIELD字段 >= 10

func TestSearchByRang(t *testing.T) {
	a := assert.New(t)
	query := map[string]interface{}{
		"query": map[string]interface{}{
			"range": map[string]interface{}{
				"price": map[string]interface{}{
					"gte": "0",
					"lte": "20",
				},
			},
		},
	}
	marshal, _ := json.Marshal(query)
	t.Log(string(marshal))
	response, err := client.Search(client.Search.WithIndex("book"), client.Search.WithBody(bytes.NewReader(marshal)))
	a.Nil(err)
	t.Log(response)
}
           

文檔搜尋 多個字段

func TestSearchByInesDoc(t *testing.T) {
	a := assert.New(t)
	query := map[string]interface{}{
		"query": map[string]interface{}{
			"multi_match": map[string]interface{}{
				"query":  "金",
				"fields": []string{"name", "author"},
			},
		},
		"highlight": map[string]interface{}{
			"pre_tags":  []string{"<font color='red'>"},
			"post_tags": []string{"</font>"},
			"fields": map[string]interface{}{
				"title": map[string]interface{}{},
			},
		},
	}
	marshal, _ := json.Marshal(query)
	response, err := client.Search(client.Search.WithIndex("book"), client.Search.WithBody(bytes.NewReader(marshal)))
	a.Nil(err)
	t.Log(response)
}
           

布爾 must and

func TestSearchByAnd(t *testing.T) {
	a := assert.New(t)

	name := "金庸"
	price := "0"
	query := map[string]interface{}{
		"query": map[string]interface{}{
			"bool": map[string]interface{}{
				"must": []map[string]interface{}{
					{
						"match": map[string]interface{}{
							"author": name,
						},
					},
					{
						"match": map[string]interface{}{
							"price": price,
						},
					},
				},
			},
		},
		"from": 0,
		"size": 1,
		"sort": []map[string]interface{}{
			{"pubDate": []map[string]interface{}{
				{"order": "desc"},
			},
			},
		},
	}
	marshal, _ := json.Marshal(query)

	response, err := client.Search(client.Search.WithIndex("book"), client.Search.WithBody(bytes.NewReader(marshal)))
	a.Nil(err)
	t.Log(response)
}
           

布爾查詢 or

func TestSearchByOr(t *testing.T) {
	a := assert.New(t)

	name := "金庸"
	price := "0"
	query := map[string]interface{}{
		"query": map[string]interface{}{
			"bool": map[string]interface{}{
				"should": []map[string]interface{}{
					{
						"match": map[string]interface{}{
							"author": name,
						},
					},
					{
						"match": map[string]interface{}{
							"price": price,
						},
					},
				},
			},
		},
		"from": 0,
		"size": 1,
		"sort": []map[string]interface{}{
			{"pubDate": []map[string]interface{}{
				{"order": "desc"},
			},
			},
		},
	}
	marshal, _ := json.Marshal(query)

	response, err := client.Search(client.Search.WithIndex("book"), client.Search.WithBody(bytes.NewReader(marshal)))
	a.Nil(err)
	t.Log(response)
}
           

精确度查詢

func TestSearchByTerm(t *testing.T) {
	a := assert.New(t)
	query := map[string]interface{}{
		"query": map[string]interface{}{
			"term": map[string]interface{}{
				"name.keyword": "射雕英雄傳",
			},
		},
	}

	marshal, _ := json.Marshal(query)
	t.Log(string(marshal))
	response, err := client.Search(client.Search.WithIndex("book"), client.Search.WithBody(bytes.NewReader(marshal)))
	a.Nil(err)
	t.Log(response)
}
           

使用Mysql 的方式查詢

func TestSearchBySql(t *testing.T) {
	a := assert.New(t)
	index := "book"
	query := map[string]interface{}{
		"query": "select count(1) from " + index,
	}
	jsonBody, _ := json.Marshal(query)
	t.Log(string(jsonBody))
	response, err := client.SQL.Query(bytes.NewReader(jsonBody), client.SQL.Query.WithContext(context.Background()))
	a.Nil(err)
	t.Log(response)
}
           

Cat 的操作

func TestCatDemo(t *testing.T) {
	// 檢視叢集健康狀态
	health, _ := client.Cat.Health()
	t.Log(health.String())
	//allocation 檢視節點磁盤資源配置設定資訊
	allocation, _ := client.Cat.Allocation(client.Cat.Allocation.WithNodeID(""))
	t.Log(allocation)
	//shards 節點分片資訊
	shards, _ := client.Cat.Shards()
	t.Log(shards)
	//master?v 檢視主節點
	master, _ := client.Cat.Master()
	t.Log(master)
	// nodes 檢視叢集資訊
	nodes, _ := client.Cat.Nodes()
	t.Log(nodes)
	// tasks 傳回叢集中一個或多個節點上目前執行的任務資訊。
	tasks, _ := client.Cat.Tasks()
	t.Log(tasks)
	// indices 檢視索引資訊
	response, _ := client.Cat.Indices(client.Cat.Indices.WithIndex(""))
	t.Log(response)
	// segments 分片中的分段資訊
	segments, _ := client.Cat.Segments()
	t.Log(segments)
	// count 檢視目前叢集的doc數量
	count, _ := client.Cat.Count()
	t.Log(count)
	// recovery 顯示正在進行和先前完成的索引碎片恢複的視圖
	recovery, _ := client.Cat.Recovery()
	t.Log(recovery)
	// /pending_tasks 顯示正在等待的任務
	pendingTasks, _ := client.Cat.PendingTasks()
	t.Log(pendingTasks)
	// aliases 顯示别名、過濾器、路由資訊
	aliases, _ := client.Cat.Aliases()
	t.Log(aliases)
	// thread_pool 檢視線程池資訊
	threadPool, _ := client.Cat.ThreadPool()
	t.Log(threadPool)
	// plugins 顯示每個運作插件節點的視圖
	plugins, _ := client.Cat.Plugins()
	t.Log(plugins)
	// fielddata #檢視每個資料節點上fielddata目前占用的堆記憶體。
	fielddata, _ := client.Cat.Fielddata()
	t.Log(fielddata)
	// nodeattrs 檢視每個節點的自定義屬性
	nodeattrs, _ := client.Cat.Nodeattrs()
	t.Log(nodeattrs)
	// /templates 模闆
	templates, _ := client.Cat.Templates()
	t.Log(templates)
}
           

聚合查詢

聚合 group by

func TestAggGroupBy(t *testing.T) {
	a := assert.New(t)
	query := map[string]interface{}{
		"aggs": map[string]interface{}{ // 合查詢語句的簡寫
			"count_name": map[string]interface{}{ // 給聚合查詢取個名字,
				"terms": map[string]interface{}{ // 聚合類型為,terms,terms是桶聚合的一種,類似SQL的group by的作用,根據字段分組,相同字段值的文檔分為一組。
					"field": "name.keyword", // terms聚合類型的參數,這裡需要設定分組的字段為name,根據name分組
				},
			},
		},
		"from": 0,
		"size": 1,
		"sort": []map[string]interface{}{
			{"pubDate": []map[string]interface{}{
				{"order": "desc"},
			},
			},
		},
	}
	marshal, _ := json.Marshal(query)
	t.Log(string(marshal))
	response, err := client.Search(client.Search.WithIndex("book"), client.Search.WithBody(bytes.NewReader(marshal)))
	a.Nil(err)
	t.Log(response)
}
           

count

func TestAggCount(t *testing.T) {
	a := assert.New(t)
	query := map[string]interface{}{
		"aggs": map[string]interface{}{ // 合查詢語句的簡寫
			"count_name": map[string]interface{}{ // 給聚合查詢取個名字,
				"value_count": map[string]interface{}{
					"field": "name.keyword", //
				},
			},
		},
		"from": 0,
		"size": 1,
		"sort": []map[string]interface{}{
			{"pubDate": []map[string]interface{}{
				{"order": "desc"},
			},
			},
		},
	}
	marshal, _ := json.Marshal(query)
	t.Log(string(marshal))
	response, err := client.Search(client.Search.WithIndex("book"), client.Search.WithBody(bytes.NewReader(marshal)))
	a.Nil(err)
	t.Log(response)
}
           

Cardinality 基數聚合,也是用于統計文檔的總數,跟Value Count的差別是,基數聚合會去重,不會統計重複的值,類似SQL的count(DISTINCT 字段)用法。

func TestAggCardinality(t *testing.T) {
	a := assert.New(t)
	query := map[string]interface{}{
		"aggs": map[string]interface{}{ // 合查詢語句的簡寫
			"count_name": map[string]interface{}{ // 給聚合查詢取個名字,
				"cardinality": map[string]interface{}{
					"field": "name.keyword", //
				},
			},
		},
		"from": 0,
		"size": 1,
		"sort": []map[string]interface{}{
			{"pubDate": []map[string]interface{}{
				{"order": "desc"},
			},
			},
		},
	}
	marshal, _ := json.Marshal(query)
	t.Log(string(marshal))
	response, err := client.Search(client.Search.WithIndex("book"), client.Search.WithBody(bytes.NewReader(marshal)))
	a.Nil(err)
	t.Log(response)
}
           

Avg

func TestAggAvg(t *testing.T) {
	a := assert.New(t)
	query := map[string]interface{}{
		"aggs": map[string]interface{}{ // 合查詢語句的簡寫
			"count_name": map[string]interface{}{ // 給聚合查詢取個名字,
				"avg": map[string]interface{}{
					"field": "price", //
				},
			},
		},
		"from": 0,
		"size": 1,
		"sort": []map[string]interface{}{
			{"pubDate": []map[string]interface{}{
				{"order": "desc"},
			},
			},
		},
	}
	marshal, _ := json.Marshal(query)
	t.Log(string(marshal))
	response, err := client.Search(client.Search.WithIndex("book"), client.Search.WithBody(bytes.NewReader(marshal)))
	a.Nil(err)
	t.Log(response)
}
           

sum

func TestAggSum(t *testing.T) {
	a := assert.New(t)
	query := map[string]interface{}{
		"aggs": map[string]interface{}{ // 合查詢語句的簡寫
			"count_name": map[string]interface{}{ // 給聚合查詢取個名字,
				"sum": map[string]interface{}{
					"field": "price", //
				},
			},
		},
		"from": 0,
		"size": 1,
		"sort": []map[string]interface{}{
			{"pubDate": []map[string]interface{}{
				{"order": "desc"},
			},
			},
		},
	}
	marshal, _ := json.Marshal(query)
	t.Log(string(marshal))
	response, err := client.Search(client.Search.WithIndex("book"), client.Search.WithBody(bytes.NewReader(marshal)))
	a.Nil(err)
	t.Log(response)
}
           

Max

func TestAggMax(t *testing.T) {
	a := assert.New(t)
	query := map[string]interface{}{
		"aggs": map[string]interface{}{ // 合查詢語句的簡寫
			"count_name": map[string]interface{}{ // 給聚合查詢取個名字,
				"max": map[string]interface{}{
					"field": "price", //
				},
			},
		},
		"from": 0,
		"size": 1,
		"sort": []map[string]interface{}{
			{"pubDate": []map[string]interface{}{
				{"order": "desc"},
			},
			},
		},
	}
	marshal, _ := json.Marshal(query)
	t.Log(string(marshal))
	response, err := client.Search(client.Search.WithIndex("book"), client.Search.WithBody(bytes.NewReader(marshal)))
	a.Nil(err)
	t.Log(response)
}
           

Min

func TestAggMin(t *testing.T) {
	a := assert.New(t)
	query := map[string]interface{}{
		"aggs": map[string]interface{}{ // 合查詢語句的簡寫
			"count_name": map[string]interface{}{ // 給聚合查詢取個名字,
				"min": map[string]interface{}{
					"field": "price", //
				},
			},
		},
		"from": 0,
		"size": 1,
		"sort": []map[string]interface{}{
			{"pubDate": []map[string]interface{}{
				{"order": "desc"},
			},
			},
		},
	}
	marshal, _ := json.Marshal(query)
	t.Log(string(marshal))
	response, err := client.Search(client.Search.WithIndex("book"), client.Search.WithBody(bytes.NewReader(marshal)))
	a.Nil(err)
	t.Log(response)
}
           

綜合

func TestAgg(t *testing.T) {
	a := assert.New(t)
	query := map[string]interface{}{
		"aggs": map[string]interface{}{ // 合查詢語句的簡寫
			"count_name": map[string]interface{}{ // 給聚合查詢取個名字,
				"min": map[string]interface{}{
					"field": "price",
				},
			},
			"count_name1": map[string]interface{}{
				"value_count": map[string]interface{}{
					"field": "name.keyword", //
				},
			},
		},
		"from": 0,
		"size": 1,
		"sort": []map[string]interface{}{
			{"pubDate": []map[string]interface{}{
				{"order": "desc"},
			},
			},
		},
	}
	marshal, _ := json.Marshal(query)
	t.Log(string(marshal))
	response, err := client.Search(client.Search.WithIndex("book"), client.Search.WithBody(bytes.NewReader(marshal)))
	a.Nil(err)
	t.Log(response)
}
           

// Terms聚合 terms聚合的作用跟SQL中group by作用一樣,都是根據字段唯一值對資料進行分組(分桶),字段值相等的文檔都分到同一個桶内。select price, count(*) from book group by price

func TestAggTerms(t *testing.T) {
	a := assert.New(t)
	query := map[string]interface{}{
		"aggs": map[string]interface{}{ // 合查詢語句的簡寫
			"count_name": map[string]interface{}{ // 給聚合查詢取個名字,
				"terms": map[string]interface{}{
					"field": "price",
				},
			},
		},
		"from": 0,
		"size": 1,
		"sort": []map[string]interface{}{
			{"pubDate": []map[string]interface{}{
				{"order": "desc"},
			},
			},
		},
	}
	marshal, _ := json.Marshal(query)
	t.Log(string(marshal))
	response, err := client.Search(client.Search.WithIndex("book"), client.Search.WithBody(bytes.NewReader(marshal)))
	a.Nil(err)
	t.Log(response)
}
           

Histogram聚合

func TestAggHistogram(t *testing.T) {
	a := assert.New(t)
	query := map[string]interface{}{
		"aggs": map[string]interface{}{ // 合查詢語句的簡寫
			"count_name": map[string]interface{}{ // 給聚合查詢取個名字,
				"histogram": map[string]interface{}{
					"field":    "price",
					"interval": 50, // 分桶的間隔為50,意思就是price字段值按50間隔分組
				},
			},
		},
		"from": 0,
		"size": 1,
		"sort": []map[string]interface{}{
			{"pubDate": []map[string]interface{}{
				{"order": "desc"},
			},
			},
		},
	}
	marshal, _ := json.Marshal(query)
	t.Log(string(marshal))
	response, err := client.Search(client.Search.WithIndex("book"), client.Search.WithBody(bytes.NewReader(marshal)))
	a.Nil(err)
	t.Log(response)
}
           

Date histogram

func TestAggDateHistogram(t *testing.T) {
	a := assert.New(t)
	query := map[string]interface{}{
		"aggs": map[string]interface{}{ // 合查詢語句的簡寫
			"count_name": map[string]interface{}{ // 給聚合查詢取個名字,
				"date_histogram": map[string]interface{}{
					"field":             "pubDate",    // 根據date字段分組
					"calendar_interval": "month",      // 分組間隔:month代表每月、支援minute(每分鐘)、hour(每小時)、day(每天)、week(每周)、year(每年)
					"format":            "yyyy-MM-dd", // 設定傳回結果中桶key的時間格式
				},
			},
		},
		"from": 0,
		"size": 1,
		"sort": []map[string]interface{}{
			{"pubDate": []map[string]interface{}{
				{"order": "desc"},
			},
			},
		},
	}
	marshal, _ := json.Marshal(query)
	t.Log(string(marshal))
	response, err := client.Search(client.Search.WithIndex("book"), client.Search.WithBody(bytes.NewReader(marshal)))
	a.Nil(err)
	t.Log(response)
}
           

Range

func TestAggRange(t *testing.T) {
	a := assert.New(t)
	query := map[string]interface{}{
		"aggs": map[string]interface{}{ // 合查詢語句的簡寫
			"count_name": map[string]interface{}{ // 給聚合查詢取個名字,
				"range": map[string]interface{}{
					"field": "price",
					"ranges": []interface{}{ // 範圍配置
						map[string]float64{"to": 100.0},                // 意思就是 price <= 100的文檔歸類到一個桶
						map[string]float64{"from": 100.0, "to": 200.0}, // price>100 and price<200的文檔歸類到一個桶
						map[string]float64{"from": 200.0},              // price>200的文檔歸類到一個桶},
					},
				},
			}},
		"from": 0,
		"size": 1,
		"sort": []map[string]interface{}{
			{"pubDate": []map[string]interface{}{
				{"order": "desc"},
			},
			},
		},
	}
	marshal, _ := json.Marshal(query)
	t.Log(string(marshal))
	response, err := client.Search(client.Search.WithIndex("book"), client.Search.WithBody(bytes.NewReader(marshal)))
	a.Nil(err)
	t.Log(response)
}
           

綜合案例

func TestAggs(t *testing.T) {
	a := assert.New(t)
	query := map[string]interface{}{
		"aggs": map[string]interface{}{ // 合查詢語句的簡寫
			"count_name1": map[string]interface{}{ // 給聚合查詢取個名字,
				"range": map[string]interface{}{
					"field": "price",
					"ranges": []interface{}{ // 範圍配置
						map[string]float64{"to": 100.0},                // 意思就是 price <= 100的文檔歸類到一個桶
						map[string]float64{"from": 100.0, "to": 200.0}, // price>100 and price<200的文檔歸類到一個桶
						map[string]float64{"from": 200.0},              // price>200的文檔歸類到一個桶},
					},
				},
			},
			"aggs": map[string]interface{}{ // 合查詢語句的簡寫
				"count_name": map[string]interface{}{ // 給聚合查詢取個名字,
					"min": map[string]interface{}{
						"field": "price",
					},
				},
			}},
	}
	marshal, _ := json.Marshal(query)
	t.Log(string(marshal))
	response, err := client.Search(client.Search.WithIndex("book"), client.Search.WithBody(bytes.NewReader(marshal)))
	a.Nil(err)
	t.Log(response)
}
           

繼續閱讀