elastic

package
v0.0.0-...-8c930d8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 11, 2026 License: Apache-2.0 Imports: 24 Imported by: 0

README

DSL 语法

Match 查询(全文搜索):

// 基础 match 查询
req := &SearchRequest{
    Query: map[string]any{
        "match": map[string]any{
            "message": "hello world",
        },
    },
}

// match_phrase(短语匹配,要求词序一致)
req := &SearchRequest{
    Query: map[string]any{
        "match_phrase": map[string]any{
            "message": "hello world",
        },
    },
}

// multi_match(多字段匹配)
req := &SearchRequest{
    Query: map[string]any{
        "multi_match": map[string]any{
            "query": "hello world",
            "fields": []string{"message", "title", "content"},
        },
    },
}

Term 查询(精确匹配):

// 单个 term 查询
req := &SearchRequest{
    Query: map[string]any{
        "term": map[string]any{
            "status": "active",
        },
    },
}

// terms 查询(多值匹配)
req := &SearchRequest{
    Query: map[string]any{
        "terms": map[string]any{
            "status": []string{"active", "pending"},
        },
    },
}

Range 查询(范围查询):

req := &SearchRequest{
    Query: map[string]any{
        "range": map[string]any{
            "age": map[string]any{
                "gte": 18,
                "lte": 30,
            },
        },
    },
}

// 日期范围查询
req := &SearchRequest{
    Query: map[string]any{
        "range": map[string]any{
            "created_at": map[string]any{
                "gte": "2024-01-01",
                "lte": "now",
                "format": "yyyy-MM-dd",
            },
        },
    },
}

Bool 查询(组合查询):

req := &SearchRequest{
    Query: map[string]any{
        "bool": map[string]any{
            // must: AND 关系,必须满足
            "must": []map[string]any{
                {
                    "match": map[string]any{
                        "title": "search keyword",
                    },
                },
                {
                    "term": map[string]any{
                        "status": "active",
                    },
                },
            },
            // should: OR 关系,可以满足
            "should": []map[string]any{
                {
                    "term": map[string]any{
                        "tag": "important",
                    },
                },
            },
            // must_not: NOT 关系,必须不满足
            "must_not": []map[string]any{
                {
                    "term": map[string]any{
                        "status": "deleted",
                    },
                },
            },
            // filter: 过滤,不计算相关性得分
            "filter": []map[string]any{
                {
                    "range": map[string]any{
                        "created_at": map[string]any{
                            "gte": "2024-01-01",
                        },
                    },
                },
            },
        },
    },
}

嵌套查询(Nested Query):

req := &SearchRequest{
    Query: map[string]any{
        "nested": map[string]any{
            "path": "comments",
            "query": map[string]any{
                "bool": map[string]any{
                    "must": []map[string]any{
                        {
                            "match": map[string]any{
                                "comments.text": "great",
                            },
                        },
                    },
                },
            },
        },
    },
}

聚合查询(Aggregations):

req := &SearchRequest{
    Size: new(0), // 只要聚合、不要命中时设为 0;不设 Size 就按集群默认返回 10 条
    Query: map[string]any{
        "match_all": map[string]any{},
    },
    Aggs: map[string]any{
        "status_count": map[string]any{
            "terms": map[string]any{
                "field": "status",
            },
        },
        "avg_age": map[string]any{
            "avg": map[string]any{
                "field": "age",
            },
        },
    },
}

排序:

不设 Sort 时按相关度(_score)排序,每条命中带 Score;只有 search_after 必须配 Sort,缺了在发请求前就报错。排序方向只认 asc、desc(大小写都行),字段名不能为空,写错了同样在发请求前报错。

req := &SearchRequest{
    Query: map[string]any{
        "match_all": map[string]any{},
    },
    Sort: []map[string]any{
        {
            "created_at": map[string]any{
                "order": "desc",
            },
        },
        {
            "_score": map[string]any{
                "order": "desc",
            },
        },
    },
}

分页:

req := &SearchRequest{
    Query: map[string]any{
        "match_all": map[string]any{},
    },
    From: 0,       // 起始位置
    Size: new(10), // 每页大小
}

总数:

结果的 Total 要和 TotalRelation 一起读:TotalRelationEq 是准确值;TotalRelationGte 表示集群数到一万就停了,实际至少这么多。要准确总数时在请求里打开 TrackTotalHits:

req := &SearchRequest{
    Query: map[string]any{
        "match_all": map[string]any{},
    },
    TrackTotalHits: true,
}

建议

  1. 对于精确匹配使用 term 查询
  2. 对于全文搜索使用 match 查询
  3. 使用 bool 查询组合多个条件
  4. 使用 filter 进行过滤可以提高性能
  5. 合理使用分页避免深分页问题

