golang elastic search操作示例

package main

import (
    "context"
    "encoding/json"
    "fmt"
    "log"
    "time"

    "github.com/olivere/elastic/v7"
)

// 定义一个员工结构体
type Employee struct {
    Firstname string                 `json:"firstname"`
    Lastname  string                 `json:"lastname"`
    Age       int                    `json:"age"`
    About     string                 `json:"about"`
    Interests []string               `json:"interests"`
    Metadata  map[string]interface{} `json:"metadata,omitempty"`
}

func main() {
    // 创建 Elasticsearch 客户端
    client, err := elastic.NewClient(
        elastic.SetURL("http://localhost:9200"),
        elastic.SetSniff(false), // 在生产环境中根据需要设置
        elastic.SetHealthcheck(true),
    )
    if err != nil {
        log.Fatal("创建 Elasticsearch 客户端失败:", err)
    }

    // 检查 Elasticsearch 集群是否可用
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()

    info, code, err := client.Ping("http://localhost:9200").Do(ctx)
    if err != nil {
        log.Fatal("连接 Elasticsearch 集群失败:", err)
    }
    fmt.Printf("Elasticsearch 返回 code: %d, version: %s\n", code, info.Version.Number)

    // 获取 Elasticsearch 版本号
    esversion, err := client.ElasticsearchVersion("http://localhost:9200")
    if err != nil {
        log.Fatal("获取 Elasticsearch 版本失败:", err)
    }
    fmt.Printf("Elasticsearch 版本: %s\n", esversion)

    // 创建索引
    indexName := "employees"
    createIndex(client, indexName)

    // 添加文档
    addDocument(client, indexName)

    // 批量添加文档
    bulkAddDocuments(client, indexName)

    // 查询文档
    searchDocuments(client, indexName)

    // 更新文档
    updateDocument(client, indexName)

    // 删除文档
    deleteDocument(client, indexName)

    // 删除索引
    deleteIndex(client, indexName)
}

// 创建索引
func createIndex(client *elastic.Client, indexName string) {
    ctx := context.Background()

    // 检查索引是否已存在
    exists, err := client.IndexExists(indexName).Do(ctx)
    if err != nil {
        log.Fatal("检查索引存在性失败:", err)
    }
    if exists {
        fmt.Printf("索引 %s 已存在,正在删除...\n", indexName)
        _, err = client.DeleteIndex(indexName).Do(ctx)
        if err != nil {
            log.Fatalln("删除索引失败")
        }
    }

    // 创建新索引
    // 定义索引映射
    mapping := `{
        "settings":{
            "number_of_shards":1,
            "number_of_replicas":0
        },
        "mappings":{
            "properties":{
                "firstname":{
                    "type":"text"
                },
                "lastname":{
                    "type":"text"
                },
                "age":{
                    "type":"integer"
                },
                "about":{
                    "type":"text"
                },
                "interests":{
                    "type":"keyword"
                },
                "metadata":{
                    "type":"object",
                    "dynamic": true
                }
            }
        }
    }`

    createIndex, err := client.CreateIndex(indexName).BodyString(mapping).Do(ctx)
    if err != nil {
        log.Fatal("创建索引失败:", err)
    }
    if !createIndex.Acknowledged {
        log.Fatal("创建索引未被确认")
    }

    fmt.Printf("成功创建索引: %s\n", indexName)
}

// 添加单个文档
func addDocument(client *elastic.Client, indexName string) {
    ctx := context.Background()

    // 创建员工实例
    employee := Employee{
        Firstname: "John",
        Lastname:  "Doe",
        Age:       35,
        About:     "I love to go rock climbing",
        Interests: []string{"sports", "music"},
        Metadata: map[string]interface{}{
            "created_by": "system",
            "timestamp":  time.Now().Unix(),
        },
    }

    // 添加文档
    put, err := client.Index().
        Index(indexName).
        BodyJson(employee).
        Do(ctx)
    if err != nil {
        log.Fatal("添加文档失败:", err)
    }

    fmt.Printf("添加文档成功,ID: %s\n", put.Id)
}

// 批量添加文档
func bulkAddDocuments(client *elastic.Client, indexName string) {
    ctx := context.Background()

    // 创建批量处理服务
    bulkRequest := client.Bulk()

    // 准备批量数据
    employees := []Employee{
        {
            Firstname: "Jane",
            Lastname:  "Smith",
            Age:       32,
            About:     "I like to collect rock albums",
            Interests: []string{"music"},
            Metadata: map[string]interface{}{
                "created_by": "system",
                "timestamp":  time.Now().Unix(),
            },
        },
        {
            Firstname: "Douglas",
            Lastname:  "Home",
            Age:       28,
            About:     "Rock climber and skateboarder",
            Interests: []string{"sports", "extreme"},
            Metadata: map[string]interface{}{
                "created_by": "admin",
                "timestamp":  time.Now().Unix(),
            },
        },
    }

    // 添加到批量请求
    for _, emp := range employees {
        doc := elastic.NewBulkIndexRequest().
            Index(indexName).
            Doc(emp)
        bulkRequest = bulkRequest.Add(doc)
    }

    // 执行批量操作
    bulkResponse, err := bulkRequest.Do(ctx)
    if err != nil {
        log.Fatal("批量添加文档失败:", err)
    }
    if bulkResponse.Errors {
        log.Fatal("批量添加文档出现错误")
    }

    fmt.Printf("批量添加 %d 个文档成功\n", len(employees))
}

// 查询文档
func searchDocuments(client *elastic.Client, indexName string) {
    ctx := context.Background()

    // 简单查询所有文档
    fmt.Println("\n查询所有文档:")
    searchResult, err := client.Search().
        Index(indexName).
        Do(ctx)
    if err != nil {
        log.Fatal("查询文档失败:", err)
    }

    fmt.Printf("查询到 %d 个文档\n", searchResult.TotalHits())

    if searchResult.TotalHits() > 0 {
        for _, hit := range searchResult.Hits.Hits {
            var emp Employee
            err := json.Unmarshal(hit.Source, &emp)
            if err != nil {
                log.Fatal("解析文档失败:", err)
            }
            fmt.Printf("ID: %s, 姓名: %s %s, 年龄: %d\n", hit.Id, emp.Firstname, emp.Lastname, emp.Age)
        }
    }

    // 使用查询条件搜索
    fmt.Println("\n搜索对运动感兴趣的员工:")
    termQuery := elastic.NewTermQuery("interests", "sports")
    searchResult, err = client.Search().
        Index(indexName).
        Query(termQuery).
        Do(ctx)
    if err != nil {
        log.Fatal("条件查询失败:", err)
    }

    fmt.Printf("找到 %d 个对运动感兴趣的员工\n", searchResult.TotalHits())
    for _, hit := range searchResult.Hits.Hits {
        var emp Employee
        err := json.Unmarshal(hit.Source, &emp)
        if err != nil {
            log.Fatal("解析文档失败:", err)
        }
        fmt.Printf("ID: %s, 姓名: %s %s, 兴趣: %v\n", hit.Id, emp.Firstname, emp.Lastname, emp.Interests)
    }
}

// 更新文档
func updateDocument(client *elastic.Client, indexName string) {
    ctx := context.Background()

    // 首先查找一个文档
    searchResult, err := client.Search().
        Index(indexName).
        Size(1).
        Do(ctx)
    if err != nil {
        log.Fatal("查找文档失败:", err)
    }

    if searchResult.TotalHits() > 0 {
        hit := searchResult.Hits.Hits[0]

        // 更新文档
        update, err := client.Update().
            Index(indexName).
            Id(hit.Id).
            Doc(map[string]interface{}{"age": 30}).
            Do(ctx)
        if err != nil {
            log.Fatal("更新文档失败:", err)
        }

        fmt.Printf("更新文档成功,ID: %s, 新版本: %d\n", update.Id, update.Version)
    }
}

// 删除文档
func deleteDocument(client *elastic.Client, indexName string) {
    ctx := context.Background()

    // 查找一个文档进行删除
    searchResult, err := client.Search().
        Index(indexName).
        Size(1).
        Do(ctx)
    if err != nil {
        log.Fatal("查找文档失败:", err)
    }

    if searchResult.TotalHits() > 0 {
        hit := searchResult.Hits.Hits[0]

        // 删除文档
        d, err := client.Delete().
            Index(indexName).
            Id(hit.Id).
            Do(ctx)
        if err != nil {
            log.Fatal("删除文档失败:", err)
        }

        fmt.Printf("删除文档成功,ID: %s\n", d.Id)
    }
}

// 删除索引
func deleteIndex(client *elastic.Client, indexName string) {
    ctx := context.Background()

    // 删除索引
    deleteIndex, err := client.DeleteIndex(indexName).Do(ctx)
    if err != nil {
        log.Fatal("删除索引失败:", err)
    }
    if !deleteIndex.Acknowledged {
        log.Fatal("删除索引未被确认")
    }

    fmt.Printf("成功删除索引: %s\n", indexName)
}

 

posted @ 2025-08-13 10:30  CJTARRR  阅读(9)  评论(0)    收藏  举报