go调用olivere包操作elasticsearch的常用基本操作
不想看下面啰嗦的直接看官方文档:点这儿
完整示例代码:
package main
import (
"context"
"fmt"
"github.com/olivere/elastic/v7"
"time"
)
type User struct {
Name string `json:"name"`
Age int `json:"age"`
Married bool `json:"married"`
Sex string `json:"sex"`
Created time.Time `json:"created, omitempty"`
Tags []string `json:"tags,omitempty"`
Location string `json:"location,omitempty"`
Suggest *elastic.SuggestField `json:"suggest_field,omitempty"`
}
// 定义一些变量,mapping为定制的index字段类型
const mapping = `
{
"settings":{
"number_of_shards": 1,
"number_of_replicas": 0
},
"mappings":{
"properties":{
"name":{
"type":"text"
},
"age":{
"type":"long"
},
"married":{
"type":"boolean"
},
"created":{
"type":"date"
},
"tags":{
"type":"keyword"
},
"location":{
"type":"geo_point"
},
"suggest_field":{
"type":"completion"
}
}
}
}`
const mapping1 = `
{
"properties": {
"sex": {
"type": "text"
}
}
}
}`
var ctx = context.Background()
var esUrl string = "http://192.168.1.109:9200"
func main() {
//连接客户端
client, err := elastic.NewClient(elastic.SetURL(esUrl), elastic.SetSniff(false))
if err != nil {
// Handle error
panic(err)
}
// Ping the Elasticsearch server to get e.g. the version number
// ping通服务端,并获得服务端的es版本,本实例的es版本为version 7.6.1
info, code, err := client.Ping(esUrl).Do(ctx)
if err != nil {
// Handle error
panic(err)
}
fmt.Printf("Elasticsearch returned with code>: %d and version %s\n", code, info.Version.Number)
// 获取版本号的直接API
esVersion, err := client.ElasticsearchVersion(esUrl)
if err != nil {
panic(err)
}
fmt.Printf("es的版本为%s\n", esVersion)
// 创建index前,先查看es引擎中是否存在自己想要创建的索引index
//exists, err := client.IndexExists("user").Do(ctx)
//if err != nil {
// panic(err)
//}
//if !exists {
// // 如果不存在,就创建
// createIndex, err := client.CreateIndex("user").BodyString(mapping1).Do(ctx)
// if err != nil {
// // Handle error
// panic(err)
// }
// if !createIndex.Acknowledged {
// // Not acknowledged ,创建失败
// }
//}
为已有的索引添加字段
//
//_, err = client.PutMapping().Index("user").BodyString(mapping1).Do(ctx)
//if err != nil {
// fmt.Println(err)
// panic(err)
//}
// 添加文档方法1
//user1 := User{Name:"bob",Sex:"male",Married:false,Age:23}
//put1,err :=client.Index().Index("user").BodyJson(user1).Id("1").Do(ctx)
//if err != nil{
// panic(err)
//}
//fmt.Printf("Indexed user %s to index %s, type %s\n", put1.Id, put1.Index, put1.Type) //Indexed user 1 to index user, type _doc
添加文档方法2
//user2 := `{"name":"mike","sex":"male","married":true,"age":"22"}`
//put2, err := client.Index().Index("user").BodyString(user2).Do(ctx)// 不指定id
//if err != nil{
// panic(err)
//}
//fmt.Printf("Indexed user %s to index %s, type %s\n", put2.Id, put2.Index, put2.Type)//Indexed user 4-K2wXIB33YuyEzPYoAi to index user, type _doc
// 查询
get1, err := client.Get().Index("user").Id("1").Do(ctx)
if err != nil{
panic(err)
}
if get1.Found{
fmt.Printf("Got document %s in version %d from index %s, type %s\n", get1.Id, get1.Version, get1.Index, get1.Type)
// Got document 1 in version 824633838776 from index user, type _doc
}
// Flush to make sure the documents got written.将文档涮入磁盘
//_, err = client.Flush().Index("user").Do(ctx)
//if err != nil {
// panic(err)
//}
// 按"term"搜索Search with a term query
//termQuery := elastic.NewTermQuery("name", "mike")
//searchResult, err := client.Search().
// Index("user"). // 搜索的索引"user"
// Query(termQuery). // specify the query
// Sort("age", true). //按字段"age"排序,升序排列
// From(0).Size(10). // 分页,单页显示10条
// Pretty(true). // pretty print request and response JSON以json的形式返回信息
// Do(ctx) // 执行
//if err != nil {
// // Handle error
// panic(err)
//}
//fmt.Printf("Query took %d milliseconds\n", searchResult.TookInMillis)// Query took 3 milliseconds
//var user User
// Each是一个简便函数,此函数忽略了错误输出
//for _, item1 := range searchResult.Each(reflect.TypeOf(user)) {
// if u, ok := item1.(User); ok {
// fmt.Printf("Person by %s,age:%d,married:%t,Sex:%s\n", u.Name, u.Age, u.Married,u.Sex) //Person by bob,age:23,married:false,Sex:male
// }
//}
// 搜索文档方法2
// 使用hits,获得更详细的输出结果
//if searchResult.Hits.TotalHits.Value >0{
// fmt.Printf("找到的数据总数是 %d \n", searchResult.Hits.TotalHits.Value)
// for _,hits := range searchResult.Hits.Hits{
// u :=User{}
// err := json.Unmarshal([]byte(hits.Source), &u)
// if err != nil{
// fmt.Println("反序列化失败",err)
// }
// fmt.Printf("User by %s,age:%d,married:%t,Sex:%s\n", u.Name, u.Age, u.Married,u.Sex)
// }
//}else {
// fmt.Println("没有搜到用户")
//}
// 更新文档 update
//update, err := client.Update().Index("user").Id("1").
// Script(elastic.NewScriptInline("ctx._source.age += params.num").Lang("painless").Param("num", 1)).
// //Upsert(map[string]interface{}{"created": "2020-06-17"}). // 插入未初始化的字段value
// Do(ctx)
//if err != nil {
// // Handle error
// panic(err)
//}
//fmt.Printf("New version of user %q is now %d\n", update.Id, update.Version)
// 更新方法2
//update,err := client.Update().Index("user").Id("1").
// Script(elastic.NewScriptInline("ctx._source.created=params.date").Lang("painless").Param("date","2020-06-17")).
// Do(ctx)
termQuery := elastic.NewTermQuery("name", "bob")
update,err := client.UpdateByQuery("user").Query(termQuery).
Script(elastic.NewScriptInline("ctx._source.age += params.num").Lang("painless").Param("num", 1)).
Do(ctx)
if err != nil{
panic(err)
}
//fmt.Printf("New version of user %q is now %d\n", update.Id, update.Version)
fmt.Println(update)
// 删除文档
//termQuery := elastic.NewTermQuery("name", "mike")
//_, err = client.DeleteByQuery().Index("user"). // search in index "user"
// Query(termQuery). // specify the query
// Do(ctx)
//if err != nil {
// // Handle error
// panic(err)
//}
}
CURD拆分解释
一、创建
1、创建客户端
// 说明:如果是本机开启的es服务不需要加setsniff参数,此用例是用docker和局域网内开启的服务
client, err := elastic.NewClient(elastic.SetURL(esUrl), elastic.SetSniff(false))
if err != nil {
// Handle error
panic(err)
2、创建索引
// 创建index前,先查看es引擎中是否存在自己想要创建的索引index
exists, err := client.IndexExists("user").Do(ctx)
if err != nil {
panic(err)
}
if !exists {
// 如果不存在,就创建
createIndex, err := client.CreateIndex("user").BodyString(mapping).Do(ctx)
if err != nil {
// Handle error
panic(err)
}
if !createIndex.Acknowledged {
// Not acknowledged ,创建失败
fmt.println("Not acknowledged")
}
3、创建定制文档字段type
// 前提是创建index的时候,没有执行字段mapping
_, err = client.PutMapping().Index("user").BodyString(mapping1).Do(ctx)
if err != nil {
fmt.Println(err)
panic(err)
}
说明:
// mapping 为url形式的字符串,要用反单引号
mapping = `
{
"settings":{
"number_of_shards": 1,
"number_of_replicas": 0
},
"mappings":{
"properties":{
"name":{
"type":"text"
},
"age":{
"type":"long"
},
"married":{
"type":"boolean"
},
"created":{
"type":"date"
},
"tags":{
"type":"keyword"
},
"location":{
"type":"geo_point"
},
"suggest_field":{
"type":"completion"
}
}
}
}`
mapping1 = `
{
"properties": {
"sex": {
"type": "text"
}
}
}
}`
二、添加文档
两种方式,API分别为BodyJson和BodyString(观察来说,BodyString就是用反引号包裹的es原生语法)
// 添加文档方法1
user1 := User{Name:"bob",Sex:"male",Married:false,Age:23}
put1,err:=client.Index().Index("user").BodyJson(user1).Id("1").Do(ctx)
if err != nil{
panic(err)
}
fmt.Printf("Indexed user %s to index %s, type %s\n", put1.Id, put1.Index, put1.Type) //Indexed user 1 to index user, type _doc
// 添加文档方法2
user2 := `{"name":"mike","sex":"male","married":true,"age":"22"}`
put2, err := client.Index().Index("user").BodyString(user2).Do(ctx)// 不指定id
if err != nil{
panic(err)
}
fmt.Printf("Indexed user %s to index %s, type
三、查询
// 使用文档id查询
get1, err := client.Get().Index("user").Id("1").Do(ctx)
if err != nil{
panic(err)
}
if get1.Found{
fmt.Printf("Got document %s in version %d from index %s, type %s\n", get1.Id, get1.Version, get1.Index, get1.Type)
// 数据永久化,Flush to make sure the documents got written.将文档涮入磁盘
_, err = client.Flush().Index("user").Do(ctx)
if err != nil {
panic(err)
}
// 按"term"搜索Search with a term query
termQuery := elastic.NewTermQuery("name", "mike")
searchResult, err := client.Search().
Index("user"). // 搜索的索引"user"
Query(termQuery). // specify the query
Sort("age", true). //按字段"age"排序,升序排列
From(0).Size(10). // 分页,单页显示10条
Pretty(true). // pretty print request and response JSON以json的形式返回信息
Do(ctx) // 执行
if err != nil {
// Handle error
panic(err)
}
fmt.Printf("Query took %d milliseconds\n", searchResult.TookInMillis)// Query took 3 milliseconds
var user User
Each是一个简便函数,此函数忽略了错误输出
for _, item1 := range searchResult.Each(reflect.TypeOf(user)) {
if u, ok := item1.(User); ok {
fmt.Printf("Person by %s,age:%d,married:%t,Sex:%s\n", u.Name, u.Age, u.Married,u.Sex) //Person by bob,age:23,married:false,Sex:male
}
}
// 搜索文档方法2
// 使用hits,获得更详细的输出结果
if searchResult.Hits.TotalHits.Value >0{
fmt.Printf("找到的数据总数是 %d \n", searchResult.Hits.TotalHits.Value)
for _,hits := range searchResult.Hits.Hits{
u :=User{}
err := json.Unmarshal([]byte(hits.Source), &u)
if err != nil{
fmt.Println("反序列化失败",err)
}
fmt.Printf("User by %s,age:%d,married:%t,Sex:%s\n", u.Name, u.Age, u.Married,u.Sex)
}
}else {
fmt.Println("没有搜到用户")
}
三、更新文档
// 根据id更新文档 update
update, err := client.Update().Index("user").Id("1").
Script(elastic.NewScriptInline("ctx._source.age += params.num").Lang("painless").Param("num", 1)).
//Upsert(map[string]interface{}{"created": "2020-06-17"}). // 插入未初始化的字段value
Do(ctx)
/*
update,err := client.Update().Index("user").Id("1"). Script(elastic.NewScriptInline("ctx._source.created=params.date").Lang("painless").Param("date","2020-06-17")). Do(ctx)
*/
if err != nil {
// Handle error
panic(err)
}
fmt.Printf("New version of user %q is now %d\n", update.Id, update.Version)
// 根据查出来的结果更新方法2
termQuery := elastic.NewTermQuery("name", "bob")
update,err := client.UpdateByQuery("user").Query(termQuery).
Script(elastic.NewScriptInline("ctx._source.age += params.num").Lang("painless").Param("num", 1)).
Do(ctx)
if err != nil{
panic(err)
}
fmt.Printf("New version of user %q is now %d\n", update.Id, update.Version)
四、删除
// 删除文档
termQuery := elastic.NewTermQuery("name", "mike")
_, err = client.DeleteByQuery().Index("user"). // search in index "user"
Query(termQuery). // specify the query
Do(ctx)
if err != nil {
// Handle error
panic(err)
}
// 按文档id删除
_,err = client.Delete().Index("bob").Id("2").Do(ctx)
if err != nil{
panic(err)
}
// 删除索引
_,err = client.DeleteIndex("user").Do(ctx)
if err != nil{
panic(err)
}