Go 操作ElasticSearch

package main

import (
    "bytes"
    "context"
    "encoding/json"
    "fmt"
    "log"
    "os"
    "strconv"
    "strings"
    "time"

    "github.com/elastic/go-elasticsearch/v7"
    elastic "gopkg.in/olivere/elastic.v3"
)

type TypeTweet struct {
    Id       int       `json:"id"`
    User     string    `json:"user"`
    Message  string    `json:"message"`
    Retweets int       `json:"retweets"`
    Tags     []string  `json:"tags"`
    Created  time.Time `json:"created"`
}

func main() {

    ExampleSearchService()

}

type TypeTweetES struct {
    Took int `json:"took"`
    // TimedOut bool   `json:"timed_out"`
    // _shards  Shards `json:"_shards"`
    Hits Hits `json:"hits"`
}

type Shards struct {
    Total      int `json:"total"`
    Successful int `json:"successful"`
    Skipped    int `json:"skipped"`
    Failed     int `json:"failed"`
}

type Hits struct {
    Total Total `json:"total"`
    // max_score string
    Hits []interface{} `json:"hits"`
}

type Total struct {
    Value    int    `json:"value"`
    Relation string `json:"relation"`
}

func ExampleSearchService() {

    // 索引
    index := "twitter"
    url := "http://127.0.0.1:9200"
    tp := "typeTweet" // type

    // 获取本地Elasticsearch实例的客户端。
    // 不要运行嗅探器。
    // 将健康检查间隔设置为10秒。当请求失败时,
    // 重试3次。将错误消息打印到os.Stderr并提供信息
    // 发送到os.Stdout的消息。
    client, err := elastic.NewClient(
        elastic.SetURL(url),
        // elastic.SetBasicAuth("elastic", "123456"),
        elastic.SetSniff(false),
        elastic.SetHealthcheckInterval(10*time.Second),
        // elastic.SetMaxRetries(3), 已弃用
        elastic.SetErrorLog(log.New(os.Stderr, "ELASTIC ", log.LstdFlags)),
        elastic.SetInfoLog(log.New(os.Stdout, "", log.LstdFlags)))
    if err != nil {
        // Handle error
        panic(err)
    }

    fmt.Println("连接成功")

    // 获取ES版本号
    esversion, err := client.ElasticsearchVersion(url)
    if err != nil {
        // Handle error
        panic(err)
    }
    fmt.Printf("版本号: %s", esversion)

    // 检查索引是否存在。
    exists, err := client.IndexExists(index).Do()
    if err != nil {
        // Handle error
        panic(err)
    }
    if !exists {
        fmt.Println("创建索引")
        createIndex, err := client.CreateIndex(index).Do()
        if err != nil {
            // Handle error
            fmt.Println("创建索引失败:")
            panic(err)
        }
        if !createIndex.Acknowledged {
            fmt.Println("创建索引成功")
        }
    } else {
        fmt.Println("索引存在")
    }

    // 删除索引
    // deleteIndex, err := client.DeleteIndex("twitter_test").Do()
    // if err != nil {
    //  // Handle error
    //  fmt.Println("删除索引失败")
    //  panic(err)
    // }
    // if !deleteIndex.Acknowledged {
    //
    // }

    // 保存数据 json
    for i := 1; i < 5; i++ {
        tgas1 := []string{"tag1", "tag2", "tag3"}
        tweet1 := TypeTweet{Id: i, User: "name " + strconv.Itoa(i), Message: "msg " + strconv.Itoa(i), Retweets: 2, Tags: tgas1, Created: time.Now()}
        put1, err := client.Index().
            Index(index).
            Type(tp).
            Id(strconv.Itoa(i)).
            BodyJson(tweet1).
            Do()
        if err != nil {
            // Handle error
            panic(err)
        }
        fmt.Printf("Indexed tweet %s to index %s, type %s\n", put1.Id, put1.Index, put1.Type)
    }

    // 获取索引指定 ID
    get1, err := client.Get().
        Index(index).
        Type(tp).
        Id("2").
        Do()
    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(index).Do()
    if err != nil {
        panic(err)
    }

    // 统计
    count, err := client.Count(index).Do()
    if err != nil {
        panic(err)
    }
    fmt.Println("统计", count)

    // 删除数据
    // res, err := client.Delete().
    //  Index(index).
    //  Type(tp).
    //  Id("1").
    //  Do()
    // if err != nil {
    //  panic(err)
    // }
    // fmt.Println(res)

    //修改数据
    update, err := client.Update().
        Index(index).
        Type(tp).
        Id("2").
        Doc(map[string]interface{}{"user": "name22"}).
        Do()

    fmt.Println(update)

    // //搜索文档
    fmt.Println("搜索")
    // 连接es
    cfg := elasticsearch.Config{
        Addresses: []string{
            url,
        },
        // Username: "foo",
        // Password: "bar",
        // ...
    }

    // 创建客户端
    es, err := elasticsearch.NewClient(cfg)
    if err != nil {
        log.Fatalf("Error creating the client: %s", err)
    }

    res, err := es.Info()
    if err != nil {
        log.Fatalf("Error getting response: %s", err)
    }
    // log.Println(res)

    // 建立请求主体.
    var buf bytes.Buffer
    query := map[string]interface{}{
        "query": map[string]interface{}{
            "match": map[string]interface{}{
                "user": "name 1",
            },
        },
    }
    if err := json.NewEncoder(&buf).Encode(query); err != nil {
        log.Fatalf("Error encoding query: %s", err)
    }

    // 执行搜索请求.
    res, err = es.Search(
        es.Search.WithContext(context.Background()),
        es.Search.WithIndex(index),
        es.Search.WithBody(&buf),
        es.Search.WithTrackTotalHits(true),
        es.Search.WithPretty(),
        //es.Search.WithSize(100), //限制条数最大100条
    )

    if err != nil {
        log.Fatalf("Error getting response: %s", err)
    }
    defer res.Body.Close()

    restr := res.String()

    //去除左边状态字符
    trim_left := strings.Trim(restr, "[200 OK]")
    //去空格
    jsonStr := strings.TrimSpace(trim_left)

    var tweetEs TypeTweetES
    json.Unmarshal([]byte(jsonStr), &tweetEs)
    hits := tweetEs.Hits.Hits
    // fmt.Printf("%T\n", hits)
    for _, v := range hits {
        for k1, v2 := range v.(map[string]interface{}) {
            if k1 == "_source" {
                for k3, v3 := range v2.(map[string]interface{}) {
                    fmt.Println(k3, v3)
                }
            }
        }
    }

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,706评论 4 366
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,002评论 1 301
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,462评论 0 250
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,375评论 0 216
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,763评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,849评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,033评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,768评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,490评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,734评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,204评论 1 264
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,566评论 3 260
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,227评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,137评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,934评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,926评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,774评论 2 274

推荐阅读更多精彩内容