VelesQL Syntax for Filtering Data Based on Vector Similarity: A Complete Guide
VelesQL filters vector similarity using the similarity(<vector_field>, $query_vector) <operator> <threshold> predicate in WHERE clauses, automatically triggering HNSW index searches when the query handler detects the condition.
VelesDB is an open-source vector database that treats semantic search as a first-class operation. The VelesQL syntax for filtering data based on vector similarity allows developers to combine approximate nearest neighbor (ANN) searches with traditional metadata filters using familiar SQL-like patterns. This integration enables high-performance retrieval across embeddings while maintaining compatibility with structured query constraints.
Basic VelesQL Similarity Filter Syntax
The core predicate follows a strict function signature that the parser recognizes as a SimilarityCondition. In crates/velesdb-core/src/velesql/ast/condition.rs (lines 19-22), the AST defines this structure to handle vector comparisons separately from standard scalar filters.
The complete syntax structure is:
SELECT *
FROM <collection>
WHERE similarity(<vector_field>, $query_vector) <operator> <threshold>
The components work as follows:
<vector_field>– The column storing embeddings (e.g.,embedding,image_vector).$query_vector– A bound parameter containing the query embedding passed in the request payload.<operator>– One of>,<,>=,<=,=. Interpretation depends on the configured distance metric (e.g., cosine similarity uses>for closer matches, while euclidean distance uses<for nearer vectors).<threshold>– A numeric cutoff (0-1 range for cosine and dot-product, raw distance values for euclidean).
When this predicate appears, VelesDB automatically performs an ANN (HNSW) search, scoring each candidate with the selected metric and returning only rows satisfying the threshold.
How VelesDB Executes Similarity Queries
The execution path begins in crates/velesdb-server/src/handlers/query.rs, where the condition_has_vector_search function (lines 36-44) inspects the parsed AST. If a similarity predicate is detected, the handler routes the query to the vector-search execution path rather than executing a full table scan.
This routing triggers the following sequence:
- The parser in
crates/velesdb-core/src/velesql/parser/conditions.rs(lines 207-211) tokenizessimilarity(<field>, $vec) <op> <num>into the AST. - The validator in
crates/velesdb-core/src/velesql/validation.rs(lines 46-68) enforces semantic rules, ensuring only one similarity clause exists per query. - The execution engine performs an HNSW index search, applying the threshold filter during the graph traversal to minimize distance calculations.
Practical VelesQL Query Examples
SQL-Style Similarity Filters
The most common pattern filters a single collection by embedding similarity:
SELECT *
FROM articles
WHERE similarity(embedding, $query_vec) > 0.75
LIMIT 20;
In this example, $query_vec is supplied via the request JSON payload as "params": {"query_vec": [0.1, 0.2, ...]}.
Graph Queries with MATCH
VelesQL extends Cypher-like MATCH syntax to support vector similarity within graph traversals:
MATCH (doc:Document)-[:TAGGED_WITH]->(tag:Tag)
WHERE similarity(doc.embedding, $q) > 0.8
RETURN doc.title, tag.name, similarity() AS relevance
ORDER BY relevance DESC
LIMIT 5;
Note the use of bare similarity() in the RETURN and ORDER BY clauses, which references the score computed in the WHERE predicate.
Combining Similarity with Metadata Filters
You can combine vector predicates with standard SQL filters for hybrid search:
SELECT id, title, price
FROM products
WHERE similarity(embedding, $vec) > 0.6
AND category = 'electronics'
AND price BETWEEN 20 AND 150
ORDER BY similarity(embedding, $vec) DESC
LIMIT 10;
As implemented in the examples/mini_recommender/main.rs example (lines 165-173), this pattern first filters by metadata to reduce the HNSW search space, then ranks the remaining candidates by vector similarity.
SDK and HTTP API Usage
Raw HTTP Endpoint
Send parameterized queries to the /query endpoint:
curl -X POST http://localhost:8080/query \
-H "Content-Type: application/json" \
-d '{
"query": "SELECT * FROM docs WHERE similarity(embedding, $v) > 0.8 LIMIT 10",
"params": {"v": [0.12, 0.45, -0.33, 0.89]}
}'
The server parses the similarity() predicate, executes the ANN search on the HNSW index, and returns matching rows with a score field containing the computed similarity value.
TypeScript SDK
According to the TypeScript SDK documentation in sdks/typescript/README.md (lines 307-313), you can parameterize queries programmatically:
import { VelesDBClient } from '@wiscale/velesdb';
const client = new VelesDBClient({ baseUrl: 'http://localhost:8080' });
const query = `
SELECT * FROM docs
WHERE similarity(embedding, $vec) > 0.7
ORDER BY similarity(embedding, $vec) DESC
LIMIT 5
`;
const result = await client.query(query, { vec: myEmbedding });
console.log(result.results); // Contains id, score, and payload fields
Validation Rules and Constraints
The query planner enforces strict constraints to ensure deterministic vector search behavior. In crates/velesdb-core/src/velesql/validation.rs (lines 46-68), the validator rejects queries containing more than one similarity() predicate. This restriction prevents ambiguous routing decisions when multiple vector fields or query vectors might conflict during HNSW index traversal.
Additionally, the parser requires that the second argument to similarity() be a bound parameter ($variable) rather than a literal vector, ensuring consistent query planning and parameter sanitization.
Summary
- VelesQL treats
similarity(<field>, $vector)as a first-class predicate compatible with SQL-style SELECT and graph MATCH queries. - The query handler in
crates/velesdb-server/src/handlers/query.rsautomatically detects similarity conditions and routes to HNSW index search viacondition_has_vector_search. - Threshold operators (
>,<,>=,<=,=) filter results based on the configured distance metric (cosine, euclidean, or dot-product). - Hybrid filtering combines vector similarity with standard WHERE clauses for metadata, enabling efficient pre-filtering before ANN search.
- Validation rules restrict queries to a single similarity predicate per statement, enforced in
crates/velesdb-core/src/velesql/validation.rs.
Frequently Asked Questions
What comparison operators work with the similarity() function in VelesQL?
You can use >, <, >=, <=, and =. The semantic meaning depends on your collection's distance metric: cosine and dot-product similarity typically use > to find vectors closer to 1.0, while euclidean distance uses < to find vectors with smaller raw distances. The threshold value should match the metric's output range.
Can I include multiple similarity() predicates in a single VelesQL query?
No. The validator in crates/velesdb-core/src/velesql/validation.rs explicitly enforces a single similarity clause per query (lines 46-68). This ensures the query planner can unambiguously route to a single HNSW index search with one query vector and one distance metric.
How do I sort results by vector similarity in VelesQL?
Use the similarity() function in an ORDER BY clause, passing the same arguments as the WHERE predicate: ORDER BY similarity(embedding, $vec) DESC. When used in both WHERE and ORDER BY, VelesDB reuses the computed similarity scores from the HNSW search to avoid redundant calculations.
Does VelesQL support vector similarity filtering within graph MATCH queries?
Yes. You can place similarity() predicates inside MATCH WHERE clauses to rank graph nodes by embedding similarity. The syntax supports referencing the similarity score in RETURN clauses using bare similarity() and ordering results by that score, as demonstrated in the graph query examples and README documentation.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →