返回

Elasticsearch操作指南:轻松玩转增删改查和复合查询

后端

使用 Go 操作 Elasticsearch:轻松实现数据管理

简介

Elasticsearch 是一款强大的分布式搜索引擎,它可以高效存储、搜索和分析大规模数据。Go 是一种简洁且高效的编程语言,非常适合用作 Elasticsearch 客户端。本文将全面介绍如何使用 Go 操作 Elasticsearch,涵盖从基本操作到高级查询和高亮显示。

准备工作

在开始之前,你需要准备以下内容:

  • 安装 Go 语言环境
  • 安装 Elasticsearch
  • 创建 Elasticsearch 客户端

单条数据的增删改查

新增数据

type Product struct {
    ID          string  `json:"id"`
    Name        string  `json:"name"`
    Description string  `json:"description"`
    Price       float64 `json:"price"`
}

client.Index().
    Index("products").
    Type("_doc").
    Id("1").
    BodyJson(Product{
        ID:          "1",
        Name:        "iPhone X",
        Description: "The latest iPhone from Apple",
        Price:       999.99,
    }).
    Do(ctx)

删除数据

client.Delete().
    Index("products").
    Type("_doc").
    Id("1").
    Do(ctx)

更新数据

client.Update().
    Index("products").
    Type("_doc").
    Id("1").
    Doc(map[string]interface{}{
        "name":        "iPhone XS",
        "description": "The latest and greatest iPhone from Apple",
        "price":       1099.99,
    }).
    Do(ctx)

查询数据

result, err := client.Get().
    Index("products").
    Type("_doc").
    Id("1").
    Do(ctx)
if err != nil {
    // Handle error
}

var product Product
err = json.Unmarshal(result.Source, &product)
if err != nil {
    // Handle error
}

fmt.Println(product)

多条数据的增删改查

批量新增数据

var products []Product
products = append(products, Product{
    ID:          "2",
    Name:        "iPad Pro",
    Description: "The latest iPad from Apple",
    Price:       799.99,
})
products = append(products, Product{
    ID:          "3",
    Name:        "MacBook Pro",
    Description: "The latest MacBook from Apple",
    Price:       1299.99,
})

bulk := client.Bulk()
for _, product := range products {
    req := elastic.NewBulkIndexRequest().
        Index("products").
        Type("_doc").
        Id(product.ID).
        Doc(product)
    bulk.Add(req)
}

bulk.Do(ctx)

批量删除数据

var ids []string
ids = append(ids, "2")
ids = append(ids, "3")

bulk := client.Bulk()
for _, id := range ids {
    req := elastic.NewBulkDeleteRequest().
        Index("products").
        Type("_doc").
        Id(id)
    bulk.Add(req)
}

bulk.Do(ctx)

批量更新数据

var products []Product
products = append(products, Product{
    ID:          "2",
    Name:        "iPad Air",
    Description: "The latest iPad from Apple",
    Price:       599.99,
})
products = append(products, Product{
    ID:          "3",
    Name:        "MacBook Air",
    Description: "The latest MacBook from Apple",
    Price:       999.99,
})

bulk := client.Bulk()
for _, product := range products {
    req := elastic.NewBulkUpdateRequest().
        Index("products").
        Type("_doc").
        Id(product.ID).
        DocAsUpsert(true).
        Doc(product)
    bulk.Add(req)
}

bulk.Do(ctx)

批量查询数据

var ids []string
ids = append(ids, "2")
ids = append(ids, "3")

result, err := client.MultiGet().
    Add("products", "_doc", ids...).
    Do(ctx)
if err != nil {
    // Handle error
}

for _, hit := range result.Docs {
    var product Product
    err = json.Unmarshal(hit.Source, &product)
    if err != nil {
        // Handle error
    }

    fmt.Println(product)
}

复合查询

布尔查询

query := elastic.NewBoolQuery().
    Must(elastic.NewTermQuery("name", "iPhone")).
    MustNot(elastic.NewTermQuery("price", "999.99")).
    Should(elastic.NewTermQuery("description", "latest")).
    MinimumNumberShouldMatch(1)

范围查询

query := elastic.NewRangeQuery("price").
    Gte(500).
    Lte(1000)

正则表达式查询

query := elastic.NewRegexpQuery("name", "iP.*")

模糊查询

query := elastic.NewFuzzyQuery("name", "iPhone")

评分查询

BM25

query := elastic.NewFunctionScoreQuery().
    Query(elastic.NewMatchQuery("name", "iPhone")).
    AddScoreFunc(elastic.NewBM25ScoreFunction().
        Field("name").
        Boost(1.5)).
    AddScoreFunc(elastic.NewBM25ScoreFunction().
        Field("description").
        Boost(1.0))

TF-IDF

query := elastic.NewFunctionScoreQuery().
    Query(elastic.NewMatchQuery("name", "iPhone")).
    AddScoreFunc(elastic.NewTFIDFScoreFunction().
        Field("name").
        Boost(1.5)).
    AddScoreFunc(elastic.NewTFIDFScoreFunction().
        Field("description").
        Boost(1.0))

More Like This

query := elastic.NewMoreLikeThisQuery().
    Field("name").
    LikeText("iPhone")

高亮显示

highlight := elastic.NewHighlight().
    PreTags("<mark>").
    PostTags("</mark>").
    Fields("name", "description")

result, err := client.Search().
    Index("products").
    Query(query).
    Highlight(highlight).
    Do(ctx)
if err != nil {
    // Handle error
}

for _, hit := range result.Hits.Hits {
    fmt.Println(hit.Highlight["name"][0])
    fmt.Println(hit.Highlight["description"][0])
}

常见问题解答

1. 如何连接到远程 Elasticsearch 集群?

  • 使用 elastic.SetSniff(true) 启用自动嗅探功能。

2. 如何处理错误?

  • 使用 defer func() { if r := recover(); r != nil { ... } }() 捕获 panic 错误。

3. 如何分页查询结果?

  • 使用 From()Size() 函数。

4. 如何使用聚合函数?

  • 使用 elastic.NewAggregation() 创建聚合。

5. 如何使用排序?

  • 使用 elastic.NewFieldSort() 创建排序。

总结

本文介绍了使用 Go 操作 Elasticsearch 的基础知识和高级技术,包括增删改查、复合查询、评分查询和高亮显示。通过掌握这些技巧,你可以轻松高效地管理 Elasticsearch 数据,为你的应用程序提供强大的搜索和分析能力。