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

Property Remappings

⚠️ 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.

Simple Remappings  

Sometimes, you may want to rename a property that is returned from a traversal. You can access properties of an item by using the name of the property as defined in the schema.

::{new_name: property_name}
::{alias: _::{property}}

You can use the name directly, or if you want to be more explicit, or in cases where there may be name clashes, you can use the _:: operator.

⚠️ 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: Basic property remapping

QUERY GetUserWithAlias () =>
    users <- N<User>::RANGE(0, 5)
    RETURN users::{
        userID: ::ID,
        displayName: name
    }

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 Johnson", "age": 25, "email": "alice@example.com"},
    {"name": "Bob Smith", "age": 30, "email": "bob@example.com"},
    {"name": "Charlie Brown", "age": 28, "email": "charlie@example.com"},
]

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

result = client.query("GetUserWithAlias", {})
print("Users with remapped properties:", 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 Johnson", 25, "alice@example.com"),
        ("Bob Smith", 30, "bob@example.com"),
        ("Charlie Brown", 28, "charlie@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("GetUserWithAlias", &json!({})).await?;
    println!("Users with remapped properties: {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 Johnson", "age": uint8(25), "email": "alice@example.com"},
        {"name": "Bob Smith", "age": uint8(30), "email": "bob@example.com"},
        {"name": "Charlie Brown", "age": uint8(28), "email": "charlie@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("GetUserWithAlias", helix.WithData(map[string]any{})).Scan(&result); err != nil {
        log.Fatalf("GetUserWithAlias failed: %s", err)
    }

    fmt.Printf("Users with remapped properties: %#v\n", result)
}
import HelixDB from "helix-ts";

async function main() {
    const client = new HelixDB("http://localhost:6969");

    const users = [
        { name: "Alice Johnson", age: 25, email: "alice@example.com" },
        { name: "Bob Smith", age: 30, email: "bob@example.com" },
        { name: "Charlie Brown", age: 28, email: "charlie@example.com" },
    ];

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

    const result = await client.query("GetUserWithAlias", {});
    console.log("Users with remapped properties:", result);
}

main().catch((err) => {
    console.error("GetUserWithAlias query failed:", err);
});
curl -X POST \
  http://localhost:6969/CreateUser \
  -H 'Content-Type: application/json' \
  -d '{"name":"Alice Johnson","age":25,"email":"alice@example.com"}'

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

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

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

Nested Mappings  

::|item_name|{
    field: item_name::traversal,
    nested_field: other::{
        property: item_name::ID,
        ..
    }
}

ℹ️ Note

The important thing to note here, is that if we were to access the ID like we have shown previously: nested_field: ID. This ID would be the ID of the other item, not the item_name item due to the tighter scope.

⚠️ Warning

When accessing properties in nested mappings, scope matters. Use the explicit item_name::property syntax to access properties from outer scopes to avoid ambiguity.

Example 1: User posts with nested remappings

QUERY GetUserPosts (user_id: ID) =>
    user <- N<User>(user_id)
    posts <- user::Out<HasPost>
    RETURN user::|usr|{
        posts: posts::{
            postID: ID,
            creatorID: usr::ID,
            creatorName: usr::name,
            ..
        }
    }

QUERY CreateUser (name: String, age: U8, email: String) =>
    user <- AddN<User>({
        name: name,
        age: age,
        email: email
    })
    RETURN user

QUERY CreatePost (user_id: ID, title: String, content: String) =>
    user <- N<User>(user_id)
    post <- AddN<Post>({
        title: title,
        content: content
    })
    AddE<HasPost>::From(user)::To(post)
    RETURN post
N::User {
    name: String,
    age: U8,
    email: String
}

N::Post {
    title: String,
    content: String
}

E::HasPost {
    From: User,
    To: Post
}

Here’s how to run the query using the SDKs or curl

from helix.client import Client

client = Client(local=True, port=6969)

user_result = client.query("CreateUser", {
    "name": "Alice Johnson",
    "age": 25,
    "email": "alice@example.com"
})
user_id = user_result[0]["user"]["id"]

posts = [
    {"title": "My First Post", "content": "This is my first blog post!"},
    {"title": "Learning GraphDB", "content": "Graph databases are fascinating."},
    {"title": "Weekend Plans", "content": "Planning to explore the city."},
]

for post in posts:
    client.query("CreatePost", {
        "user_id": user_id,
        "title": post["title"],
        "content": post["content"]
    })

result = client.query("GetUserPosts", {"user_id": user_id})
print("User posts with nested remappings:", 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 user_result: serde_json::Value = client.query("CreateUser", &json!({
        "name": "Alice Johnson",
        "age": 25,
        "email": "alice@example.com"
    })).await?;
    let user_id = user_result["user"]["id"].as_str().unwrap();

    let posts = vec![
        ("My First Post", "This is my first blog post!"),
        ("Learning GraphDB", "Graph databases are fascinating."),
        ("Weekend Plans", "Planning to explore the city."),
    ];

    for (title, content) in &posts {
        let _post: serde_json::Value = client.query("CreatePost", &json!({
            "user_id": user_id,
            "title": title,
            "content": content
        })).await?;
    }

    let result: serde_json::Value = client.query("GetUserPosts", &json!({
        "user_id": user_id
    })).await?;
    println!("User posts with nested remappings: {result:#?}");

    Ok(())
}
package main

import (
    "fmt"
    "log"

    "github.com/HelixDB/helix-go"
)

func main() {
    client := helix.NewClient("http://localhost:6969")

    var userResult map[string]any
    if err := client.Query("CreateUser", helix.WithData(map[string]any{
        "name": "Alice Johnson",
        "age":  uint8(25),
        "email": "alice@example.com",
    })).Scan(&userResult); err != nil {
        log.Fatalf("CreateUser failed: %s", err)
    }
    userID := userResult["user"].(map[string]any)["id"].(string)

    posts := []map[string]string{
        {"title": "My First Post", "content": "This is my first blog post!"},
        {"title": "Learning GraphDB", "content": "Graph databases are fascinating."},
        {"title": "Weekend Plans", "content": "Planning to explore the city."},
    }

    for _, post := range posts {
        var postResult map[string]any
        if err := client.Query("CreatePost", helix.WithData(map[string]any{
            "user_id": userID,
            "title":   post["title"],
            "content": post["content"],
        })).Scan(&postResult); err != nil {
            log.Fatalf("CreatePost failed: %s", err)
        }
    }

    var result map[string]any
    if err := client.Query("GetUserPosts", helix.WithData(map[string]any{
        "user_id": userID,
    })).Scan(&result); err != nil {
        log.Fatalf("GetUserPosts failed: %s", err)
    }

    fmt.Printf("User posts with nested remappings: %#v\n", result)
}
import HelixDB from "helix-ts";

async function main() {
    const client = new HelixDB("http://localhost:6969");

    const userResult = await client.query("CreateUser", {
        name: "Alice Johnson",
        age: 25,
        email: "alice@example.com"
    });
    const userId = userResult.user.id;

    const posts = [
        { title: "My First Post", content: "This is my first blog post!" },
        { title: "Learning GraphDB", content: "Graph databases are fascinating." },
        { title: "Weekend Plans", content: "Planning to explore the city." },
    ];

    for (const post of posts) {
        await client.query("CreatePost", {
            user_id: userId,
            title: post.title,
            content: post.content
        });
    }

    const result = await client.query("GetUserPosts", { user_id: userId });
    console.log("User posts with nested remappings:", result);
}

main().catch((err) => {
    console.error("GetUserPosts query failed:", err);
});
curl -X POST \
  http://localhost:6969/CreateUser \
  -H 'Content-Type: application/json' \
  -d '{"name":"Alice Johnson","age":25,"email":"alice@example.com"}'

curl -X POST \
  http://localhost:6969/CreatePost \
  -H 'Content-Type: application/json' \
  -d '{"user_id":"<user_id>","title":"My First Post","content":"This is my first blog post!"}'

curl -X POST \
  http://localhost:6969/CreatePost \
  -H 'Content-Type: application/json' \
  -d '{"user_id":"<user_id>","title":"Learning GraphDB","content":"Graph databases are fascinating."}'

curl -X POST \
  http://localhost:6969/CreatePost \
  -H 'Content-Type: application/json' \
  -d '{"user_id":"<user_id>","title":"Weekend Plans","content":"Planning to explore the city."}'

curl -X POST \
  http://localhost:6969/GetUserPosts \
  -H 'Content-Type: application/json' \
  -d '{"user_id":"<user_id>"}'