Examples
This sections lists a series of frequent use cases that will help you start with this new API.
- Creating an index
- Indexing a document
- Retrieving a document
- Search
- Aggregations
- Indexing dense vectors
This is a work in progress, the documentation will evolve in the future.
For this example on how to create an index, lets create an index named test-index and provide a mapping for the field price which will be an integer. Notice how using the builder for the IntegerNumberProperty will automatically apply the correct value for the type field.
res, err := es.Indices.Create("test-index").
Request(&create.Request{
Mappings: &types.TypeMapping{
Properties: map[string]types.Property{
"price": types.NewIntegerNumberProperty(),
},
},
}).
Do(nil)
The standard way of indexing a document is to provide a struct to the Request method, the standard json/encoder will be run on your structure and the result will be sent to Elasticsearch.
document := struct {
Id int `json:"id"`
Name string `json:"name"`
Price int `json:"price"`
}{
Id: 1,
Name: "Foo",
Price: 10,
}
res, err := es.Index("index_name").
Request(document).
Do(context.Background())
Alternatively, you can use the Raw method and provide the already serialized JSON:
res, err := es.Index("index_name").
Raw([]byte(`{
"id": 1,
"name": "Foo",
"price": 10
}`)).Do(context.Background())
Retrieving a document follows the API as part of the argument of the endpoint. In order you provide the index, the id and then run the query:
res, err := es.Get("index_name", "doc_id").Do(context.Background())
If you do not wish to retrieve the content of the document and want only to check if it exists in your index, we provide the IsSuccess shortcut:
if exists, err := es.Exists("index_name", "doc_id").IsSuccess(nil); exists {
// The document exists !
} else if err != nil {
// Handle error.
}
Result is true if everything succeeds, false if the document doesn’t exist. If an error occurs during the request, you will be granted with a false and the relevant error.
Building a search query can be done with structs or builder. As an example, let’s search for a document with a field name with a value of Foo in the index named index_name.
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())
- The targeted index for this search.
- The request part of the search.
- Match query specifies that
nameshould matchFoo. - The query is run with a
context.Backgroundand returns the response.
It produces the following JSON:
{
"query": {
"match": {
"name": {
"query": "Foo"
}
}
}
}
Given documents with a price field, we run a sum aggregation on index_name:
totalPricesAgg, err := es.Search().
Index("index_name").
Request(
&search.Request{
Size: some.Int(0),
Aggregations: map[string]types.Aggregations{
"total_prices": {
Sum: &types.SumAggregation{
Field: some.String("price"),
},
},
},
},
).Do(context.Background())
- Specifies the index name.
- Sets the size to 0 to retrieve only the result of the aggregation.
- Specifies the field name on which the sum aggregation runs.
- The
SumAggregationis part of theAggregationsmap.
When working with vector embeddings for semantic search or machine learning applications, the typed API provides specialized types for encoding dense vectors that can significantly improve indexing performance.
The types.DenseVectorF32 type automatically encodes []float32 vectors as base64 strings during JSON serialization, reducing payload size and improving indexing speed:
type Document struct {
DocID string `json:"docid"`
Title string `json:"title"`
Emb types.DenseVectorF32 `json:"emb"`
}
document := Document{
DocID: "doc1",
Title: "Example document with vector embedding",
Emb: types.DenseVectorF32{0.1, 0.2, 0.3, 0.4, 0.5},
}
res, err := es.Index("my-vectors").
Request(document).
Do(context.Background())
- Use
types.DenseVectorF32instead of[]float32for vector fields. - Assign float32 slices directly; base64 encoding happens automatically during serialization.
Before indexing documents with vectors, create an index with the appropriate dense vector mapping:
mappings := esdsl.NewTypeMapping().
AddProperty("docid", esdsl.NewKeywordProperty()).
AddProperty("title", esdsl.NewTextProperty()).
AddProperty("emb", esdsl.NewDenseVectorProperty().
Dims(1536).
Index(true).
Similarity(densevectorsimilarity.Cosine))
res, err := es.Indices.
Create("my-vectors").
Mappings(mappings).
Do(context.Background())
- Define the vector field as a
DenseVectorProperty. - Specify the dimensionality of your vectors (e.g., 1536 for OpenAI embeddings).
- Enable indexing to support kNN search capabilities.
- Set the similarity metric:
Cosine,DotProduct, orL2Norm.
Once your vectors are indexed, you can perform k-nearest neighbors (kNN) search to find similar documents:
queryVector := []float32{0.1, 0.2, 0.3, 0.4, 0.5}
res, err := es.Search().
Index("my-vectors").
Request(&search.Request{
Query: esdsl.NewKnnQuery().
Field("emb").
QueryVector(queryVector...).
K(10).
NumCandidates(100).
QueryCaster(),
}).
Do(context.Background())
- Define your query vector (typically from the same embedding model).
- Use
esdsl.NewKnnQuery()to build a kNN query. - Specify which vector field to search.
- Provide the query vector to find similar vectors.
- Return the top 10 nearest neighbors.
- Consider 100 candidates during the search for better accuracy.
Using types.DenseVectorF32 provides significant performance improvements over standard JSON arrays of floats:
- Reduced payload size: Base64 encoding is more compact than JSON number arrays
- Faster parsing: Eliminates JSON number parsing overhead
- Improved indexing speed: Performance gains increase with vector dimensionality and can improve indexing speeds by up to 3x
For best performance, use types.DenseVectorF32 when your vectors are already in []float32 format. If you have pre-encoded bytes, use types.DenseVectorBytes to avoid re-encoding.
If you already have pre-encoded vector bytes from another system, use types.DenseVectorBytes:
type Document struct {
Emb types.DenseVectorBytes `json:"emb"`
}
vectorBytes := []byte{...}
document := Document{
Emb: types.DenseVectorBytes(vectorBytes),
}
res, err := es.Index("my-vectors").
Request(document).
Do(context.Background())
- Use
types.DenseVectorByteswhen you have pre-encoded bytes. - Provide the raw byte representation of your vector data.