Vector search
⚠️ Warning
HelixQL is deprecated in HelixDB v2. Queries are now written with the Rust DSL and dispatched as JSON — see the Querying guide. This section is kept as a reference for legacy HelixQL projects.
For the complete documentation index optimized for AI agents, see llms.txt.
How do I search for similar vectors in HelixDB?
Use SearchV to find vectors similar to your query vector using cosine similarity.
SearchV<Type>(vector, limit)
ℹ️ Note
Currently, Helix only supports using an array of
F64values to represent the vector. We will be adding support for different types such asF32, binary vectors and more in the very near future. Please reach out to us if you need a different vector type.
⚠️ Warning
When using the SDKs or curling the endpoint, the query name must match what is defined in the
queries.hxfile exactly.
Example 1: Basic vector search
QUERY SearchVector (vector: [F64], limit: I64) =>
documents <- SearchV<Document>(vector, limit)
RETURN documents
QUERY InsertVector (vector: [F64], content: String, created_at: Date) =>
document <- AddV<Document>(vector, { content: content, created_at: created_at })
RETURN document
V::Document {
content: String,
created_at: Date
}
Here’s how to run the query using the SDKs or curl
from datetime import datetime, timezone
from helix.client import Client
client = Client(local=True, port=6969)
vector_data = [0.1, 0.2, 0.3, 0.4]
inserted = client.query("InsertVector", {
"vector": vector_data,
"content": "Sample document content",
"created_at": datetime.now(timezone.utc).isoformat(),
})
result = client.query("SearchVector", {
"vector": vector_data,
"limit": 10
})
print(result)
use chrono::Utc;
use helix_rs::{HelixDB, HelixDBClient};
use serde_json::json;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = HelixDB::new(Some("http://localhost"), Some(6969), None);
let vector_data = vec![0.1, 0.2, 0.3, 0.4];
let _inserted: serde_json::Value = client.query("InsertVector", &json!({
"vector": vector_data,
"content": "Sample document content",
"created_at": Utc::now().to_rfc3339(),
})).await?;
let result: serde_json::Value = client.query("SearchVector", &json!({
"vector": vector_data,
"limit": 10,
})).await?;
println!("Search results: {result:#?}");
Ok(())
}
package main
import (
"fmt"
"log"
"time"
"github.com/HelixDB/helix-go"
)
func main() {
client := helix.NewClient("http://localhost:6969")
vectorData := []float64{0.1, 0.2, 0.3, 0.4}
insertPayload := map[string]any{
"vector": vectorData,
"content": "Sample document content",
"created_at": time.Now().UTC().Format(time.RFC3339),
}
var inserted map[string]any
if err := client.Query("InsertVector", helix.WithData(insertPayload)).Scan(&inserted); err != nil {
log.Fatalf("InsertVector failed: %s", err)
}
searchPayload := map[string]any{
"vector": vectorData,
"limit": int64(10),
}
var result map[string]any
if err := client.Query("SearchVector", helix.WithData(searchPayload)).Scan(&result); err != nil {
log.Fatalf("SearchVector failed: %s", err)
}
fmt.Printf("Search results: %#v\n", result)
}
import HelixDB from "helix-ts";
async function main() {
const client = new HelixDB("http://localhost:6969");
const vectorData = [0.1, 0.2, 0.3, 0.4];
const inserted = await client.query("InsertVector", {
vector: vectorData,
content: "Sample document content",
created_at: new Date().toISOString(),
});
const result = await client.query("SearchVector", {
vector: vectorData,
limit: 10,
});
console.log("Search results:", result);
}
main().catch((err) => {
console.error("SearchVector query failed:", err);
});
curl -X POST \
http://localhost:6969/InsertVector \
-H 'Content-Type: application/json' \
-d '{"vector":[0.1,0.2,0.3,0.4],"content":"Sample document content","created_at":"'"$(date -u +"%Y-%m-%dT%H:%M:%SZ")"'"}'
curl -X POST \
http://localhost:6969/SearchVector \
-H 'Content-Type: application/json' \
-d '{"vector":[0.1,0.2,0.3,0.4],"limit":10}'
Example 2: Vector search with postfiltering
QUERY SearchRecentDocuments (vector: [F64], limit: I64, cutoff_date: Date) =>
documents <- SearchV<Document>(vector, limit)::WHERE(_::{created_at}::GTE(cutoff_date))
RETURN documents
QUERY InsertVector (vector: [F64], content: String, created_at: Date) =>
document <- AddV<Document>(vector, { content: content, created_at: created_at })
RETURN document
V::Document {
content: String,
created_at: Date
}
Here’s how to run the query using the SDKs or curl
from datetime import datetime, timezone, timedelta
from helix.client import Client
client = Client(local=True, port=6969)
vector_data = [0.12, 0.34, 0.56, 0.78]
recent_date = datetime.now(timezone.utc).isoformat()
old_date = (datetime.now(timezone.utc) - timedelta(days=45)).isoformat()
client.query("InsertVector", {
"vector": vector_data,
"content": "Recent document content",
"created_at": recent_date,
})
client.query("InsertVector", {
"vector": [0.15, 0.35, 0.55, 0.75],
"content": "Old document content",
"created_at": old_date,
})
cutoff_date = (datetime.now(timezone.utc) - timedelta(days=30)).isoformat()
result = client.query("SearchRecentDocuments", {
"vector": vector_data,
"limit": 5,
"cutoff_date": cutoff_date,
})
print(result)
use chrono::{Duration, Utc};
use helix_rs::{HelixDB, HelixDBClient};
use serde_json::json;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = HelixDB::new(Some("http://localhost"), Some(6969), None);
let vector_data = vec![0.12, 0.34, 0.56, 0.78];
let recent_date = Utc::now().to_rfc3339();
let old_date = (Utc::now() - Duration::days(45)).to_rfc3339();
let _recent: serde_json::Value = client.query("InsertVector", &json!({
"vector": vector_data,
"content": "Recent document content",
"created_at": recent_date,
})).await?;
let _old: serde_json::Value = client.query("InsertVector", &json!({
"vector": [0.15, 0.35, 0.55, 0.75],
"content": "Old document content",
"created_at": old_date,
})).await?;
let cutoff_date = (Utc::now() - Duration::days(30)).to_rfc3339();
let result: serde_json::Value = client.query("SearchRecentDocuments", &json!({
"vector": vector_data,
"limit": 5,
"cutoff_date": cutoff_date,
})).await?;
println!("Filtered search results: {result:#?}");
Ok(())
}
package main
import (
"fmt"
"log"
"time"
"github.com/HelixDB/helix-go"
)
func main() {
client := helix.NewClient("http://localhost:6969")
vectorData := []float64{0.12, 0.34, 0.56, 0.78}
recentDate := time.Now().UTC().Format(time.RFC3339)
oldDate := time.Now().UTC().AddDate(0, 0, -45).Format(time.RFC3339)
recentPayload := map[string]any{
"vector": vectorData,
"content": "Recent document content",
"created_at": recentDate,
}
var recent map[string]any
if err := client.Query("InsertVector", helix.WithData(recentPayload)).Scan(&recent); err != nil {
log.Fatalf("InsertVector (recent) failed: %s", err)
}
oldPayload := map[string]any{
"vector": []float64{0.15, 0.35, 0.55, 0.75},
"content": "Old document content",
"created_at": oldDate,
}
var old map[string]any
if err := client.Query("InsertVector", helix.WithData(oldPayload)).Scan(&old); err != nil {
log.Fatalf("InsertVector (old) failed: %s", err)
}
cutoffDate := time.Now().UTC().AddDate(0, 0, -30).Format(time.RFC3339)
searchPayload := map[string]any{
"vector": vectorData,
"limit": int64(5),
"cutoff_date": cutoffDate,
}
var result map[string]any
if err := client.Query("SearchRecentDocuments", helix.WithData(searchPayload)).Scan(&result); err != nil {
log.Fatalf("SearchRecentDocuments failed: %s", err)
}
fmt.Printf("Filtered search results: %#v\n", result)
}
import HelixDB from "helix-ts";
async function main() {
const client = new HelixDB("http://localhost:6969");
const vectorData = [0.12, 0.34, 0.56, 0.78];
const recentDate = new Date().toISOString();
const oldDate = new Date(Date.now() - 45 * 24 * 60 * 60 * 1000).toISOString();
await client.query("InsertVector", {
vector: vectorData,
content: "Recent document content",
created_at: recentDate,
});
await client.query("InsertVector", {
vector: [0.15, 0.35, 0.55, 0.75],
content: "Old document content",
created_at: oldDate,
});
const cutoffDate = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString();
const result = await client.query("SearchRecentDocuments", {
vector: vectorData,
limit: 5,
cutoff_date: cutoffDate,
});
console.log("Filtered search results:", result);
}
main().catch((err) => {
console.error("SearchRecentDocuments query failed:", err);
});
curl -X POST \
http://localhost:6969/InsertVector \
-H 'Content-Type: application/json' \
-d '{"vector":[0.12,0.34,0.56,0.78],"content":"Recent document content","created_at":"'"$(date -u +"%Y-%m-%dT%H:%M:%SZ")"'"}'
curl -X POST \
http://localhost:6969/InsertVector \
-H 'Content-Type: application/json' \
-d '{"vector":[0.15,0.35,0.55,0.75],"content":"Old document content","created_at":"'"$(date -u -d '45 days ago' +"%Y-%m-%dT%H:%M:%SZ")"'"}'
curl -X POST \
http://localhost:6969/SearchRecentDocuments \
-H 'Content-Type: application/json' \
-d '{"vector":[0.12,0.34,0.56,0.78],"limit":5,"cutoff_date":"'"$(date -u -d '30 days ago' +"%Y-%m-%dT%H:%M:%SZ")"'"}'
Example 3: Using the built in Embed function
You can also use the built in Embed function to search with text directly without sending in the array of floats. It uses the embedding model defined in your config.hx.json file.
⚠️ Warning
All vectors in a vector type must have the same dimensions. If you change your embedding model (e.g., switching from
text-embedding-ada-002to a different model), the new vectors will have different dimensions and will cause an error. Ensure you use the same embedding model consistently for all vectors.
QUERY SearchWithText (text: String, limit: I64) =>
documents <- SearchV<Document>(Embed(text), limit)
RETURN documents
QUERY InsertTextAsVector (content: String, created_at: Date) =>
document <- AddV<Document>(Embed(content), { content: content, created_at: created_at })
RETURN document
V::Document {
content: String,
created_at: Date
}
OPENAI_API_KEY=your_api_key
Here’s how to run the query using the SDKs or curl
from datetime import datetime, timezone
from helix.client import Client
client = Client(local=True, port=6969)
sample_texts = [
"Introduction to machine learning algorithms",
"Deep neural networks and AI",
"Natural language processing techniques"
]
for text in sample_texts:
client.query("InsertTextAsVector", {
"content": text,
"created_at": datetime.now(timezone.utc).isoformat(),
})
result = client.query("SearchWithText", {
"text": "machine learning algorithms",
"limit": 10,
})
print(result)
use chrono::Utc;
use helix_rs::{HelixDB, HelixDBClient};
use serde_json::json;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = HelixDB::new(Some("http://localhost"), Some(6969), None);
let sample_texts = vec![
"Introduction to machine learning algorithms",
"Deep neural networks and AI",
"Natural language processing techniques"
];
for text in &sample_texts {
let _inserted: serde_json::Value = client.query("InsertTextAsVector", &json!({
"content": text,
"created_at": Utc::now().to_rfc3339(),
})).await?;
}
let result: serde_json::Value = client.query("SearchWithText", &json!({
"text": "machine learning algorithms",
"limit": 10,
})).await?;
println!("Text search results: {result:#?}");
Ok(())
}
package main
import (
"fmt"
"log"
"time"
"github.com/HelixDB/helix-go"
)
func main() {
client := helix.NewClient("http://localhost:6969")
sampleTexts := []string{
"Introduction to machine learning algorithms",
"Deep neural networks and AI",
"Natural language processing techniques",
}
for _, text := range sampleTexts {
insertPayload := map[string]any{
"content": text,
"created_at": time.Now().UTC().Format(time.RFC3339),
}
var inserted map[string]any
if err := client.Query("InsertTextAsVector", helix.WithData(insertPayload)).Scan(&inserted); err != nil {
log.Fatalf("InsertTextAsVector failed: %s", err)
}
}
searchPayload := map[string]any{
"text": "machine learning algorithms",
"limit": int64(10),
}
var result map[string]any
if err := client.Query("SearchWithText", helix.WithData(searchPayload)).Scan(&result); err != nil {
log.Fatalf("SearchWithText failed: %s", err)
}
fmt.Printf("Text search results: %#v\n", result)
}
import HelixDB from "helix-ts";
async function main() {
const client = new HelixDB("http://localhost:6969");
const sampleTexts = [
"Introduction to machine learning algorithms",
"Deep neural networks and AI",
"Natural language processing techniques"
];
for (const text of sampleTexts) {
await client.query("InsertTextAsVector", {
content: text,
created_at: new Date().toISOString(),
});
}
const result = await client.query("SearchWithText", {
text: "machine learning algorithms",
limit: 10,
});
console.log("Text search results:", result);
}
main().catch((err) => {
console.error("SearchWithText query failed:", err);
});
curl -X POST \
http://localhost:6969/InsertTextAsVector \
-H 'Content-Type: application/json' \
-d '{"content":"Introduction to machine learning algorithms","created_at":"'"$(date -u +"%Y-%m-%dT%H:%M:%SZ")"'"}'
curl -X POST \
http://localhost:6969/InsertTextAsVector \
-H 'Content-Type: application/json' \
-d '{"content":"Deep neural networks and AI","created_at":"'"$(date -u +"%Y-%m-%dT%H:%M:%SZ")"'"}'
curl -X POST \
http://localhost:6969/InsertTextAsVector \
-H 'Content-Type: application/json' \
-d '{"content":"Natural language processing techniques","created_at":"'"$(date -u +"%Y-%m-%dT%H:%M:%SZ")"'"}'
curl -X POST \
http://localhost:6969/SearchWithText \
-H 'Content-Type: application/json' \
-d '{"text":"machine learning algorithms","limit":10}'