# VelesQL Syntax for Filtering Data Based on Vector Similarity: A Complete Guide

> Master VelesQL syntax for vector similarity filtering. Learn how to use similarity predicates in WHERE clauses to efficiently search your VelesDB with HNSW index support.

- Repository: [Wiscale/velesdb](https://github.com/cyberlife-coder/velesdb)
- Tags: how-to-guide
- Published: 2026-02-28

---

**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`](https://github.com/cyberlife-coder/velesdb/blob/main/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:

```sql
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`](https://github.com/cyberlife-coder/velesdb/blob/main/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:

1. The parser in [`crates/velesdb-core/src/velesql/parser/conditions.rs`](https://github.com/cyberlife-coder/velesdb/blob/main/crates/velesdb-core/src/velesql/parser/conditions.rs) (lines 207-211) tokenizes `similarity(<field>, $vec) <op> <num>` into the AST.
2. The validator in [`crates/velesdb-core/src/velesql/validation.rs`](https://github.com/cyberlife-coder/velesdb/blob/main/crates/velesdb-core/src/velesql/validation.rs) (lines 46-68) enforces semantic rules, ensuring only one similarity clause exists per query.
3. 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:

```sql
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:

```sql
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:

```sql
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`](https://github.com/cyberlife-coder/velesdb/blob/main/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:

```bash
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`](https://github.com/cyberlife-coder/velesdb/blob/main/sdks/typescript/README.md) (lines 307-313), you can parameterize queries programmatically:

```typescript
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`](https://github.com/cyberlife-coder/velesdb/blob/main/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.rs`](https://github.com/cyberlife-coder/velesdb/blob/main/crates/velesdb-server/src/handlers/query.rs) automatically detects similarity conditions and routes to HNSW index search via `condition_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`](https://github.com/cyberlife-coder/velesdb/blob/main/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`](https://github.com/cyberlife-coder/velesdb/blob/main/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.