Master Elasticsearch Vector Search: A Step‑by‑Step Neural Search Tutorial

This tutorial walks you through installing Elasticsearch 8.x, generating sentence embeddings with Python, creating a dense_vector index, bulk‑loading documents, and performing both exact and approximate k‑nearest‑neighbor queries using script_score and the built‑in knn API.

dbaplus Community
dbaplus Community
dbaplus Community
Master Elasticsearch Vector Search: A Step‑by‑Step Neural Search Tutorial

Overview

This guide explains how to enable and use vector (neural) search in Elasticsearch 8.x, covering the full end‑to‑end workflow from downloading the server to executing k‑NN queries.

1. Install Elasticsearch

Download Elasticsearch 8.5.3 (or any 8.x release) from the official download page and verify the SHA/ASC signatures. Ensure Java JDK 17+ is installed, then start the node with bin/elasticsearch. Security is disabled for the tutorial by setting xpack.security.enabled: false in elasticsearch.yml and restarting.

2. Generate Embeddings

Use a Python script based on sentence_transformers (model all‑MiniLM‑L6‑v2) to convert raw text into 384‑dimensional dense vectors. The script reads a TSV file of documents, encodes them in batches, and writes the vectors to an output file.

from sentence_transformers import SentenceTransformer
import torch, sys, itertools, time
BATCH_SIZE = 100
MODEL_NAME = 'all-MiniLM-L6-v2'
model = SentenceTransformer(MODEL_NAME)
if torch.cuda.is_available():
    model = model.to('cuda')

def batch_encode_to_vectors(in_path, out_path):
    with open(in_path, 'r') as docs, open(out_path, 'w+') as out:
        for n, lines in enumerate(iter(lambda: tuple(itertools.islice(docs, BATCH_SIZE)), ())):
            vectors = model.encode(lines, show_progress_bar=True)
            for v in vectors:
                out.write(','.join(map(str, v)) + '
')

def main():
    batch_encode_to_vectors(sys.argv[1], sys.argv[2])
if __name__ == '__main__':
    main()

Run the script:

python batch-sentence-transformers.py ./example_input/documents_10k.tsv ./example_output/vector_documents_10k.tsv

3. Create a Dense‑Vector Index

Define an index with a dense_vector field (384 dimensions, indexed, cosine similarity) and two text fields. Example request:

curl -XPUT http://localhost:9200/neural_index -H 'Content-Type: application/json' -d '{
  "mappings": {
    "properties": {
      "general_text_vector": {"type": "dense_vector", "dims": 384, "index": true, "similarity": "cosine"},
      "general_text": {"type": "text"},
      "color": {"type": "text"}
    }
  }
}'

Check the mapping with curl -XGET http://localhost:9200/neural_index.

4. Index Documents

Combine the original text file and the generated vectors, optionally add a random color field, and bulk‑index the data using the Python Elasticsearch client. The script reads both files, builds JSON documents, and sends them in batches of 1 000.

import sys, time, random
from elasticsearch import Elasticsearch
from elasticsearch.helpers import bulk
ELASTIC_ADDRESS = 'http://localhost:9200'
INDEX_NAME = 'neural_index'
BATCH_SIZE = 1000

def index_documents(txt_path, vec_path):
    client = Elasticsearch([ELASTIC_ADDRESS])
    docs = []
    with open(txt_path, 'r') as txt_f, open(vec_path, 'r') as vec_f:
        for i, (doc, vec_str) in enumerate(zip(txt_f, vec_f)):
            vector = [float(v) for v in vec_str.split(',')]
            color = random.choice(['red','green','white','black'])
            docs.append({"_id": str(i), "general_text": doc, "general_text_vector": vector, "color": color})
            if i % BATCH_SIZE == 0 and i != 0:
                bulk(client, docs, index=INDEX_NAME)
                docs = []
        if docs:
            bulk(client, docs, index=INDEX_NAME)
    print('Indexing finished')

if __name__ == '__main__':
    index_documents(sys.argv[1], sys.argv[2])

Run the indexer:

python indexer_elastic.py ./example_input/documents_10k.tsv ./example_output/vector_documents_10k.tsv

5. Search with Vectors

Two query styles are demonstrated:

Exact k‑NN (script_score) : Use a script_score query that computes cosine similarity between a query vector and the stored general_text_vector.

Approximate k‑NN : Use the built‑in knn option (HNSW) with parameters k, num_candidates, and optional filter clauses.

Example exact query:

curl -XPOST http://localhost:9200/neural_index/_search -H 'Content-Type: application/json' -d '{
  "query": {
    "script_score": {
      "query": {"match_all": {}},
      "script": {
        "source": "cosineSimilarity(params.queryVector, 'general_text_vector') + 1.0",
        "params": {"queryVector": [ -0.009, -0.072, ... ]}
      }
    }
  }
}'

Example approximate query with pre‑filter on color:

curl -XPOST http://localhost:9200/neural_index/_search -H 'Content-Type: application/json' -d '{
  "knn": {
    "field": "general_text_vector",
    "query_vector": [ -0.009, -0.072, ... ],
    "k": 3,
    "num_candidates": 10,
    "filter": {"term": {"color": "white"}}
  },
  "_source": false,
  "fields": ["color"]
}'

Mixed queries (text match + knn) are also possible, allowing hybrid relevance scoring.

Limitations and Open Issues

Current dense_vector fields cannot be sorted, aggregated, or used in nested mappings, and have cardinality limits (1024 indexed, 2048 non‑indexed vectors). Ongoing improvements are tracked in the Elasticsearch GitHub issue #84324.

Conclusion

The tutorial demonstrates how to set up neural search in Elasticsearch, generate embeddings with Python, index large document collections, and perform both exact and approximate vector queries. Future work includes multi‑value support, re‑ranking enhancements, and tighter integration with transformer models.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Pythonvector searchkNNDense VectorsNeural Search
dbaplus Community
Written by

dbaplus Community

Enterprise-level professional community for Database, BigData, and AIOps. Daily original articles, weekly online tech talks, monthly offline salons, and quarterly XCOPS&DAMS conferences—delivered by industry experts.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.