go es实例
1、下载第三方库
go get github.com/olivere/elastic
下载过程中出现如下报错:
解决方案:
2、示例
- import
package mainimport ("context""encoding/json""fmt""reflect""time""github.com/olivere/elastic"
)
- es中用于序列化/反序列化数据的结构
json中字段若有omitempty标记,则这个字段为空时,json序列化为string时不会包含该字段。
type Tweet struct {User string `json:"user"`Message string `json:"message"`Retweets int `json:"retweets"`Image string `json:"image,omitempty"`Created time.Time `json:"created,omitempty"`Tags []string `json:"tags,omitempty"`Location string `json:"location,omitempty"`Suggest *elastic.SuggestField `json:"suggest_field,omitempty"`
}
const mapping = `
{"settings":{"number_of_shards": 1,"number_of_replicas": 0},"mappings":{"tweet":{"properties":{"user":{"type":"keyword"},"message":{"type":"text","store": true,"fielddata": true},"image":{"type":"keyword"},"created":{"type":"date"},"tags":{"type":"keyword"},"location":{"type":"geo_point"},"suggest_field":{"type":"completion"}}}}
}`
func main(){//从elastic.v5开始,必须传递ctx上下文来执行每个服务ctx := context.Background()//获取客户端连接到es默认安装地址127.0.0.1:9200client, err := elastic.NewClient()if err != nil {// Handle errorpanic(err)}//Ping es服务去获取版本号if err != nil {// Handle errorpanic(err)}fmt.Printf("Elasticsearch returned with code %d and version %s\n", code, info.Version.Number)//获取es版本号的快捷方式esversion, err := client.ElasticsearchVersion("http://127.0.0.1:9200")if err != nil {// Handle errorpanic(err)}fmt.Printf("Elasticsearch version %s\n", esversion)//使用IndexExists服务检查指定索引是否存在exists, err := client.IndexExists("twitter").Do(ctx)if err != nil {// Handle errorpanic(err)}if !exists {// Create a new index.createIndex, err := client.CreateIndex("twitter").BodyString(mapping).Do(ctx)if err != nil {// Handle errorpanic(err)}if !createIndex.Acknowledged {// Not acknowledged}}//索引tweet(使用JSON序列化)tweet1 := Tweet{User: "olivere", Message: "Take Five", Retweets: 0}put1, err := client.Index().Index("twitter").Type("tweet").Id("1").BodyJson(tweet1).Do(ctx)if err != nil {// Handle errorpanic(err)}fmt.Printf("Indexed tweet %s to index %s, type %s\n", put1.Id, put1.Index, put1.Type)//索引第二条推文(按字符串)tweet2 := `{"user" : "olivere", "message" : "It's a Raggy Waltz"}`put2, err := client.Index().Index("twitter").Type("tweet").Id("2").BodyString(tweet2).Do(ctx)if err != nil {// Handle errorpanic(err)}fmt.Printf("Indexed tweet %s to index %s, type %s\n", put2.Id, put2.Index, put2.Type)//通过指定ID获取推文get1, err := client.Get().Index("twitter").Type("tweet").Id("1").Do(ctx)if err != nil {// Handle errorpanic(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)}//刷新确保文档已经写好_, err = client.Flush().Index("twitter").Do(ctx)if err != nil {panic(err)}//使用term查询语句进行搜索termQuery := elastic.NewTermQuery("user", "olivere")searchResult, err := client.Search().Index("twitter"). // 在索引"twitter"中搜索Query(termQuery). // 指定查询Sort("user", true). // 按"user"字段升序排序From(0).Size(10). // take documents 0-9Pretty(true). // pretty print request and response JSONDo(ctx) // 执行请求if err != nil {// Handle errorpanic(err)}//searchResilt是SearchRusult类型,返回hits、suggestions和所有来自es的其他信息fmt.Printf("Query took %d milliseconds\n", searchResult.TookInMillis)//Each是一个方便的函数,迭代搜索结果中的hits//它确保你不需要去检查响应中的nil值//但是,它忽略序列化中的错误,如果你想完全控制遍历hits,见如下代码:var ttyp Tweet//reflect.TypeOf()用来动态获取输入参数接口中的值的类型,如果接口为空返回nil。实际就是获取interface{}的pair中的typefor _, item := range searchResult.Each(reflect.TypeOf(ttyp)) {if t, ok := item.(Tweet); ok {fmt.Printf("Tweet by %s: %s\n", t.User, t.Message)}}//TotalHits是另一个遍历函数,即使出现问题也能正常工作fmt.Printf("Found a total of %d tweets\n", searchResult.TotalHits())//在完全控制每个步骤的情况下迭代结果if searchResult.Hits.TotalHits > 0 {fmt.Printf("Found a total of %d tweets\n", searchResult.Hits.TotalHits)// 遍历结果for _, hit := range searchResult.Hits.Hits {// hit.Index 包含索引的名称// 反序列化 hit.Source到一个Tweet (也可以只是一个map[string]interface{}).var t Tweeterr := json.Unmarshal(*hit.Source, &t)if err != nil {// Deserialization failed}// Work with tweetfmt.Printf("Tweet by %s: %s\n", t.User, t.Message)}} else {// No hitsfmt.Print("Found no tweets\n")}//通过es的Update API更新tweet//增加retweets的数量update, err := client.Update().Index("twitter").Type("tweet").Id("1").Script(elastic.NewScriptInline("ctx._source.retweets += params.num").Lang("painless").Param("num", 1)).Upsert(map[string]interface{}{"retweets": 0}).Do(ctx)if err != nil {// Handle errorpanic(err)}fmt.Printf("New version of tweet %q is now %d\n", update.Id, update.Version)//删除一个indexdeleteIndex, err := client.DeleteIndex("twitter").Do(ctx)if err != nil {// Handle errorpanic(err)}if !deleteIndex.Acknowledged {// Not acknowledged}
}