Loading

Searching

This page covers how to build and run search queries with the Go client. For the full Elasticsearch search API reference, see the Search API documentation.

As an example, let's search for a document with a field name with a value of Foo in the index named index_name.

query := `{
  "query": {
    "match": {
      "name": { "query": "Foo" }
    }
  }
}`

res, err := client.Search(
    client.Search.WithIndex("index_name"),
    client.Search.WithBody(strings.NewReader(query)),
)
if err != nil {
    log.Fatal(err)
}
defer res.Body.Close()
		
  1. The targeted index for this search.
  2. Pass the JSON query body as an io.Reader.
  3. Always close the response body when done.

With a struct request:

res, err := es.Search().
    Index("index_name").
    Request(&search.Request{
        Query: &types.Query{
            Match: map[string]types.MatchQuery{
                "name": {Query: "Foo"},
            },
        },
    }).Do(context.Background())
		
  1. The targeted index for this search.
  2. The request part of the search.
  3. Match query specifies that name should match Foo.
  4. The query is run with a context.Background and returns the typed response.

It produces the following JSON:

{
  "query": {
    "match": {
      "name": {
        "query": "Foo"
      }
    }
  }
}
		

The esdsl query builders provide a concise, fluent syntax:

import "github.com/elastic/go-elasticsearch/v9/typedapi/esdsl"
		
res, err := es.Search().
    Index("index_name").
    Query(esdsl.NewMatchQuery("name", "Foo")).
    Do(context.Background())
		
  1. The targeted index for this search.
  2. NewMatchQuery takes the field name and query text directly - no struct nesting required.

The typed API models each endpoint's body as a Go Request struct. For example, a simple term query for "Foo" in the name field:

search.Request{
    Query: &types.Query{
        Term: map[string]types.TermQuery{
            "name": {Value: "Foo"},
        },
    },
}
		

If you want to use your own pre-baked JSON queries using templates or a specific encoder, you can pass the body directly. Both API styles support raw JSON payloads:

res, err := client.Search(
    client.Search.WithIndex("index_name"),
    client.Search.WithBody(strings.NewReader(`{
      "query": {
        "term": {
          "user.id": {
            "value": "kimchy",
            "boost": 1.0
          }
        }
      }
    }`)),
)
if err != nil {
    log.Fatal(err)
}
defer res.Body.Close()
		
res, err := es.Search().
    Index("index_name").
    Raw([]byte(`{
      "query": {
        "term": {
          "user.id": {
            "value": "kimchy",
            "boost": 1.0
          }
        }
      }
    }`)).Do(context.Background())
		

No further validation or serialization is done on what is sent through this method. Setting a payload with Raw takes precedence over any request structure you may submit before running the query.