Skip to main content
Version: 0.13.0

Vector and semantic search

Lucenia provides multiple search methods that go beyond traditional keyword matching to understand the meaning and intent behind queries. These capabilities work together to deliver highly relevant results for AI-powered applications.

Vector search (k-NN)

The k-NN plugin enables nearest-neighbor search across vector fields, finding documents that are semantically similar to a query — even when they don't share the same keywords.

Search modes:

ModeDescriptionUse case
Approximate k-NNUses HNSW or IVF indexes for fast, approximate resultsLarge-scale vector search (millions+ vectors)
Exact k-NNBrute-force scoring via Painless scriptsSmall datasets or when precision is critical
Filtered k-NNPre-filter documents before vector searchCombining metadata filters with semantic search

Performance optimizations:

Query-time embedding

The query embedding search request processor automatically converts text or image queries into vector embeddings at search time — no client-side embedding required. It uses the same embedding providers available for indexing (Bedrock, OpenAI, self-hosted HTTP, Vertex, Azure, Azure Vision) to ensure query vectors are compatible with your indexed vectors.

It embeds the caller's query and substitutes the vector into the ${embedding} placeholder in query_template (mode: template), or into an existing query at embedding_path (mode: path):

PUT _search/pipeline/semantic-search
{
"request_processors": [
{
"query_embedding": {
"model_id": "amazon.titan-embed-text-v2:0",
"provider": "bedrock",
"dimensions": 1024,
"mode": "template",
"query_template": {
"size": 10,
"query": { "knn": { "chunks.embedding": { "vector": ${embedding}, "k": 10 } } }
},
"provider_config": { "region": "us-east-1" }
}
}
]
}

With this pipeline, users send plain text queries and Lucenia handles the embedding transparently. The full parameter table is on the Reranking and grounding page.

A hybrid query combines subqueries (typically BM25 match plus a vector query). Scores are on different scales, so the search pipeline must include a normalization-processor (or the score ranker processor for RRF). How the vector subquery is produced is a separate choice:

Vector sideSearch requestSearch pipeline
Client already has a vectorhybrid with match + knnphase_results_processors: normalization only
Ingest embed providers (http, bedrock, …)ext.query_embedding (plain text); pipeline rewrites a hybrid templaterequest_processors: query_embedding; phase_results_processors: normalization
semantic queryhybrid with match + semanticphase_results_processors: normalization only. Stock nodes only resolve provider: hashing.

The example below is the first row (client-supplied vector). For text-in, Lucenia-embeds, use the query_embedding hybrid example on that processor page.

Combine lexical (BM25) and vector search in a single query:

GET /knowledge-base/_search
{
"query": {
"hybrid": {
"queries": [
{
"match": {
"chunks.text": "geospatial coordinate reference systems"
}
},
{
"knn": {
"chunks.embedding": {
"vector": [0.12, -0.34, ...],
"k": 10
}
}
}
]
}
}
}

Combining the scores

Because the lexical and vector sub-queries produce scores on different scales, a hybrid query is paired with a search pipeline that first normalizes each sub-query's scores and then combines them into a single ranking. Lucenia ships this as two phase-results processors:

  • normalization-processor — normalizes then combines with a weighted technique.
  • score-ranker-processor — combines by Reciprocal Rank Fusion (RRF), which needs no score normalization.
PUT _search/pipeline/hybrid-pipeline
{
"phase_results_processors": [
{
"normalization-processor": {
"normalization": { "technique": "min_max" },
"combination": {
"technique": "arithmetic_mean",
"parameters": { "weights": [0.3, 0.7] }
}
}
}
]
}

Normalization techniques (normalization.technique):

TechniqueNotes
min_maxDefault. Scales each sub-query's scores to [0,1]. Supports optional lower_bounds/upper_bounds with a per-entry mode of apply, clip, or ignore.
l2L2-normalizes each sub-query's score vector.
z_scoreStandardizes scores. Only compatible with arithmetic_mean combination.
rrfRank-based; use with the score ranker processor instead.

Combination techniques (combination.technique):

TechniqueNotes
arithmetic_meanDefault. Weighted arithmetic mean of normalized scores.
geometric_meanWeighted geometric mean.
harmonic_meanWeighted harmonic mean.
rrfReciprocal Rank Fusion (via the score ranker processor).

Key constraints:

  • weights has one entry per sub-query; each must be in [0,1] and they must sum to 1.0 (±0.01).
  • For RRF, rank_constant (default 60, range 110000) sits directly in the combination clause, not under parameters.
  • A hybrid query allows at most 5 sub-queries, and a boost on the hybrid query is rejected.

Search by meaning

The semantic query lets callers send plain text and have Lucenia find the closest matches by meaning — it embeds the text at search time and runs a k-NN search for you, with no client-side embedding. Where match finds documents that contain your words, semantic finds documents that mean the same thing. It also composes with the hybrid query to fuse keyword and meaning in a single request.

For use cases where dense vectors aren't ideal, sparse representations map content to a learned vocabulary of terms with weights, combining the interpretability of keyword search with the semantic awareness of neural models. Sparse encoding models are managed like any other model through the ML Commons plugin.

Model management

All search-time models are managed through the ML Commons plugin, which provides: