Getting Started with Graph Databases
This guide walks you through setting up your first graph database connection in Ductape, from installation to creating your first nodes and relationships.
Prerequisites
Before you begin, make sure you have:
- A Ductape account and workspace
- A product created in your workspace
- Access to a graph database (Neo4j, AWS Neptune, ArangoDB, or Memgraph)
- The Ductape SDK installed in your project
Step 1: Install the SDK
Install the Ductape SDK:
- TypeScript
- Java
- Go
- .NET
npm install @ductape/sdk@0.1.8
<dependency>
<groupId>app.ductape</groupId>
<artifactId>sdk</artifactId>
<version>0.1.8</version>
</dependency>
go get github.com/ductape/ductape/sdk/go@v0.1.8
dotnet add package Ductape.Sdk --version 0.1.8
The SDK includes all graph database drivers (Neo4j, Neptune, ArangoDB, Memgraph) out of the box.
Step 2: Initialize the SDK
Set up the Ductape SDK with your credentials:
- TypeScript
- Java
- Go
- .NET
import Ductape from '@ductape/sdk';
const ductape = new Ductape({
accessKey: 'your-access-key',
});
import app.ductape.sdk.Ductape;
import app.ductape.sdk.core.EnvType;
import app.ductape.sdk.core.RequestContext;
RequestContext auth = new RequestContext(null, null, null, null, 'your-access-key');
Ductape ductape = new Ductape(EnvType.PRODUCTION, auth);
import (
"context"
"github.com/ductape/ductape/sdk/go/core"
ductapesdk "github.com/ductape/ductape/sdk/go/ductape"
)
auth := core.NewRequestContext("", "", "", "", 'your-access-key')
client, err := ductapesdk.New(core.EnvProduction, auth)
if err != nil {
return err
}
using Ductape.Sdk;
using Ductape.Sdk.Core;
var auth = new RequestContext(null, null, null, null, 'your-access-key', null);
var ductape = new Ductape(EnvType.Production, auth);
Set product and env on the constructor only — see SDK runtime defaults.
Step 3: Register a Graph Database
Register your graph database with environment-specific connection strings:
- TypeScript
- Java
- Go
- .NET
await ductape.graph.create({
name: 'Social Graph',
tag: 'social-graph',
type: 'neo4j',
description: 'Stores user relationships and social connections',
envs: [
{
slug: 'dev',
connection_url: 'bolt://localhost:7687',
},
{
slug: 'staging',
connection_url: 'bolt://staging-neo4j:7687',
},
{
slug: 'prd',
connection_url: 'bolt://prod-neo4j:7687',
},
],
});
ductape.graph.create(Map.of(
"name", "Social Graph",
"tag", "social-graph",
"type", "neo4j",
"description", "Stores user relationships and social connections",
envs: [
Map.of(
"slug", "dev",
"connection_url", "bolt://"localhost", 7687"
),
Map.of(
"slug", "staging",
"connection_url", "bolt://staging-"neo4j", 7687"
),
Map.of(
"slug", "prd",
"connection_url", "bolt://prod-"neo4j", 7687"
),
]
));
client.graph.create({
"name": "Social Graph",
"tag": "social-graph",
"type": "neo4j",
"description": "Stores user relationships and social connections",
envs: [
{
"slug": "dev",
"connection_url": "bolt://"localhost": 7687",
},
{
"slug": "staging",
"connection_url": "bolt://staging-"neo4j": 7687",
},
{
"slug": "prd",
"connection_url": "bolt://prod-"neo4j": 7687",
},
],
});
await ductape.graph.create({
["name"] = "Social Graph",
["tag"] = "social-graph",
["type"] = "neo4j",
["description"] = "Stores user relationships and social connections",
envs: [
{
["slug"] = "dev",
["connection_url"] = "bolt://["localhost"] = 7687",
},
{
["slug"] = "staging",
["connection_url"] = "bolt://staging-["neo4j"] = 7687",
},
{
["slug"] = "prd",
["connection_url"] = "bolt://prod-["neo4j"] = 7687",
},
],
});
Cloud-linked graphs — provision or import from AWS Neptune, GCP Spanner Graph, or Azure Cosmos DB (Gremlin).
Check tiers before provisioning Neptune or Aura instances:
- TypeScript
- Java
- Go
- .NET
const tiers = await ductape.cloud.tiers.list({ provider: 'aws', resource_type: 'graph' });
// tiers[0].tiers → [{ name: 'db.r5.large', label: 'R5 Large — 2 vCPU, 16 GB RAM', … }, …]
Map<String, Object> tiers = ductape.cloud.tiers.list(Map.of( "provider", "aws", "resource_type", "graph" ));
// tiers[0].tiers → [Map.of( "name", "db.r5.large", "label", "R5 Large — 2 vCPU, 16 GB RAM", … ), …]
tiers := client.cloud.tiers.list({ "provider": "aws", "resource_type": "graph" });
// tiers[0].tiers → [{ "name": "db.r5.large", "label": "R5 Large — 2 vCPU, 16 GB RAM", … }, …]
var tiers = await ductape.cloud.tiers.list({ ["provider"] = "aws", ["resource_type"] = "graph" });
// tiers[0].tiers → [{ ["name"] = "db.r5.large", ["label"] = "R5 Large — 2 vCPU, 16 GB RAM", … }, …]
- TypeScript
- Java
- Go
- .NET
// AWS Neptune
await ductape.graph.create({
name: 'Social Graph',
tag: 'social-graph',
type: 'neptune',
envs: [{
slug: 'prd',
cloud: 'prod_aws',
instance: 'my-neptune-cluster',
tier: 'db.r5.large', // from cloud.tiers.list()
region: 'us-east-1',
}],
});
// GCP Spanner Graph
await ductape.graph.create({
name: 'Social Graph',
tag: 'social-graph',
type: 'spanner-graph',
envs: [{
slug: 'prd',
cloud: 'gcp_prod',
instance: 'my-spanner-instance',
region: 'us-central1',
}],
});
// Azure Cosmos DB (Gremlin)
await ductape.graph.create({
name: 'Social Graph',
tag: 'social-graph',
type: 'cosmos-gremlin',
envs: [{
slug: 'prd',
cloud: 'prod_azure',
instance: 'my-cosmos-account',
region: 'eastus',
}],
});
// AWS Neptune
ductape.graph.create(Map.of(
"name", "Social Graph",
"tag", "social-graph",
"type", "neptune",
envs: [Map.of(
"slug", "prd",
"cloud", "prod_aws",
"instance", "my-neptune-cluster",
"tier", "db.r5.large", // from cloud.tiers.list()
"region", "us-east-1"
)]
));
// GCP Spanner Graph
ductape.graph.create(Map.of(
"name", "Social Graph",
"tag", "social-graph",
"type", "spanner-graph",
envs: [Map.of(
"slug", "prd",
"cloud", "gcp_prod",
"instance", "my-spanner-instance",
"region", "us-central1"
)]
));
// Azure Cosmos DB (Gremlin)
ductape.graph.create(Map.of(
"name", "Social Graph",
"tag", "social-graph",
"type", "cosmos-gremlin",
envs: [Map.of(
"slug", "prd",
"cloud", "prod_azure",
"instance", "my-cosmos-account",
"region", "eastus"
)]
));
// AWS Neptune
client.graph.create({
"name": "Social Graph",
"tag": "social-graph",
"type": "neptune",
envs: [{
"slug": "prd",
"cloud": "prod_aws",
"instance": "my-neptune-cluster",
"tier": "db.r5.large", // from cloud.tiers.list()
"region": "us-east-1",
}],
});
// GCP Spanner Graph
client.graph.create({
"name": "Social Graph",
"tag": "social-graph",
"type": "spanner-graph",
envs: [{
"slug": "prd",
"cloud": "gcp_prod",
"instance": "my-spanner-instance",
"region": "us-central1",
}],
});
// Azure Cosmos DB (Gremlin)
client.graph.create({
"name": "Social Graph",
"tag": "social-graph",
"type": "cosmos-gremlin",
envs: [{
"slug": "prd",
"cloud": "prod_azure",
"instance": "my-cosmos-account",
"region": "eastus",
}],
});
// AWS Neptune
await ductape.graph.create({
["name"] = "Social Graph",
["tag"] = "social-graph",
["type"] = "neptune",
envs: [{
["slug"] = "prd",
["cloud"] = "prod_aws",
["instance"] = "my-neptune-cluster",
["tier"] = "db.r5.large", // from cloud.tiers.list()
["region"] = "us-east-1",
}],
});
// GCP Spanner Graph
await ductape.graph.create({
["name"] = "Social Graph",
["tag"] = "social-graph",
["type"] = "spanner-graph",
envs: [{
["slug"] = "prd",
["cloud"] = "gcp_prod",
["instance"] = "my-spanner-instance",
["region"] = "us-central1",
}],
});
// Azure Cosmos DB (Gremlin)
await ductape.graph.create({
["name"] = "Social Graph",
["tag"] = "social-graph",
["type"] = "cosmos-gremlin",
envs: [{
["slug"] = "prd",
["cloud"] = "prod_azure",
["instance"] = "my-cosmos-account",
["region"] = "eastus",
}],
});
See Cloud-linked components for the full tier reference and service matrix.
Graph Database Configuration Fields
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Human-readable display name |
tag | string | Yes | Unique identifier for the graph database |
type | string | Yes | Database type: neo4j, neptune, spanner-graph, cosmos-gremlin, arangodb, or memgraph |
description | string | No | Description of what the graph stores |
envs | array | Yes | Environment-specific connection configurations |
Environment Configuration
| Field | Type | Required | Description |
|---|---|---|---|
slug | string | Yes | Environment identifier (e.g., dev, staging, prd) |
connection_url | string | Yes* | Graph database connection string |
cloud | string | No | Workspace cloud connection tag (imports/provisions Neptune or Cosmos Gremlin) |
instance | string | No | Cloud resource name when using cloud |
database | string | No | Database name (ArangoDB) |
graphName | string | No | Graph name (ArangoDB) |
region | string | No | AWS region (Neptune) |
Step 4: Connect to Your Graph Database
Before running operations, establish a connection:
- TypeScript
- Java
- Go
- .NET
const result = await ductape.graph.connect({
graph: 'social-graph',
});
console.log('Connected:', result.connected);
console.log('Database Type:', result.type);
console.log('Latency:', result.latency, 'ms');
Map<String, Object> result = ductape.graphs().connect(Map<String, Object>.of(
"graph", "social-graph"
));
System.out.println('"Connected", ", result.connected);
System.out.println("Database "Type", ", result.type);
System.out.println(""Latency", ", result.latency, "ms');
import "context"
result := client.GraphAPI.Connect(ctx, map[string]any{
"graph": "social-graph",
});
fmt.Println('"Connected": ", result.connected);
fmt.Println("Database "Type": ", result.type);
fmt.Println(""Latency": ", result.latency, "ms');
var result = await ductape.Graph.Connect(new Dictionary<string, object?>
{
["graph"] = "social-graph",
});
Console.WriteLine('["Connected"] = ", result.connected);
Console.WriteLine("Database ["Type"] = ", result.type);
Console.WriteLine("["Latency"] = ", result.latency, "ms');
Once connected, subsequent operations inherit the connection context. You no longer need to specify env, product, or graph on every operation (constructor defaults apply before connect; connection context applies after).
Step 5: Create Your First Node
With the connection established, create a node in your graph:
- TypeScript
- Java
- Go
- .NET
// Create a person node
const result = await ductape.graph.createNode({
labels: ['Person'],
properties: {
name: 'Alice Johnson',
email: 'alice@example.com',
age: 28,
city: 'San Francisco',
joined: new Date(),
},
});
console.log('Created node ID:', result.node.id);
console.log('Node data:', result.node.properties);
// Create a person node
Map<String, Object> result = ductape.graph.createNode(Map.of(
labels: ['Person'],
properties: Map.of(
"name", "Alice Johnson",
"email", "alice@example.com",
"age", 28,
"city", "San Francisco",
joined: Instant.now()
)
));
System.out.println('Created node "ID", ", result.node.id);
System.out.println("Node data:', result.node.properties);
// Create a person node
result := client.graph.createNode({
labels: ['Person'],
properties: {
"name": "Alice Johnson",
"email": "alice@example.com",
"age": 28,
"city": "San Francisco",
joined: new Date(),
},
});
fmt.Println('Created node "ID": ", result.node.id);
fmt.Println("Node data:', result.node.properties);
// Create a person node
var result = await ductape.graph.createNode({
labels: ['Person'],
properties: {
["name"] = "Alice Johnson",
["email"] = "alice@example.com",
["age"] = 28,
["city"] = "San Francisco",
joined: DateTime.UtcNow,
},
});
Console.WriteLine('Created node ["ID"] = ", result.node.id);
Console.WriteLine("Node data:', result.node.properties);
Step 6: Create a Relationship
Connect nodes with a relationship:
- TypeScript
- Java
- Go
- .NET
// Create another person
const bobResult = await ductape.graph.createNode({
labels: ['Person'],
properties: {
name: 'Bob Smith',
email: 'bob@example.com',
age: 32,
},
});
// Create a friendship relationship
const friendship = await ductape.graph.createRelationship({
type: 'FRIENDS_WITH',
startNodeId: result.node.id, // Alice
endNodeId: bobResult.node.id, // Bob
properties: {
since: 2020,
closeness: 'high',
metAt: 'conference',
},
});
console.log('Created relationship:', friendship.relationship.id);
// Create another person
Map<String, Object> bobResult = ductape.graph.createNode(Map.of(
labels: ['Person'],
properties: Map.of(
"name", "Bob Smith",
"email", "bob@example.com",
"age", 32
)
));
// Create a friendship relationship
Map<String, Object> friendship = ductape.graph.createRelationship(Map.of(
"type", "FRIENDS_WITH",
startNodeId: result.node.id, // Alice
endNodeId: bobResult.node.id, // Bob
properties: Map.of(
"since", 2020,
"closeness", "high",
"metAt", "conference"
)
));
System.out.println('Created relationship:', friendship.relationship.id);
// Create another person
bobResult := client.graph.createNode({
labels: ['Person'],
properties: {
"name": "Bob Smith",
"email": "bob@example.com",
"age": 32,
},
});
// Create a friendship relationship
friendship := client.graph.createRelationship({
"type": "FRIENDS_WITH",
startNodeId: result.node.id, // Alice
endNodeId: bobResult.node.id, // Bob
properties: {
"since": 2020,
"closeness": "high",
"metAt": "conference",
},
});
fmt.Println('Created relationship:', friendship.relationship.id);
// Create another person
var bobResult = await ductape.graph.createNode({
labels: ['Person'],
properties: {
["name"] = "Bob Smith",
["email"] = "bob@example.com",
["age"] = 32,
},
});
// Create a friendship relationship
var friendship = await ductape.graph.createRelationship({
["type"] = "FRIENDS_WITH",
startNodeId: result.node.id, // Alice
endNodeId: bobResult.node.id, // Bob
properties: {
["since"] = 2020,
["closeness"] = "high",
["metAt"] = "conference",
},
});
Console.WriteLine('Created relationship:', friendship.relationship.id);
Step 7: Query Your Graph
Find nodes using filters:
- TypeScript
- Java
- Go
- .NET
// Find all people in San Francisco
const people = await ductape.graph.findNodes({
labels: ['Person'],
where: { city: 'San Francisco' },
limit: 10,
});
console.log('Found people:', people.nodes.length);
people.nodes.forEach(person => {
console.log(`${person.properties.name} - ${person.properties.email}`);
});
// Find all people in San Francisco
Map<String, Object> people = ductape.graph.findNodes(Map.of(
labels: ['Person'],
where: Map.of( "city", "San Francisco" ),
"limit", 10
));
System.out.println('Found people:', people.nodes.length);
people.nodes.forEach(person => Map.of(
System.out.println(`$Map.of(person.properties.name) - $Map.of(person.properties.email)`);
));
// Find all people in San Francisco
people := client.graph.findNodes({
labels: ['Person'],
where: { "city": "San Francisco" },
"limit": 10,
});
fmt.Println('Found people:', people.nodes.length);
people.nodes.forEach(person => {
fmt.Println(`${person.properties.name} - ${person.properties.email}`);
});
// Find all people in San Francisco
var people = await ductape.graph.findNodes({
labels: ['Person'],
where: { ["city"] = "San Francisco" },
["limit"] = 10,
});
Console.WriteLine('Found people:', people.nodes.length);
people.nodes.forEach(person => {
Console.WriteLine(`${person.properties.name} - ${person.properties.email}`);
});
Complete Example
Here's a complete example bringing it all together:
- TypeScript
- Java
- Go
- .NET
import Ductape from '@ductape/sdk';
async function main() {
// Initialize SDK
const ductape = new Ductape({
accessKey: 'your-access-key',
});
// Register graph database (usually done once during setup)
await ductape.graph.create({
name: 'Social Graph',
tag: 'social-graph',
type: 'neo4j',
description: 'User relationships',
envs: [
{ slug: 'dev', connection_url: 'bolt://localhost:7687' },
{ slug: 'prd', connection_url: 'bolt://prod-neo4j:7687' },
],
});
// Connect to graph database
await ductape.graph.connect({ graph: 'social-graph' });
// Create nodes
const alice = await ductape.graph.createNode({
labels: ['Person'],
properties: {
name: 'Alice Johnson',
email: 'alice@example.com',
role: 'Engineer',
},
});
const bob = await ductape.graph.createNode({
labels: ['Person'],
properties: {
name: 'Bob Smith',
email: 'bob@example.com',
role: 'Designer',
},
});
// Create relationship
await ductape.graph.createRelationship({
type: 'WORKS_WITH',
startNodeId: alice.node.id,
endNodeId: bob.node.id,
properties: { team: 'Product', since: 2023 },
});
// Query the graph
const engineers = await ductape.graph.findNodes({
labels: ['Person'],
where: { role: 'Engineer' },
});
console.log('Engineers:', engineers.nodes.map(n => n.properties.name));
// Find Alice's connections
const connections = await ductape.graph.traverse({
startNodeId: alice.node.id,
direction: 'OUTGOING',
relationshipTypes: ['WORKS_WITH'],
maxDepth: 1,
});
console.log('Alice works with:', connections.paths.length, 'people');
// Close connection when done
await ductape.graph.disconnect();
}
main().catch(console.error);
import app.ductape.sdk.Ductape;
import app.ductape.sdk.core.EnvType;
import app.ductape.sdk.core.RequestContext;
async function main() Map.of(
// Initialize SDK
RequestContext auth = new RequestContext(null, null, null, null, 'your-access-key');
Ductape ductape = new Ductape(EnvType.PRODUCTION, auth);
// Register graph database (usually done once during setup)
ductape.graph.create(Map.of(
"name", "Social Graph",
"tag", "social-graph",
"type", "neo4j",
"description", "User relationships",
envs: [
Map.of( "slug", "dev", "connection_url", "bolt://"localhost", 7687" ),
Map.of( "slug", "prd", "connection_url", "bolt://prod-"neo4j", 7687" ),
]
));
// Connect to graph database
ductape.graphs().connect(Map<String, Object>.of(
"graph", "social-graph" ));
// Create nodes
Map<String, Object> alice = ductape.graph.createNode(Map.of(
labels: ['Person'],
properties: Map.of(
"name", "Alice Johnson",
"email", "alice@example.com",
"role", "Engineer"
)
));
Map<String, Object> bob = ductape.graph.createNode(Map.of(
labels: ['Person'],
properties: Map.of(
"name", "Bob Smith",
"email", "bob@example.com",
"role", "Designer"
)
));
// Create relationship
ductape.graph.createRelationship(Map.of(
"type", "WORKS_WITH",
startNodeId: alice.node.id,
endNodeId: bob.node.id,
properties: Map.of( "team", "Product", "since", 2023 )
));
// Query the graph
Map<String, Object> engineers = ductape.graph.findNodes(Map.of(
labels: ['Person'],
where: Map.of( "role", "Engineer" )
));
System.out.println('"Engineers", ", engineers.nodes.map(n => n.properties.name));
// Find Alice"s connections
Map<String, Object> connections = ductape.graphs().traverse(Map<String, Object>.of(
startNodeId: alice.node.id,
"direction", "OUTGOING",
relationshipTypes: ['WORKS_WITH'],
"maxDepth", 1
));
System.out.println('Alice works "with", ", connections.paths.length, "people');
// Close connection when done
ductape.graph.disconnect();
)
main();
import (
"context"
"github.com/ductape/ductape/sdk/go/core"
ductapesdk "github.com/ductape/ductape/sdk/go/ductape"
)
async function main() {
// Initialize SDK
auth := core.NewRequestContext("", "", "", "", 'your-access-key')
client, err := ductapesdk.New(core.EnvProduction, auth)
if err != nil {
return err
}
// Register graph database (usually done once during setup)
client.graph.create({
"name": "Social Graph",
"tag": "social-graph",
"type": "neo4j",
"description": "User relationships",
envs: [
{ "slug": "dev", "connection_url": "bolt://"localhost": 7687" },
{ "slug": "prd", "connection_url": "bolt://prod-"neo4j": 7687" },
],
});
// Connect to graph database
client.GraphAPI.Connect(ctx, map[string]any{
"graph": "social-graph" });
// Create nodes
alice := client.graph.createNode({
labels: ['Person'],
properties: {
"name": "Alice Johnson",
"email": "alice@example.com",
"role": "Engineer",
},
});
bob := client.graph.createNode({
labels: ['Person'],
properties: {
"name": "Bob Smith",
"email": "bob@example.com",
"role": "Designer",
},
});
// Create relationship
client.graph.createRelationship({
"type": "WORKS_WITH",
startNodeId: alice.node.id,
endNodeId: bob.node.id,
properties: { "team": "Product", "since": 2023 },
});
// Query the graph
engineers := client.graph.findNodes({
labels: ['Person'],
where: { "role": "Engineer" },
});
fmt.Println('"Engineers": ", engineers.nodes.map(n => n.properties.name));
// Find Alice"s connections
connections := client.graph.traverse({
startNodeId: alice.node.id,
"direction": "OUTGOING",
relationshipTypes: ['WORKS_WITH'],
"maxDepth": 1,
});
fmt.Println('Alice works "with": ", connections.paths.length, "people');
// Close connection when done
client.graph.disconnect();
}
main().catch(console.error);
using Ductape.Sdk;
using Ductape.Sdk.Core;
async function main() {
// Initialize SDK
var auth = new RequestContext(null, null, null, null, 'your-access-key', null);
var ductape = new Ductape(EnvType.Production, auth);
// Register graph database (usually done once during setup)
await ductape.graph.create({
["name"] = "Social Graph",
["tag"] = "social-graph",
["type"] = "neo4j",
["description"] = "User relationships",
envs: [
{ ["slug"] = "dev", ["connection_url"] = "bolt://["localhost"] = 7687" },
{ ["slug"] = "prd", ["connection_url"] = "bolt://prod-["neo4j"] = 7687" },
],
});
// Connect to graph database
await ductape.Graph.Connect(new Dictionary<string, object?>
{
["graph"] = "social-graph" });
// Create nodes
var alice = await ductape.graph.createNode({
labels: ['Person'],
properties: {
["name"] = "Alice Johnson",
["email"] = "alice@example.com",
["role"] = "Engineer",
},
});
var bob = await ductape.graph.createNode({
labels: ['Person'],
properties: {
["name"] = "Bob Smith",
["email"] = "bob@example.com",
["role"] = "Designer",
},
});
// Create relationship
await ductape.graph.createRelationship({
["type"] = "WORKS_WITH",
startNodeId: alice.node.id,
endNodeId: bob.node.id,
properties: { ["team"] = "Product", ["since"] = 2023 },
});
// Query the graph
var engineers = await ductape.graph.findNodes({
labels: ['Person'],
where: { ["role"] = "Engineer" },
});
Console.WriteLine('["Engineers"] = ", engineers.nodes.map(n => n.properties.name));
// Find Alice"s connections
var connections = await ductape.graph.traverse({
startNodeId: alice.node.id,
["direction"] = "OUTGOING",
relationshipTypes: ['WORKS_WITH'],
["maxDepth"] = 1,
});
Console.WriteLine('Alice works ["with"] = ", connections.paths.length, "people');
// Close connection when done
await ductape.graph.disconnect();
}
main().catch(console.error);
Testing Your Connection
Use the testConnection method to verify connectivity without performing operations:
- TypeScript
- Java
- Go
- .NET
const result = await ductape.graph.testConnection({
graph: 'social-graph',
});
if (result.connected) {
console.log('Connection successful!');
console.log('Type:', result.type);
console.log('Version:', result.version);
console.log('Latency:', result.latency, 'ms');
} else {
console.error('Connection failed:', result.error);
}
Map<String, Object> result = ductape.graph.testConnection(Map.of(
"graph", "social-graph"
));
if (result.connected) Map.of(
System.out.println('Connection successful!');
System.out.println('"Type", ", result.type);
System.out.println(""Version", ", result.version);
System.out.println(""Latency", ", result.latency, "ms');
) else Map.of(
console.error('Connection failed:', result.error);
)
result := client.graph.testConnection({
"graph": "social-graph",
});
if (result.connected) {
fmt.Println('Connection successful!');
fmt.Println('"Type": ", result.type);
fmt.Println(""Version": ", result.version);
fmt.Println(""Latency": ", result.latency, "ms');
} else {
console.error('Connection failed:', result.error);
}
var result = await ductape.graph.testConnection({
["graph"] = "social-graph",
});
if (result.connected) {
Console.WriteLine('Connection successful!');
Console.WriteLine('["Type"] = ", result.type);
Console.WriteLine("["Version"] = ", result.version);
Console.WriteLine("["Latency"] = ", result.latency, "ms');
} else {
console.error('Connection failed:', result.error);
}
Managing Multiple Graph Databases
You can register and use multiple graph databases in a single product:
- TypeScript
- Java
- Go
- .NET
// Register multiple graph databases
await ductape.graph.create({
name: 'Social Graph',
tag: 'social-graph',
type: 'neo4j',
envs: [{ slug: 'dev', connection_url: 'bolt://localhost:7687' }],
});
await ductape.graph.create({
name: 'Knowledge Graph',
tag: 'knowledge-graph',
type: 'arangodb',
envs: [{
slug: 'dev',
connection_url: 'http://localhost:8529',
database: 'knowledge',
graphName: 'entities',
}],
});
await ductape.graph.create({
name: 'Network Graph',
tag: 'network-graph',
type: 'memgraph',
envs: [{ slug: 'dev', connection_url: 'bolt://localhost:7688' }],
});
// Switch between graphs by connecting to each (product/env from constructor)
await ductape.graph.connect({ graph: 'social-graph' });
// Query social graph
const users = await ductape.graph.findNodes({ labels: ['Person'] });
// Connect to different graph
await ductape.graph.connect({ graph: 'knowledge-graph' });
// Query knowledge graph
const entities = await ductape.graph.findNodes({ labels: ['Entity'] });
// Register multiple graph databases
ductape.graph.create(Map.of(
"name", "Social Graph",
"tag", "social-graph",
"type", "neo4j",
envs: [Map.of( "slug", "dev", "connection_url", "bolt://"localhost", 7687" )]
));
ductape.graph.create(Map.of(
"name", "Knowledge Graph",
"tag", "knowledge-graph",
"type", "arangodb",
envs: [Map.of(
"slug", "dev",
"connection_url", "http://"localhost", 8529",
"database", "knowledge",
"graphName", "entities"
)]
));
ductape.graph.create(Map.of(
"name", "Network Graph",
"tag", "network-graph",
"type", "memgraph",
envs: [Map.of( "slug", "dev", "connection_url", "bolt://"localhost", 7688" )]
));
// Switch between graphs by connecting to each (product/env from constructor)
ductape.graphs().connect(Map<String, Object>.of(
"graph", "social-graph" ));
// Query social graph
Map<String, Object> users = ductape.graph.findNodes(Map.of( labels: ['Person'] ));
// Connect to different graph
ductape.graphs().connect(Map<String, Object>.of(
"graph", "knowledge-graph" ));
// Query knowledge graph
Map<String, Object> entities = ductape.graph.findNodes(Map.of( labels: ['Entity'] ));
import "context"
// Register multiple graph databases
client.graph.create({
"name": "Social Graph",
"tag": "social-graph",
"type": "neo4j",
envs: [{ "slug": "dev", "connection_url": "bolt://"localhost": 7687" }],
});
client.graph.create({
"name": "Knowledge Graph",
"tag": "knowledge-graph",
"type": "arangodb",
envs: [{
"slug": "dev",
"connection_url": "http://"localhost": 8529",
"database": "knowledge",
"graphName": "entities",
}],
});
client.graph.create({
"name": "Network Graph",
"tag": "network-graph",
"type": "memgraph",
envs: [{ "slug": "dev", "connection_url": "bolt://"localhost": 7688" }],
});
// Switch between graphs by connecting to each (product/env from constructor)
client.GraphAPI.Connect(ctx, map[string]any{
"graph": "social-graph" });
// Query social graph
users := client.graph.findNodes({ labels: ['Person'] });
// Connect to different graph
client.GraphAPI.Connect(ctx, map[string]any{
"graph": "knowledge-graph" });
// Query knowledge graph
entities := client.graph.findNodes({ labels: ['Entity'] });
// Register multiple graph databases
await ductape.graph.create({
["name"] = "Social Graph",
["tag"] = "social-graph",
["type"] = "neo4j",
envs: [{ ["slug"] = "dev", ["connection_url"] = "bolt://["localhost"] = 7687" }],
});
await ductape.graph.create({
["name"] = "Knowledge Graph",
["tag"] = "knowledge-graph",
["type"] = "arangodb",
envs: [{
["slug"] = "dev",
["connection_url"] = "http://["localhost"] = 8529",
["database"] = "knowledge",
["graphName"] = "entities",
}],
});
await ductape.graph.create({
["name"] = "Network Graph",
["tag"] = "network-graph",
["type"] = "memgraph",
envs: [{ ["slug"] = "dev", ["connection_url"] = "bolt://["localhost"] = 7688" }],
});
// Switch between graphs by connecting to each (product/env from constructor)
await ductape.Graph.Connect(new Dictionary<string, object?>
{
["graph"] = "social-graph" });
// Query social graph
var users = await ductape.graph.findNodes({ labels: ['Person'] });
// Connect to different graph
await ductape.Graph.Connect(new Dictionary<string, object?>
{
["graph"] = "knowledge-graph" });
// Query knowledge graph
var entities = await ductape.graph.findNodes({ labels: ['Entity'] });
Updating Graph Configuration
Update an existing graph database configuration:
- TypeScript
- Java
- Go
- .NET
await ductape.graph.update('social-graph', {
name: 'Social Graph v2',
description: 'Updated social network graph',
envs: [
{ slug: 'dev', connection_url: 'bolt://new-dev-host:7687' },
{ slug: 'prd', connection_url: 'bolt://new-prod-host:7687' },
],
});
ductape.graph.update('social-graph', Map.of(
"name", "Social Graph v2",
"description", "Updated social network graph",
envs: [
Map.of( "slug", "dev", "connection_url", "bolt://new-dev-"host", 7687" ),
Map.of( "slug", "prd", "connection_url", "bolt://new-prod-"host", 7687" ),
]
));
client.graph.update('social-graph', {
"name": "Social Graph v2",
"description": "Updated social network graph",
envs: [
{ "slug": "dev", "connection_url": "bolt://new-dev-"host": 7687" },
{ "slug": "prd", "connection_url": "bolt://new-prod-"host": 7687" },
],
});
await ductape.graph.update('social-graph', {
["name"] = "Social Graph v2",
["description"] = "Updated social network graph",
envs: [
{ ["slug"] = "dev", ["connection_url"] = "bolt://new-dev-["host"] = 7687" },
{ ["slug"] = "prd", ["connection_url"] = "bolt://new-prod-["host"] = 7687" },
],
});
Fetching Graph Information
Retrieve information about your registered graph databases:
- TypeScript
- Java
- Go
- .NET
// Get all graphs in the product
const graphs = await ductape.graph.fetchAll();
graphs.forEach((graph) => {
console.log(`${graph.name} (${graph.tag}): ${graph.type}`);
});
// Get a specific graph
const socialGraph = await ductape.graph.fetch('social-graph');
console.log('Graph:', socialGraph.name);
console.log('Type:', socialGraph.type);
console.log('Environments:', socialGraph.envs);
// Get all graphs in the product
Map<String, Object> graphs = ductape.graph.fetchAll();
graphs.forEach((graph) => Map.of(
System.out.println(`$Map.of(graph.name) ($Map.of(graph.tag)): $Map.of(graph.type)`);
));
// Get a specific graph
Map<String, Object> socialGraph = ductape.graph.fetch('social-graph');
System.out.println('"Graph", ", socialGraph.name);
System.out.println(""Type", ", socialGraph.type);
System.out.println("Environments:', socialGraph.envs);
// Get all graphs in the product
graphs := client.graph.fetchAll();
graphs.forEach((graph) => {
fmt.Println(`${graph.name} (${graph.tag}): ${graph.type}`);
});
// Get a specific graph
socialGraph := client.graph.fetch('social-graph');
fmt.Println('"Graph": ", socialGraph.name);
fmt.Println(""Type": ", socialGraph.type);
fmt.Println("Environments:', socialGraph.envs);
// Get all graphs in the product
var graphs = await ductape.graph.fetchAll();
graphs.forEach((graph) => {
Console.WriteLine(`${graph.name} (${graph.tag}): ${graph.type}`);
});
// Get a specific graph
var socialGraph = await ductape.graph.fetch('social-graph');
Console.WriteLine('["Graph"] = ", socialGraph.name);
Console.WriteLine("["Type"] = ", socialGraph.type);
Console.WriteLine("Environments:', socialGraph.envs);
Connection String Formats
Neo4j
bolt://hostname:7687
bolt://username:password@hostname:7687
bolt+s://hostname:7687 # with TLS
bolt+ssc://hostname:7687 # with self-signed cert
neo4j://hostname:7687 # routing
AWS Neptune
wss://cluster.region.neptune.amazonaws.com:8182/gremlin
https://cluster.region.neptune.amazonaws.com:8182/openCypher
ArangoDB
http://hostname:8529
https://hostname:8529
http://username:password@hostname:8529
Memgraph
bolt://hostname:7687
bolt://username:password@hostname:7687
bolt+ssc://hostname:7687 # with TLS
Common Patterns
Find or Create Pattern
Ensure a node exists, creating it only if needed:
- TypeScript
- Java
- Go
- .NET
const person = await ductape.graph.mergeNode({
labels: ['Person'],
matchProperties: { email: 'alice@example.com' },
onCreate: {
name: 'Alice Johnson',
email: 'alice@example.com',
createdAt: new Date(),
},
onMatch: {
lastSeen: new Date(),
},
});
console.log(person.created ? 'Created new node' : 'Found existing node');
Map<String, Object> person = ductape.graph.mergeNode(Map.of(
labels: ['Person'],
matchProperties: Map.of( "email", "alice@example.com" ),
onCreate: Map.of(
"name", "Alice Johnson",
"email", "alice@example.com",
createdAt: Instant.now()
),
onMatch: Map.of(
lastSeen: Instant.now()
)
));
System.out.println(person.created ? 'Created new node' : 'Found existing node');
person := client.graph.mergeNode({
labels: ['Person'],
matchProperties: { "email": "alice@example.com" },
onCreate: {
"name": "Alice Johnson",
"email": "alice@example.com",
createdAt: new Date(),
},
onMatch: {
lastSeen: new Date(),
},
});
fmt.Println(person.created ? 'Created new node' : 'Found existing node');
var person = await ductape.graph.mergeNode({
labels: ['Person'],
matchProperties: { ["email"] = "alice@example.com" },
onCreate: {
["name"] = "Alice Johnson",
["email"] = "alice@example.com",
createdAt: DateTime.UtcNow,
},
onMatch: {
lastSeen: DateTime.UtcNow,
},
});
Console.WriteLine(person.created ? 'Created new node' : 'Found existing node');
Batch Operations
Create multiple nodes efficiently:
- TypeScript
- Java
- Go
- .NET
const people = [
{ name: 'Alice', email: 'alice@example.com' },
{ name: 'Bob', email: 'bob@example.com' },
{ name: 'Charlie', email: 'charlie@example.com' },
];
for (const person of people) {
await ductape.graph.createNode({
labels: ['Person'],
properties: person,
});
}
Map<String, Object> people = [
Map.of( "name", "Alice", "email", "alice@example.com" ),
Map.of( "name", "Bob", "email", "bob@example.com" ),
Map.of( "name", "Charlie", "email", "charlie@example.com" ),
];
for (Map<String, Object> person of people) Map.of(
ductape.graph.createNode(Map.of(
labels: ['Person'],
properties: person
));
)
people := [
{ "name": "Alice", "email": "alice@example.com" },
{ "name": "Bob", "email": "bob@example.com" },
{ "name": "Charlie", "email": "charlie@example.com" },
];
for (const person of people) {
client.graph.createNode({
labels: ['Person'],
properties: person,
});
}
var people = [
{ ["name"] = "Alice", ["email"] = "alice@example.com" },
{ ["name"] = "Bob", ["email"] = "bob@example.com" },
{ ["name"] = "Charlie", ["email"] = "charlie@example.com" },
];
for (var person of people) {
await ductape.graph.createNode({
labels: ['Person'],
properties: person,
});
}
Finding Paths
Discover how nodes are connected:
- TypeScript
- Java
- Go
- .NET
const path = await ductape.graph.shortestPath({
startNodeId: aliceId,
endNodeId: charlieId,
relationshipTypes: ['FRIENDS_WITH'],
});
if (path.path) {
console.log(`Path length: ${path.path.length}`);
console.log('Connected through:', path.path.nodes.map(n => n.properties.name));
}
Map<String, Object> path = ductape.graph.shortestPath(Map.of(
startNodeId: aliceId,
endNodeId: charlieId,
relationshipTypes: ['FRIENDS_WITH']
));
if (path.path) Map.of(
System.out.println(`Path length: $Map.of(path.path.length)`);
System.out.println('Connected through:', path.path.nodes.map(n => n.properties.name));
)
path := client.graph.shortestPath({
startNodeId: aliceId,
endNodeId: charlieId,
relationshipTypes: ['FRIENDS_WITH'],
});
if (path.path) {
fmt.Println(`Path length: ${path.path.length}`);
fmt.Println('Connected through:', path.path.nodes.map(n => n.properties.name));
}
var path = await ductape.graph.shortestPath({
startNodeId: aliceId,
endNodeId: charlieId,
relationshipTypes: ['FRIENDS_WITH'],
});
if (path.path) {
Console.WriteLine(`Path length: ${path.path.length}`);
Console.WriteLine('Connected through:', path.path.nodes.map(n => n.properties.name));
}
Next Steps
Now that you have your graph database set up, learn how to:
- Work with Nodes - Create, update, query, and delete nodes
- Manage Relationships - Connect nodes with typed relationships
- Traverse Graphs - Find paths and explore neighborhoods
- Advanced Querying - Complex filters and pattern matching
- Use Transactions - Ensure data consistency
- Best Practices - Production patterns and optimization
See Also
- Graph Overview - Full API reference
- Best Practices - Performance and production patterns