go get github.com/olivere/elastic
package main
import (
"context"
"encoding/json"
"fmt"
"reflect"
"time"
"github.com/olivere/elastic"
)
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:9200
client, err := elastic.NewClient()
if err != nil {
// Handle error
panic(err)
}
//Ping es服务去获取版本号
if err != nil {
// Handle error
panic(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 error
panic(err)
}
fmt.Printf("Elasticsearch version %s\n", esversion)
//使用IndexExists服务检查指定索引是否存在
exists, err := client.IndexExists("twitter").Do(ctx)
if err != nil {
// Handle error
panic(err)
}
if !exists {
// Create a new index.
createIndex, err := client.CreateIndex("twitter").BodyString(mapping).Do(ctx)
if err != nil {
// Handle error
panic(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 error
panic(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 error
panic(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 error
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)
}
//刷新确保文档已经写好
_, 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-9
Pretty(true). // pretty print request and response JSON
Do(ctx) // 执行请求
if err != nil {
// Handle error
panic(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中的type
for _, 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 Tweet
err := json.Unmarshal(*hit.Source, &t)
if err != nil {
// Deserialization failed
}
// Work with tweet
fmt.Printf("Tweet by %s: %s\n", t.User, t.Message)
}
} else {
// No hits
fmt.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 error
panic(err)
}
fmt.Printf("New version of tweet %q is now %d\n", update.Id, update.Version)
//删除一个index
deleteIndex, err := client.DeleteIndex("twitter").Do(ctx)
if err != nil {
// Handle error
panic(err)
}
if !deleteIndex.Acknowledged {
// Not acknowledged
}
}