示例

// 复杂查询示例
req := &SearchRequest{
    Query: map[string]any{
        "bool": map[string]any{
            "must": []map[string]any{
                {
                    "match": map[string]any{
                        "title": "search keyword",
                    },
                },
            },
            "filter": []map[string]any{
                {
                    "term": map[string]any{
                        "status": "active",
                    },
                },
                {
                    "range": map[string]any{
                        "created_at": map[string]any{
                            "gte": "2024-01-01",
                            "lte": "now",
                        },
                    },
                },
            },
        },
    },
    Sort: []map[string]any{
        {
            "created_at": map[string]any{
                "order": "desc",
            },
        },
    },
    From: 0,
    Size: new(20),
}

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	Document = new(document)
	Index    = new(index)
)

Functions

func Client

func Client() (*elasticsearch.Client, error)

Client returns the initialized Elasticsearch client.

func New

New returns a new Elasticsearch client with given configuration. It's the caller's responsibility to ensure proper usage of the client.

Types

type AggregationOptions

type AggregationOptions struct {
	Field string            `json:"field"`
	Size  *int              `json:"size,omitempty"`
	Order map[string]string `json:"order,omitempty"`
}

AggregationOptions represents options for aggregation query

type AggregationResult

type AggregationResult struct {
	Value    any              `json:"value,omitempty"`     // For metric aggregations
	DocCount int64            `json:"doc_count,omitempty"` // Document count
	Buckets  []map[string]any `json:"buckets,omitempty"`   // For bucket aggregations
}

AggregationResult represents the result of an aggregation. It can contain single value metrics (min, max, avg, sum) or bucket results (terms).

type Documenter

type Documenter interface {
	// Document returns the fields to index, keyed by field name. The values
	// must encode as JSON, and the names should match the index mapping.
	//
	//	return map[string]any{"title": "sample", "tags": []string{"a", "b"}}
	Document() map[string]any

	// GetID returns the id the document is stored under, unique within the
	// index. An empty id leaves it to the cluster, which generates one.
	GetID() string
}

Documenter is a value BulkIndex writes into an index: its fields and the id it is stored under. A model embedding model.Base implements GetID already.

type GetRequest

type GetRequest struct {
	Source []string // fields to return
}

type GetResult

type GetResult struct {
	ID     string         `json:"_id"`
	Found  bool           `json:"found"`
	Source map[string]any `json:"_source,omitempty"`
}

type IndexOption

type IndexOption struct {
	Settings map[string]any
	Mappings map[string]any
}

IndexOption carries the settings and mappings Create gives a new index.

type MatchPhraseOptions

type MatchPhraseOptions struct {
	Query          any      `json:"query"`
	Slop           *int     `json:"slop,omitempty"`
	Analyzer       string   `json:"analyzer,omitempty"`
	ZeroTermsQuery string   `json:"zero_terms_query,omitempty"`
	MaxExpansions  *int     `json:"max_expansions,omitempty"`
	Boost          *float64 `json:"boost,omitempty"`
}

MatchPhraseOptions represents options for match_phrase query

type Order

type Order string
const (
	Asc  Order = "asc"
	Desc Order = "desc"
)

type QueryBuilder

type QueryBuilder struct {
	// contains filtered or unexported fields
}

QueryBuilder helps build Elasticsearch queries. It supports must, must_not, should, filter clauses, pagination, sorting, field filtering, search_after and the total count.

func NewQueryBuilder

func NewQueryBuilder() *QueryBuilder

NewQueryBuilder creates a query builder. Until set, the size, the from and the sort are left to the cluster, see SearchRequest.

func (*QueryBuilder) Aggs

func (qb *QueryBuilder) Aggs(name string, agg map[string]any) *QueryBuilder

Aggs adds a custom aggregation

func (*QueryBuilder) AggsAvg

func (qb *QueryBuilder) AggsAvg(name string, field string) *QueryBuilder

AggsAvg adds an avg aggregation

func (*QueryBuilder) AggsCardinality

func (qb *QueryBuilder) AggsCardinality(name string, field string) *QueryBuilder

AggsCardinality adds a cardinality aggregation

func (*QueryBuilder) AggsMax

func (qb *QueryBuilder) AggsMax(name string, field string) *QueryBuilder

AggsMax adds a max aggregation

func (*QueryBuilder) AggsMin

func (qb *QueryBuilder) AggsMin(name string, field string) *QueryBuilder

AggsMin adds a min aggregation

func (*QueryBuilder) AggsStats

func (qb *QueryBuilder) AggsStats(name string, field string) *QueryBuilder

AggsStats adds a stats aggregation

func (*QueryBuilder) AggsSum

