Conditional Steps
⚠️ 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.
Filtering with WHERE
Filter elements based on specific conditions.
::WHERE(<condition>)
::WHERE(_::{property}::COMPARISON(value))
ℹ️ Note
The condition in the WHERE step must evaluate to a boolean value. If the condition is not met, the element will be filtered out from the results.
⚠️ Warning
When using the SDKs or curling the endpoint, the query name must match what is defined in the
queries.hxfile exactly.
Comparison Operations
The following operations can be used to compare values.
EQ and NEQ can be used to compare strings, booleans, and numbers.
GT, GTE, LT, and LTE can only be used to compare numbers.
String, Boolean, and Number Operations
| Operation | Description | Example |
|---|---|---|
::EQ(value) | Equals | ::WHERE(_::{status}::EQ("active")) |
::NEQ(value) | Not equals | ::WHERE(_::{age}::NEQ(25)) |
Number Operations
| Operation | Description | Example |
|---|---|---|
::GT(value) | Greater than | ::WHERE(_::{age}::GT(25)) |
::LT(value) | Less than | ::WHERE(_::{age}::LT(30)) |
::GTE(value) | Greater than or equal | ::WHERE(_::{rating}::GTE(4.5)) |
::LTE(value) | Less than or equal | ::WHERE(_::{priority}::LTE(2)) |
String Operations
| Operation | Description | Example |
|---|---|---|
::CONTAINS(value) | String contains substring | ::WHERE(_::{name}::CONTAINS("john")) |
::CONTAINS(object) | Array contains object | ::WHERE(_::Out<Follows>::CONTAINS(user)) |
Array/Set Operations
| Operation | Description | Example |
|---|---|---|
::IS_IN(array) | Value exists in array | ::WHERE(_::{status}::IS_IN(["active", "pending"])) |
Example 1: Basic filtering with WHERE
QUERY GetAdultUsers () =>
adult_users <- N<User>::WHERE(_::{age}::GT(18))
RETURN adult_users
QUERY CreateUser (name: String, age: U8, email: String) =>
user <- AddN<User>({
name: name,
age: age,
email: email
})
RETURN user
N::User {
name: String,
age: U8,
email: String
}
Here’s how to run the query using the SDKs or curl
from helix.client import Client
client = Client(local=True, port=6969)
users = [
{"name": "Alice", "age": 25, "email": "alice@example.com"},
{"name": "Bob", "age": 16, "email": "bob@example.com"},
{"name": "Charlie", "age": 30, "email": "charlie@example.com"},
{"name": "Diana", "age": 17, "email": "diana@example.com"},
]
for user in users:
client.query("CreateUser", user)
result = client.query("GetAdultUsers", {})
print(result)
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 users = vec![
("Alice", 25, "alice@example.com"),
("Bob", 16, "bob@example.com"),
("Charlie", 30, "charlie@example.com"),
("Diana", 17, "diana@example.com"),
];
for (name, age, email) in &users {
let _created: serde_json::Value = client.query("CreateUser", &json!({
"name": name,
"age": age,
"email": email,
})).await?;
}
let result: serde_json::Value = client.query("GetAdultUsers", &json!({})).await?;
println!("Adult users: {result:#?}");
Ok(())
}
package main
import (
"fmt"
"log"
"github.com/HelixDB/helix-go"
)
func main() {
client := helix.NewClient("http://localhost:6969")
users := []map[string]any{
{"name": "Alice", "age": uint8(25), "email": "alice@example.com"},
{"name": "Bob", "age": uint8(16), "email": "bob@example.com"},
{"name": "Charlie", "age": uint8(30), "email": "charlie@example.com"},
{"name": "Diana", "age": uint8(17), "email": "diana@example.com"},
}
for _, user := range users {
var created map[string]any
if err := client.Query("CreateUser", helix.WithData(user)).Scan(&created); err != nil {
log.Fatalf("CreateUser failed: %s", err)
}
}
var result map[string]any
if err := client.Query("GetAdultUsers", helix.WithData(map[string]any{})).Scan(&result); err != nil {
log.Fatalf("GetAdultUsers failed: %s", err)
}
fmt.Printf("Adult users: %#v\n", result)
}
import HelixDB from "helix-ts";
async function main() {
const client = new HelixDB("http://localhost:6969");
const users = [
{ name: "Alice", age: 25, email: "alice@example.com" },
{ name: "Bob", age: 16, email: "bob@example.com" },
{ name: "Charlie", age: 30, email: "charlie@example.com" },
{ name: "Diana", age: 17, email: "diana@example.com" },
];
for (const user of users) {
await client.query("CreateUser", user);
}
const result = await client.query("GetAdultUsers", {});
console.log("Adult users:", result);
}
main().catch((err) => {
console.error("GetAdultUsers query failed:", err);
});
curl -X POST \
http://localhost:6969/CreateUser \
-H 'Content-Type: application/json' \
-d '{"name":"Alice","age":25,"email":"alice@example.com"}'
curl -X POST \
http://localhost:6969/CreateUser \
-H 'Content-Type: application/json' \
-d '{"name":"Bob","age":16,"email":"bob@example.com"}'
curl -X POST \
http://localhost:6969/CreateUser \
-H 'Content-Type: application/json' \
-d '{"name":"Charlie","age":30,"email":"charlie@example.com"}'
curl -X POST \
http://localhost:6969/CreateUser \
-H 'Content-Type: application/json' \
-d '{"name":"Diana","age":17,"email":"diana@example.com"}'
curl -X POST \
http://localhost:6969/GetAdultUsers \
-H 'Content-Type: application/json' \
-d '{}'
💡 Tip
For multiple conditions, see Multiple Conditional Steps.
Example 2: String and equality filtering
QUERY GetActiveUsers (status: String) =>
active_users <- N<User>::WHERE(_::{status}::EQ(status))
RETURN active_users
QUERY CreateUser (name: String, age: U8, email: String, status: String) =>
user <- AddN<User>({
name: name,
age: age,
email: email,
status: status
})
RETURN user
N::User {
name: String,
age: U8,
email: String,
status: String
}
Here’s how to run the query using the SDKs or curl
from helix.client import Client
client = Client(local=True, port=6969)
users = [
{"name": "Alice", "age": 25, "email": "alice@example.com", "status": "active"},
{"name": "Bob", "age": 30, "email": "bob@example.com", "status": "inactive"},
{"name": "Charlie", "age": 28, "email": "charlie@example.com", "status": "active"},
{"name": "Diana", "age": 22, "email": "diana@example.com", "status": "pending"},
]
for user in users:
client.query("CreateUser", user)
result = client.query("GetActiveUsers", {"status": "active"})
print(result)
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 users = vec![
("Alice", 25, "alice@example.com", "active"),
("Bob", 30, "bob@example.com", "inactive"),
("Charlie", 28, "charlie@example.com", "active"),
("Diana", 22, "diana@example.com", "pending"),
];
for (name, age, email, status) in &users {
let _created: serde_json::Value = client.query("CreateUser", &json!({
"name": name,
"age": age,
"email": email,
"status": status,
})).await?;
}
let result: serde_json::Value = client.query("GetActiveUsers", &json!({
"status": "active"
})).await?;
println!("Active users: {result:#?}");
Ok(())
}
package main
import (
"fmt"
"log"
"github.com/HelixDB/helix-go"
)
func main() {
client := helix.NewClient("http://localhost:6969")
users := []map[string]any{
{"name": "Alice", "age": uint8(25), "email": "alice@example.com", "status": "active"},
{"name": "Bob", "age": uint8(30), "email": "bob@example.com", "status": "inactive"},
{"name": "Charlie", "age": uint8(28), "email": "charlie@example.com", "status": "active"},
{"name": "Diana", "age": uint8(22), "email": "diana@example.com", "status": "pending"},
}
for _, user := range users {
var created map[string]any
if err := client.Query("CreateUser", helix.WithData(user)).Scan(&created); err != nil {
log.Fatalf("CreateUser failed: %s", err)
}
}
searchPayload := map[string]any{"status": "active"}
var result map[string]any
if err := client.Query("GetActiveUsers", helix.WithData(searchPayload)).Scan(&result); err != nil {
log.Fatalf("GetActiveUsers failed: %s", err)
}
fmt.Printf("Active users: %#v\n", result)
}
import HelixDB from "helix-ts";
async function main() {
const client = new HelixDB("http://localhost:6969");
const users = [
{ name: "Alice", age: 25, email: "alice@example.com", status: "active" },
{ name: "Bob", age: 30, email: "bob@example.com", status: "inactive" },
{ name: "Charlie", age: 28, email: "charlie@example.com", status: "active" },
{ name: "Diana", age: 22, email: "diana@example.com", status: "pending" },
];
for (const user of users) {
await client.query("CreateUser", user);
}
const result = await client.query("GetActiveUsers", { status: "active" });
console.log("Active users:", result);
}
main().catch((err) => {
console.error("GetActiveUsers query failed:", err);
});
curl -X POST \
http://localhost:6969/CreateUser \
-H 'Content-Type: application/json' \
-d '{"name":"Alice","age":25,"email":"alice@example.com","status":"active"}'
curl -X POST \
http://localhost:6969/CreateUser \
-H 'Content-Type: application/json' \
-d '{"name":"Bob","age":30,"email":"bob@example.com","status":"inactive"}'
curl -X POST \
http://localhost:6969/CreateUser \
-H 'Content-Type: application/json' \
-d '{"name":"Charlie","age":28,"email":"charlie@example.com","status":"active"}'
curl -X POST \
http://localhost:6969/CreateUser \
-H 'Content-Type: application/json' \
-d '{"name":"Diana","age":22,"email":"diana@example.com","status":"pending"}'
curl -X POST \
http://localhost:6969/GetActiveUsers \
-H 'Content-Type: application/json' \
-d '{"status":"active"}'
Filter by Relationships with EXISTS
Returns true if a traversal has any results. Otherwise, it returns false.
EXISTS(<traversal>)
Example 1: Using EXISTS for relationship filtering
QUERY GetUsersWithFollowers () =>
users <- N<User>::WHERE(EXISTS(_::In<Follows>))
RETURN users
QUERY CreateUser (name: String, age: U8, email: String) =>
user <- AddN<User>({
name: name,
age: age,
email: email
})
RETURN user
QUERY CreateFollow (follower_id: ID, following_id: ID) =>
follower <- N<User>(follower_id)
following <- N<User>(following_id)
AddE<Follows>::From(follower)::To(following)
RETURN "Success"
N::User {
name: String,
age: U8,
email: String
}
E::Follows {
From: User,
To: User
}
Here’s how to run the query using the SDKs or curl
from helix.client import Client
client = Client(local=True, port=6969)
users = [
{"name": "Alice", "age": 25, "email": "alice@example.com"},
{"name": "Bob", "age": 30, "email": "bob@example.com"},
{"name": "Charlie", "age": 28, "email": "charlie@example.com"},
]
user_ids = []
for user in users:
result = client.query("CreateUser", user)
user_ids.append(result[0]["user"]["id"])
client.query("CreateFollow", {"follower_id": user_ids[1], "following_id": user_ids[0]})
client.query("CreateFollow", {"follower_id": user_ids[2], "following_id": user_ids[0]})
result = client.query("GetUsersWithFollowers", {})
print(result)
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 users = vec![
("Alice", 25, "alice@example.com"),
("Bob", 30, "bob@example.com"),
("Charlie", 28, "charlie@example.com"),
];
let mut user_ids = Vec::new();
for (name, age, email) in &users {
let result: serde_json::Value = client.query("CreateUser", &json!({
"name": name,
"age": age,
"email": email,
})).await?;
user_ids.push(result["user"]["id"].as_str().unwrap().to_string());
}
let _follow1: serde_json::Value = client.query("CreateFollow", &json!({
"follower_id": user_ids[1],
"following_id": user_ids[0]
})).await?;
let _follow2: serde_json::Value = client.query("CreateFollow", &json!({
"follower_id": user_ids[2],
"following_id": user_ids[0]
})).await?;
let result: serde_json::Value = client.query("GetUsersWithFollowers", &json!({})).await?;
println!("Users with followers: {result:#?}");
Ok(())
}
package main
import (
"fmt"
"log"
"github.com/HelixDB/helix-go"
)
func main() {
client := helix.NewClient("http://localhost:6969")
users := []map[string]any{
{"name": "Alice", "age": uint8(25), "email": "alice@example.com"},
{"name": "Bob", "age": uint8(30), "email": "bob@example.com"},
{"name": "Charlie", "age": uint8(28), "email": "charlie@example.com"},
}
var userIDs []string
for _, user := range users {
var created map[string]any
if err := client.Query("CreateUser", helix.WithData(user)).Scan(&created); err != nil {
log.Fatalf("CreateUser failed: %s", err)
}
userIDs = append(userIDs, created["user"].(map[string]any)["id"].(string))
}
followPayload1 := map[string]any{
"follower_id": userIDs[1],
"following_id": userIDs[0],
}
var follow1 map[string]any
if err := client.Query("CreateFollow", helix.WithData(followPayload1)).Scan(&follow1); err != nil {
log.Fatalf("CreateFollow failed: %s", err)
}
followPayload2 := map[string]any{
"follower_id": userIDs[2],
"following_id": userIDs[0],
}
var follow2 map[string]any
if err := client.Query("CreateFollow", helix.WithData(followPayload2)).Scan(&follow2); err != nil {
log.Fatalf("CreateFollow failed: %s", err)
}
var result map[string]any
if err := client.Query("GetUsersWithFollowers", helix.WithData(map[string]any{})).Scan(&result); err != nil {
log.Fatalf("GetUsersWithFollowers failed: %s", err)
}
fmt.Printf("Users with followers: %#v\n", result)
}
import HelixDB from "helix-ts";
async function main() {
const client = new HelixDB("http://localhost:6969");
const users = [
{ name: "Alice", age: 25, email: "alice@example.com" },
{ name: "Bob", age: 30, email: "bob@example.com" },
{ name: "Charlie", age: 28, email: "charlie@example.com" },
];
const userIds: string[] = [];
for (const user of users) {
const result = await client.query("CreateUser", user);
userIds.push(result.user.id);
}
await client.query("CreateFollow", {
follower_id: userIds[1],
following_id: userIds[0]
});
await client.query("CreateFollow", {
follower_id: userIds[2],
following_id: userIds[0]
});
const result = await client.query("GetUsersWithFollowers", {});
console.log("Users with followers:", result);
}
main().catch((err) => {
console.error("GetUsersWithFollowers query failed:", err);
});
curl -X POST \
http://localhost:6969/CreateUser \
-H 'Content-Type: application/json' \
-d '{"name":"Alice","age":25,"email":"alice@example.com"}'
curl -X POST \
http://localhost:6969/CreateUser \
-H 'Content-Type: application/json' \
-d '{"name":"Bob","age":30,"email":"bob@example.com"}'
curl -X POST \
http://localhost:6969/CreateUser \
-H 'Content-Type: application/json' \
-d '{"name":"Charlie","age":28,"email":"charlie@example.com"}'
curl -X POST \
http://localhost:6969/CreateFollow \
-H 'Content-Type: application/json' \
-d '{"follower_id":"<bob_id>","following_id":"<alice_id>"}'
curl -X POST \
http://localhost:6969/CreateFollow \
-H 'Content-Type: application/json' \
-d '{"follower_id":"<charlie_id>","following_id":"<alice_id>"}'
curl -X POST \
http://localhost:6969/GetUsersWithFollowers \
-H 'Content-Type: application/json' \
-d '{}'