golang Elasticsearch查询构建器插件库effdsl的使用
golang Elasticsearch查询构建器插件库effdsl的使用
简介
effdsl是一个用于构建Elasticsearch查询的Go语言库,它提供了简单且功能性的方式来构建查询。
主要特性
- 类型安全的查询构建:通过直观的函数调用避免容易出错的map和原始字符串字面量,增强类型安全、自动完成和编译时验证
- 程序化查询创建:专为直接和精细的查询构建而设计,特别适用于需要以编程方式生成查询的情况
- 全面的查询支持:涵盖大多数复合查询、全文查询和术语级别查询,并易于扩展其他类型
安装
使用Go模块支持,只需添加以下导入:
import "github.com/sdqri/effdsl/v2"
或者运行以下Go命令安装:
go get -u github.com/sdqri/effdsl/v2
使用示例
传统方式
以下是使用原始字符串的传统方式构建简单匹配查询:
import (
es "github.com/elastic/go-elasticsearch/v8"
)
query := `{
"query": {
"match": {
"message": {
"query": "Hello World"
}
}
}
}`
res, err := es.Search(
es.Search.WithBody(strings.NewReader(query)),
)
使用effdsl
以下是使用effdsl构建相同查询的方式:
import (
es "github.com/elastic/go-elasticsearch/v8"
"github.com/sdqri/effdsl/v2"
mq "github.com/sdqri/effdsl/v2/queries/matchquery"
)
query, err := effdsl.Define(
effdsl.WithQuery(
mq.MatchQuery("message", "Hello World"),
),
)
res, err := es.Search(
es.Search.WithBody(strings.NewReader(query)),
)
完整示例
以下是一个更完整的示例,展示如何使用effdsl构建更复杂的查询:
package main
import (
"encoding/json"
"fmt"
"log"
"strings"
"github.com/elastic/go-elasticsearch/v8"
"github.com/sdqri/effdsl/v2"
mq "github.com/sdqri/effdsl/v2/queries/matchquery"
bq "github.com/sdqri/effdsl/v2/queries/boolquery"
tq "github.com/sdqri/effdsl/v2/queries/termquery"
)
func main() {
// 初始化Elasticsearch客户端
cfg := elasticsearch.Config{
Addresses: []string{"http://localhost:9200"},
}
es, err := elasticsearch.NewClient(cfg)
if err != nil {
log.Fatalf("Error creating the client: %s", err)
}
// 使用effdsl构建复杂查询
query, err := effdsl.Define(
effdsl.WithQuery(
bq.BoolQuery(
bq.WithMust(
mq.MatchQuery("title", "Elasticsearch"),
tq.TermQuery("status", "published"),
),
bq.WithFilter(
tq.TermQuery("category", "technology"),
),
bq.WithShould(
mq.MatchQuery("content", "golang"),
mq.MatchQuery("content", "effdsl"),
),
bq.WithMinimumShouldMatch(1),
),
),
effdsl.WithSize(10),
effdsl.WithFrom(0),
effdsl.WithSort("_score", effdsl.SortDesc),
effdsl.WithSort("publish_date", effdsl.SortDesc),
)
if err != nil {
log.Fatalf("Error building query: %s", err)
}
// 打印生成的查询JSON
var prettyJSON bytes.Buffer
err = json.Indent(&prettyJSON, []byte(query), "", " ")
if err != nil {
log.Fatalf("Error formatting JSON: %s", err)
}
fmt.Println("Generated Query:")
fmt.Println(prettyJSON.String())
// 执行查询
res, err := es.Search(
es.Search.WithBody(strings.NewReader(query)),
es.Search.WithPretty(),
)
if err != nil {
log.Fatalf("Error executing search: %s", err)
}
defer res.Body.Close()
// 处理查询结果...
fmt.Println("Search executed successfully")
}
贡献
欢迎贡献!无论是修复错误、添加新功能还是改进文档,您的帮助都是受欢迎的。
许可证
该项目采用MIT许可证。
更多关于golang Elasticsearch查询构建器插件库effdsl的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang Elasticsearch查询构建器插件库effdsl的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Elasticsearch查询构建器插件库effdsl的使用指南
effdsl是一个用于构建Elasticsearch查询的Golang库,它提供了类型安全且流畅的API来构建复杂的ES查询。下面我将详细介绍如何使用这个库。
安装
首先安装effdsl库:
go get github.com/olivere/elastic/v7
go get github.com/mailru/easyjson
go get github.com/effdsl/effdsl
基本查询构建
1. 匹配查询(Match Query)
package main
import (
"fmt"
"github.com/effdsl/effdsl"
)
func main() {
// 构建一个简单的匹配查询
query := effdsl.MatchQuery(
effdsl.Field("title"),
effdsl.Value("Elasticsearch"),
)
fmt.Println(query.JSON()) // 输出JSON格式的查询
}
2. 布尔查询(Bool Query)
func boolQueryExample() {
query := effdsl.BoolQuery(
effdsl.Must(
effdsl.MatchQuery(
effdsl.Field("title"),
effdsl.Value("Elasticsearch"),
),
),
effdsl.Filter(
effdsl.TermQuery(
effdsl.Field("status"),
effdsl.Value("published"),
),
),
effdsl.MustNot(
effdsl.RangeQuery(
effdsl.Field("price"),
effdsl.Lt(100),
),
),
)
fmt.Println(query.JSON())
}
3. 范围查询(Range Query)
func rangeQueryExample() {
query := effdsl.RangeQuery(
effdsl.Field("price"),
effdsl.Gte(100),
effdsl.Lte(1000),
)
fmt.Println(query.JSON())
}
高级查询示例
1. 多条件组合查询
func complexQueryExample() {
query := effdsl.BoolQuery(
effdsl.Must(
effdsl.MatchQuery(
effdsl.Field("title"),
effdsl.Value("Elasticsearch"),
),
effdsl.MatchQuery(
effdsl.Field("description"),
effdsl.Value("search engine"),
),
),
effdsl.Should(
effdsl.TermQuery(
effdsl.Field("tags"),
effdsl.Value("database"),
),
effdsl.TermQuery(
effdsl.Field("tags"),
effdsl.Value("nosql"),
),
),
effdsl.MinimumShouldMatch(1),
effdsl.Filter(
effdsl.RangeQuery(
effdsl.Field("publish_date"),
effdsl.Gte("2022-01-01"),
),
),
)
fmt.Println(query.JSON())
}
2. 聚合查询
func aggregationExample() {
query := effdsl.SearchQuery(
effdsl.Query(
effdsl.MatchAllQuery(),
),
effdsl.Aggregations(
effdsl.TermsAggregation(
effdsl.Name("by_category"),
effdsl.Field("category.keyword"),
effdsl.Size(10),
),
effdsl.AvgAggregation(
effdsl.Name("avg_price"),
effdsl.Field("price"),
),
),
)
fmt.Println(query.JSON())
}
与Elasticsearch客户端集成
package main
import (
"context"
"fmt"
"log"
"github.com/effdsl/effdsl"
"github.com/olivere/elastic/v7"
)
func main() {
// 创建Elasticsearch客户端
client, err := elastic.NewClient(
elastic.SetURL("http://localhost:9200"),
elastic.SetSniff(false),
)
if err != nil {
log.Fatal(err)
}
// 构建查询
query := effdsl.BoolQuery(
effdsl.Must(
effdsl.MatchQuery(
effdsl.Field("title"),
effdsl.Value("Elasticsearch"),
),
),
effdsl.Filter(
effdsl.RangeQuery(
effdsl.Field("price"),
effdsl.Gte(100),
),
),
)
// 执行查询
searchResult, err := client.Search().
Index("products").
Query(query).
Pretty(true).
Do(context.Background())
if err != nil {
log.Fatal(err)
}
// 处理结果
fmt.Printf("查询到 %d 条结果\n", searchResult.TotalHits())
for _, hit := range searchResult.Hits.Hits {
fmt.Printf("ID: %s\n", hit.Id)
}
}
最佳实践
- 链式调用:effdsl支持链式调用,可以使代码更简洁
query := effdsl.BoolQuery().
Must(effdsl.MatchQuery("title", "Elasticsearch")).
Filter(effdsl.RangeQuery("price").Gte(100))
- 复用查询片段:可以创建可复用的查询片段
func publishedFilter() effdsl.Query {
return effdsl.TermQuery("status", "published")
}
func priceRange(min, max int) effdsl.Query {
return effdsl.RangeQuery("price").
Gte(min).
Lte(max)
}
- 使用条件构建:根据条件动态构建查询
func buildQuery(keyword string, minPrice, maxPrice int) effdsl.Query {
bq := effdsl.BoolQuery()
if keyword != "" {
bq.Must(effdsl.MatchQuery("title", keyword))
}
if minPrice > 0 || maxPrice > 0 {
rq := effdsl.RangeQuery("price")
if minPrice > 0 {
rq.Gte(minPrice)
}
if maxPrice > 0 {
rq.Lte(maxPrice)
}
bq.Filter(rq)
}
return bq
}
effdsl提供了类型安全且直观的方式来构建Elasticsearch查询,避免了手动拼接JSON字符串的繁琐和容易出错的问题。通过使用这个库,可以大大提高开发效率和代码的可维护性。