func (qb *QueryBuilder) AggsSum(name string, field string) *QueryBuilder

AggsSum adds a sum aggregation

func (*QueryBuilder) AggsTerm

func (qb *QueryBuilder) AggsTerm(name string, field string, size int, orderBy ...string) *QueryBuilder

AggsTerm adds a terms aggregation. orderBy accepts two parameters: field and order. field can be "_count" or "_key", order can be "asc" or "desc"

func (*QueryBuilder) Bool

func (qb *QueryBuilder) Bool(fn func(qb *QueryBuilder)) *QueryBuilder

Bool adds a nested bool query

func (*QueryBuilder) Build

func (qb *QueryBuilder) Build() (*SearchRequest, error)

Build creates the SearchRequest, refusing one the cluster would, see Validate.

func (*QueryBuilder) BuildQuery

func (qb *QueryBuilder) BuildQuery() map[string]any

BuildQuery creates the query part of SearchRequest

func (*QueryBuilder) Clone

func (qb *QueryBuilder) Clone() *QueryBuilder

Clone returns a builder with the same clauses; clauses added to it leave the original alone.

func (*QueryBuilder) Exists

func (qb *QueryBuilder) Exists(field string) *QueryBuilder

Exists adds an exists query to must clauses

func (*QueryBuilder) Filter

func (qb *QueryBuilder) Filter(query map[string]any) *QueryBuilder

Filter adds a filter clause to the bool query

func (*QueryBuilder) From

func (qb *QueryBuilder) From(from int) *QueryBuilder

From sets the offset of the first hit. A negative from fails Build.

func (*QueryBuilder) Match

func (qb *QueryBuilder) Match(field string, value any) *QueryBuilder

Match adds a match query to must clauses

func (*QueryBuilder) MatchAll

func (qb *QueryBuilder) MatchAll() *QueryBuilder

MatchAll adds a match_all query

func (*QueryBuilder) MatchNot

func (qb *QueryBuilder) MatchNot(field string, value any) *QueryBuilder

MatchNot adds a match query to must_not clauses

func (*QueryBuilder) MatchPhrase

func (qb *QueryBuilder) MatchPhrase(field string, value any) *QueryBuilder

MatchPhrase adds a match_phrase query to must clauses

func (*QueryBuilder) MatchPhraseNot

func (qb *QueryBuilder) MatchPhraseNot(field string, value any) *QueryBuilder

MatchPhraseNot adds a match_phrase query to must_not clauses

func (*QueryBuilder) MatchPhraseOptions

func (qb *QueryBuilder) MatchPhraseOptions(field string, opts MatchPhraseOptions) *QueryBuilder

MatchPhraseOptions adds a match_phrase query with options to must clauses

func (*QueryBuilder) MatchPhraseOptionsNot

func (qb *QueryBuilder) MatchPhraseOptionsNot(field string, opts MatchPhraseOptions) *QueryBuilder

MatchPhraseOptionsNot adds a match_phrase query with options to must_not clauses

func (*QueryBuilder) MatchPhraseOptionsShould

func (qb *QueryBuilder) MatchPhraseOptionsShould(field string, opts MatchPhraseOptions) *QueryBuilder

MatchPhraseOptionsShould adds a match_phrase query with options to should clauses

func (*QueryBuilder) MatchPhraseShould

func (qb *QueryBuilder) MatchPhraseShould(field string, value any) *QueryBuilder

MatchPhraseShould adds a match_phrase query to should clauses

func (*QueryBuilder) MatchShould

func (qb *QueryBuilder) MatchShould(field string, value any) *QueryBuilder

MatchShould adds a match query to should clauses

func (*QueryBuilder) MinimumShouldMatch

func (qb *QueryBuilder) MinimumShouldMatch(minimum any) *QueryBuilder

MinimumShouldMatch sets minimum_should_match for should clauses

func (*QueryBuilder) Must

func (qb *QueryBuilder) Must(query map[string]any) *QueryBuilder

Must adds a must clause to the bool query

func (*QueryBuilder) MustNot

func (qb *QueryBuilder) MustNot(query map[string]any) *QueryBuilder

MustNot adds a must_not clause to the bool query

func (*QueryBuilder) Range

func (qb *QueryBuilder) Range(field string, ranges map[string]any) *QueryBuilder

Range adds a range query to filter clauses

func (*QueryBuilder) SearchAfter

func (qb *QueryBuilder) SearchAfter(value ...any) *QueryBuilder

SearchAfter sets the search_after parameter for deep pagination SearchAfter must be used together with Sort.

func (*QueryBuilder) Should

func (qb *QueryBuilder) Should(query map[string]any) *QueryBuilder

Should adds a should clause to the bool query

func (*QueryBuilder) Size

