在 Elasticsearch 中,中文分词和聚合查询是非常常见的功能。以下是如何在 Go 中使用官方客户端库实现这些功能:
中文分词
Elasticsearch 默认支持中文分词器,可以使用 ik_max_word
或 ik_smart
分词器来处理中文字段。在 Go 中,可以通过 mapping
来指定字段的类型和分词器。
import (
"context"
"fmt"
"github.com/elastic/go-elasticsearch/v7"
"github.com/elastic/go-elasticsearch/v7/esapi"
)
func main() {
es, _ := elasticsearch.NewDefaultClient()
var mapping = `
{
"mappings": {
"properties": {
"content": {
"type": "text",
"analyzer": "ik_max_word" // 使用 ik_max_word 分词器
}
}
}
}`
res, err := es.Indices.Create(
[]string{"my-index"},
es.Indices.Create.WithBody(strings.NewReader(mapping)),
es.Indices.Create.WithPretty(),
)
if err != nil {
log.Fatalf("Error creating index: %s", err)
}
}
然后,在执行查询时,可以使用 MatchQuery
或其他查询类型来搜索包含指定关键字的文档。
var buf bytes.Buffer
query := map[string]interface{}{
"query": map[string]interface{}{
"match": map[string]interface{}{
"content": "中国",
},
},
}
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("my-index"),
es.Search.WithBody(&buf),
es.Search.WithTrackTotalHits(true),
es.Search.WithPretty(),
)
if err != nil {
log.Fatalf("Error getting response: %s", err)
}
聚合查询
聚合查询是对搜索结果进行分组、统计和分析的一种功能。在 Go 中,可以使用 Aggregations
和 Bucket
来执行聚合查询。
var buf bytes.Buffer
query := map[string]interface{}{
"size": 0,
"aggs": map[string]interface{}{
"group_by_category": map[string]interface{}{
"terms": map[string]interface{}{
"field": "category",
},
},
"stats_on_price": map[string]interface{}{
"stats": map[string]interface{}{
"field": "price",
},
},
},
}
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("my-index"),
es.Search.WithBody(&buf),
es.Search.WithTrackTotalHits(true),
)
if err != nil {
log.Fatalf("Error getting response: %s", err)
}
defer res.Body.Close()
var r map[string]interface{}
if err := json.NewDecoder(res.Body).Decode(&r); err != nil {
log.Printf("Error parsing the response body: %s", err)
} else {
// 处理聚合结果
groupByCategoryBuckets := r["aggregations"].(map[string]interface{})["group_by_category"].(map[string]interface{})["buckets"].([]interface{})
for _, bucket := range groupByCategoryBuckets {
key := bucket.(map[string]interface{})["key"]
docCount := bucket.(map[string]interface{})["doc_count"]
fmt.Printf("%s: %d\n", key, docCount)
}
statsOnPrice := r["aggregations"].(map[string]interface{})["stats_on_price"].(map[string]interface{})
count := statsOnPrice["count"]
min := statsOnPrice["min"]
max := statsOnPrice["max"]
avg := statsOnPrice["avg"]
sum := statsOnPrice["sum"]
fmt.Printf("count: %v, min: %v, max: %v, avg: %v, sum: %v\n", count, min, max, avg, sum)
}
以上是在 Go 中使用官方 Elasticsearch 客户端库执行中文分词和聚合查询的示例。可以根据具体需求来选择合适的分词器和聚合查询选项。