es案例
安装环境
如果你的本地没有安装es服务;可以参考如下连接;本次案例采用的是v4版本所有需要修改下版本为elasticsearch:7.8.1
es安装
案例如下
package main
import (
"context"
"encoding/json"
"errors"
"fmt"
"github.com/olivere/elastic/v7"
"reflect"
//"reflect"
"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字段类型
//映射分类
//在 Elasticsearch 中,映射可分为动态映射和静态映射。在关系型数据库中写入数据之前首先要建表,在建表语句中声明字段的属性,在 Elasticsearch 中,则不必如此,
//Elasticsearch 最重要的功能之一就是让你尽可能快地开始探索数据,文档写入 Elasticsearch 中,它会根据字段的类型自动识别,这种机制称为动态映射,
//而静态映射则是写入数据之前对字段的属性进行手工设置。
//静态映射
//静态映射是在创建索引时手工指定索引映射,和 SQL 中在建表语句中指定字段属性类似。相比动态映射,通过静态映射可以添加更详细、更精准的配置信息,例子如下:
const mapping = `{
"mappings":{
"properties":{
"name":{
"type":"text",
"index": true
},
"age":{
"type":"long",
"index": true
},
"married":{
"type":"boolean",
"index": true
},
"created":{
"type":"date",
"index": true
},
"tags":{
"type":"keyword",
"index": true
},
"location":{
"type":"geo_point",
"index": true
},
"suggest_field":{
"type":"completion"
}
}
}
}`
//修改mapping
//我们可以在创建索引时指定mapping信息,也可以为索引增加新的field时指定mapping信息,但是已经存在的field,我们不能修改其mapping,否则会报错,例如:
//我们为music索引增加一个author field,并指定其type为text,analyzer、search_analyzer均为english
const mapping1 = `
{
"properties": {
"sex": {
"type": "text"
}
}
}
}`
var ctx = context.Background()
var esUrl string = "http://127.0.0.1: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 exists {
do, err := client.DeleteIndex("user").Do(ctx)
if nil != err {
panic(err)
}
fmt.Println(do)
exists, err = client.IndexExists("user").Do(ctx)
}
if err != nil {
panic(err)
}
if !exists {
// 如果不存在,就创建,创建一个索引user 并设置它的字段 sex
createIndex, err := client.CreateIndex("user").BodyString(mapping).Do(ctx)
if err != nil {
// Handle error
panic(err)
}
if !createIndex.Acknowledged {
// Not acknowledged ,创建失败
panic(errors.New("创建失败"))
}
}
//为已有的索引添加字段
_, 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("user3 Indexed user %s to index %s, type %s\n", put1.Id, put1.Index, put1.Type) //Indexed user 1 to index user, type _doc
//添加用户2,json字符串形式
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("user3 Indexed user %s to index %s, type %s\n", put2.Id, put2.Index, put2.Type)//Indexed user 4-K2wXIB33YuyEzPYoAi to index user, type _doc
//添加用户3,结构体形式
user3 := User{Name:"mike",Sex:"male",Married:false,Age:35}
put3,err :=client.Index().Index("user").BodyJson(user3).Do(ctx)
if err != nil{
panic(err)
}
fmt.Printf("user3 Indexed user %s to index %s, type %s\n", put3.Id, put3.Index, put3.Type) //Indexed user 3 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
var querys []elastic.Query
termQuery := elastic.NewTermQuery("name", "mike")
querys = append(querys, termQuery)
boolQuery := elastic.NewBoolQuery().Must(querys...)
//开始搜
searchResult, err := client.Search().
Index("user"). // 搜索的索引"user"
//Query(termQuery). // specify the query
Query(boolQuery). // 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 {
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("没有搜到用户")
}
fmt.Println(222)
//最终聚合数据
var data []*User
for _, h := range searchResult.Hits.Hits {
b, err := h.Source.MarshalJSON()
if err != nil {
panic("操作错误")
}
var d User
if err := json.Unmarshal(b, &d); err != nil {
panic("操作错误")
}
data = append(data, &d)
}
fmt.Println(data)
// 更新文档 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)
}
}
本作品采用《CC 协议》,转载必须注明作者和本文链接