func (qb *QueryBuilder) Size(size int) *QueryBuilder

Size sets the number of hits to return; zero asks for none, the shape of a request that wants aggregations alone. A negative size fails Build.

func (*QueryBuilder) Sort

func (qb *QueryBuilder) Sort(field string, order Order) *QueryBuilder

Sort adds a sort on field in order, after the sorts added before it. SearchAfter requires at least one. Build refuses an empty field or an order other than Asc or Desc, in any letter case.

func (*QueryBuilder) Source

func (qb *QueryBuilder) Source(fields ...string) *QueryBuilder

Source sets the _source field filtering if fields is empty, all fields will be returned if fields is not empty, only the specified fields will be returned

func (*QueryBuilder) String

func (qb *QueryBuilder) String() string

String returns the JSON representation of the query

func (*QueryBuilder) Term

func (qb *QueryBuilder) Term(field string, value any) *QueryBuilder

Term adds a term query to must clauses

func (*QueryBuilder) TermNot

func (qb *QueryBuilder) TermNot(field string, value any) *QueryBuilder

TermNot adds a term query to must_not clauses

func (*QueryBuilder) TermShould

func (qb *QueryBuilder) TermShould(field string, value any) *QueryBuilder

TermShould adds a term query to should clauses

func (*QueryBuilder) TimeRange

func (qb *QueryBuilder) TimeRange(field string, start, end time.Time) *QueryBuilder

TimeRange adds a time range query with RFC3339 format

func (*QueryBuilder) TimeRangeGte

func (qb *QueryBuilder) TimeRangeGte(field string, tm time.Time) *QueryBuilder

TimeRangeGte adds a time range query with greater than or equal condition

func (*QueryBuilder) TimeRangeLte

func (qb *QueryBuilder) TimeRangeLte(field string, tm time.Time) *QueryBuilder

TimeRangeLte adds a time range query with less than or equal condition

func (*QueryBuilder) TrackTotalHits

func (qb *QueryBuilder) TrackTotalHits() *QueryBuilder

TrackTotalHits asks the cluster to count every hit instead of stopping at ten thousand, see SearchResult.TotalRelation.

func (*QueryBuilder) Validate

func (qb *QueryBuilder) Validate() error

Validate reports what Build would refuse: a negative size or from, a sort on an empty field or in an order other than asc or desc, and search_after without a sort or with a from.

type SearchHit

type SearchHit struct {
	ID     string         `json:"_id"`
	Score  *float64       `json:"_score,omitempty"`
	Source map[string]any `json:"_source"`
}

SearchHit represents a single document in search results. It contains document ID, relevance score and source fields.

type SearchRequest

type SearchRequest struct {
	Query map[string]any `json:"query,omitempty"`
	From  int            `json:"from,omitempty"`
	// Size is the number of hits to return. Zero asks for none, the shape of
	// a request that wants aggregations alone; nil leaves the cluster's
	// default of ten.
	Size        *int             `json:"size,omitempty"`
	Sort        []map[string]any `json:"sort,omitempty"`
	Source      []string         `json:"_source,omitempty"`
	SearchAfter []any            `json:"search_after,omitempty"`
	Aggs        map[string]any   `json:"aggs,omitempty"`
	// TrackTotalHits asks the cluster to count every hit. Without it the
	// cluster stops counting at ten thousand, and SearchResult.TotalRelation
	// says whether it did.
	TrackTotalHits bool `json:"track_total_hits,omitempty"`
}

SearchRequest is an Elasticsearch search body: the query, the page, the sort, the fields to return, search_after for deep pagination and the aggregations. QueryBuilder composes one. What a request leaves unset is left to the cluster, which ranks unsorted hits by relevance and answers ten of them. Search, SearchNext and SearchPrev read a nil request as the empty one.

type SearchResult

type SearchResult struct {
	Total         int64                         `json:"total"`
	TotalRelation TotalRelation                 `json:"total_relation"`
	MaxScore      *float64                      `json:"max_score,omitempty"`
	Hits          []SearchHit                   `json:"hits"`
	Aggregations  map[string]*AggregationResult `json:"aggregations,omitempty"`
}

SearchResult is an Elasticsearch search response: the total with how exact it is, the top score, the hits and the aggregations.

type TotalRelation

type TotalRelation string

TotalRelation says how SearchResult.Total relates to the number of hits.

const (
	// TotalRelationEq means Total is the number of hits.
	TotalRelationEq TotalRelation = "eq"
	// TotalRelationGte means at least Total hits matched: the cluster
	// stopped counting at its threshold of ten thousand. A request with
	// TrackTotalHits gets the exact count.
	TotalRelationGte TotalRelation = "gte"
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL
⌂ 换网址