Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Multiple 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.

Negate a condition with NOT (!)  

Negate a condition to match the opposite.

::WHERE(!<condition>)

Example: ! can be used infront of any condition that returns a boolean.

QUERY GetActiveUsersWithFollowers () =>
    followers <- N<User>::WHERE(
        !AND( // Negate the AND condition
            !_::{is_active}::EQ(true), // Negate the EQ condition
            _::Out<Follows>::COUNT::LT(10)
        )
    )
    RETURN followers
N::User {
    name: String,
    is_active: Boolean
}

E::Follows {
    From: User,
    To: User
}

The ! operator can also be combined with EXISTS to find elements without certain relationships:

QUERY GetUsersWithoutFollowers () =>
    users <- N<User>::WHERE(!EXISTS(_::In<Follows>))
    RETURN users

Enforce all conditions with AND  

Takes a list of conditions and returns true only if all conditions are true.

::WHERE(AND(<condition1>, <condition2>, ...))

Enforce any condition with OR  

Takes a list of conditions and returns true if at least one condition is true.

::WHERE(OR(<condition1>, <condition2>, ...))

⚠️ Warning

When using the SDKs or curling the endpoint, the query name must match what is defined in the queries.hx file exactly.

Example 1: Using AND for range filtering

QUERY GetYoungAdults () =>
    users <- N<User>::WHERE(AND(_::{age}::GT(18), _::{age}::LT(30)))
    RETURN 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": 35, "email": "charlie@example.com"},
    {"name": "Diana", "age": 22, "email": "diana@example.com"},
    {"name": "Eve", "age": 17, "email": "eve@example.com"},
]

for user in users:
    client.query("CreateUser", user)

result = client.query("GetYoungAdults", {})
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", 35, "charlie@example.com"),
        ("Diana", 22, "diana@example.com"),
        ("Eve", 17, "eve@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("GetYoungAdults", &json!({})).await?;
    println!("Young adults: {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(35), "email": "charlie@example.com"},
        {"name": "Diana", "age": uint8(22), "email": "diana@example.com"},
        {"name": "Eve", "age": uint8(17), "email": "eve@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("GetYoungAdults", helix.WithData(map[string]any{})).Scan(&result); err != nil {
        log.Fatalf("GetYoungAdults failed: %s", err)
    }

    fmt.Printf("Young adults: %#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: 35, email: "charlie@example.com" },
        { name: "Diana", age: 22, email: "diana@example.com" },
        { name: "Eve", age: 17, email: "eve@example.com" },
    ];

    for (const user of users) {
        await client.query("CreateUser", user);
    }

    const result = await client.query("GetYoungAdults", {});
    console.log("Young adults:", result);
}

main().catch((err) => {
    console.error("GetYoungAdults 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":35,"email":"charlie@example.com"}'

curl -X POST \
  http://localhost:6969/CreateUser \
  -H 'Content-Type: application/json' \
  -d '{"name":"Diana","age":22,"email":"diana@example.com"}'

curl -X POST \
  http://localhost:6969/CreateUser \
  -H 'Content-Type: application/json' \
  -d '{"name":"Eve","age":17,"email":"eve@example.com"}'

curl -X POST \
  http://localhost:6969/GetYoungAdults \
  -H 'Content-Type: application/json' \
  -d '{}'

Example 2: Using OR for multiple valid options

QUERY GetSpecificUsers () =>
    users <- N<User>::WHERE(OR(_::{name}::EQ("Alice"), _::{name}::EQ("Bob")))
    RETURN 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": 30, "email": "bob@example.com"},
    {"name": "Charlie", "age": 28, "email": "charlie@example.com"},
    {"name": "Diana", "age": 22, "email": "diana@example.com"},
]

for user in users:
    client.query("CreateUser", user)

result = client.query("GetSpecificUsers", {})
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"),
        ("Diana", 22, "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("GetSpecificUsers", &json!({})).await?;
    println!("Specific 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(30), "email": "bob@example.com"},
        {"name": "Charlie", "age": uint8(28), "email": "charlie@example.com"},
        {"name": "Diana", "age": uint8(22), "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("GetSpecificUsers", helix.WithData(map[string]any{})).Scan(&result); err != nil {
        log.Fatalf("GetSpecificUsers failed: %s", err)
    }

    fmt.Printf("Specific 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: 30, email: "bob@example.com" },
        { name: "Charlie", age: 28, email: "charlie@example.com" },
        { name: "Diana", age: 22, email: "diana@example.com" },
    ];

    for (const user of users) {
        await client.query("CreateUser", user);
    }

    const result = await client.query("GetSpecificUsers", {});
    console.log("Specific users:", result);
}

main().catch((err) => {
    console.error("GetSpecificUsers 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/CreateUser \
  -H 'Content-Type: application/json' \
  -d '{"name":"Diana","age":22,"email":"diana@example.com"}'

curl -X POST \
  http://localhost:6969/GetSpecificUsers \
  -H 'Content-Type: application/json' \
  -d '{}'

Example 3: Complex nested AND and OR conditions

QUERY GetFilteredUsers () =>
    users <- N<User>::WHERE(
        AND(
            _::{age}::GT(18),
            OR(_::{name}::EQ("Alice"), _::{name}::EQ("Bob"))
        )
    )
    RETURN 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": "Alice", "age": 17, "email": "alice2@example.com"},
    {"name": "Charlie", "age": 30, "email": "charlie@example.com"},
    {"name": "Bob", "age": 22, "email": "bob2@example.com"},
]

for user in users:
    client.query("CreateUser", user)

result = client.query("GetFilteredUsers", {})
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"),
        ("Alice", 17, "alice2@example.com"),
        ("Charlie", 30, "charlie@example.com"),
        ("Bob", 22, "bob2@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("GetFilteredUsers", &json!({})).await?;
    println!("Filtered 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": "Alice", "age": uint8(17), "email": "alice2@example.com"},
        {"name": "Charlie", "age": uint8(30), "email": "charlie@example.com"},
        {"name": "Bob", "age": uint8(22), "email": "bob2@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("GetFilteredUsers", helix.WithData(map[string]any{})).Scan(&result); err != nil {
        log.Fatalf("GetFilteredUsers failed: %s", err)
    }

    fmt.Printf("Filtered 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: "Alice", age: 17, email: "alice2@example.com" },
        { name: "Charlie", age: 30, email: "charlie@example.com" },
        { name: "Bob", age: 22, email: "bob2@example.com" },
    ];

    for (const user of users) {
        await client.query("CreateUser", user);
    }

    const result = await client.query("GetFilteredUsers", {});
    console.log("Filtered users:", result);
}

main().catch((err) => {
    console.error("GetFilteredUsers 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":"Alice","age":17,"email":"alice2@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":"Bob","age":22,"email":"bob2@example.com"}'

curl -X POST \
  http://localhost:6969/GetFilteredUsers \
  -H 'Content-Type: application/json' \
  -d '{}'