or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mddriver-management.mderror-handling.mdgraph-types.mdindex.mdreactive-programming.mdsession-operations.mdtemporal-types.mdtransaction-management.md

graph-types.mddocs/

0

# Graph Data Types

1

2

Neo4j graph data types including nodes, relationships, and paths with comprehensive type checking utilities.

3

4

## Capabilities

5

6

### Node Type

7

8

Represents a node in the Neo4j graph with identity, labels, and properties.

9

10

```typescript { .api }

11

interface Node {

12

/** Unique node identity within the database */

13

identity: Integer;

14

15

/** Array of labels assigned to the node */

16

labels: string[];

17

18

/** Key-value properties stored on the node */

19

properties: Record<string, any>;

20

21

/** Convert node to string representation */

22

toString(): string;

23

}

24

25

/**

26

* Check if an object is a Neo4j Node

27

* @param obj - Object to check

28

* @returns true if object is a Node instance

29

*/

30

function isNode(obj: any): obj is Node;

31

```

32

33

**Usage Examples:**

34

35

```typescript

36

import { driver, auth, isNode } from "neo4j-driver";

37

38

const session = neo4jDriver.session();

39

40

try {

41

const result = await session.run(`

42

CREATE (p:Person:User {

43

name: $name,

44

age: $age,

45

email: $email,

46

createdAt: datetime()

47

})

48

RETURN p

49

`, {

50

name: "Alice Johnson",

51

age: 30,

52

email: "alice@example.com"

53

});

54

55

const nodeRecord = result.records[0];

56

const person = nodeRecord.get("p");

57

58

if (isNode(person)) {

59

console.log(`Node ID: ${person.identity}`);

60

console.log(`Labels: ${person.labels.join(", ")}`); // "Person, User"

61

console.log(`Name: ${person.properties.name}`); // "Alice Johnson"

62

console.log(`Age: ${person.properties.age}`); // 30

63

console.log(`Email: ${person.properties.email}`); // "alice@example.com"

64

65

// Access all properties

66

Object.entries(person.properties).forEach(([key, value]) => {

67

console.log(`${key}: ${value}`);

68

});

69

}

70

} finally {

71

await session.close();

72

}

73

```

74

75

### Relationship Type

76

77

Represents a relationship between nodes with type, properties, and endpoint references.

78

79

```typescript { .api }

80

interface Relationship {

81

/** Unique relationship identity within the database */

82

identity: Integer;

83

84

/** Identity of the start node */

85

start: Integer;

86

87

/** Identity of the end node */

88

end: Integer;

89

90

/** Relationship type name */

91

type: string;

92

93

/** Key-value properties stored on the relationship */

94

properties: Record<string, any>;

95

96

/** Convert relationship to string representation */

97

toString(): string;

98

}

99

100

/**

101

* Check if an object is a Neo4j Relationship

102

* @param obj - Object to check

103

* @returns true if object is a Relationship instance

104

*/

105

function isRelationship(obj: any): obj is Relationship;

106

```

107

108

**Usage Examples:**

109

110

```typescript

111

const result = await session.run(`

112

MATCH (p1:Person {name: $name1}), (p2:Person {name: $name2})

113

CREATE (p1)-[r:KNOWS {

114

since: date(),

115

strength: $strength,

116

context: $context

117

}]->(p2)

118

RETURN r, p1, p2

119

`, {

120

name1: "Alice",

121

name2: "Bob",

122

strength: 0.8,

123

context: "work"

124

});

125

126

const record = result.records[0];

127

const relationship = record.get("r");

128

const startNode = record.get("p1");

129

const endNode = record.get("p2");

130

131

if (isRelationship(relationship)) {

132

console.log(`Relationship ID: ${relationship.identity}`);

133

console.log(`Type: ${relationship.type}`); // "KNOWS"

134

console.log(`From: ${relationship.start} To: ${relationship.end}`);

135

console.log(`Since: ${relationship.properties.since}`);

136

console.log(`Strength: ${relationship.properties.strength}`); // 0.8

137

console.log(`Context: ${relationship.properties.context}`); // "work"

138

139

// Verify endpoints match nodes

140

console.log(`Start matches: ${relationship.start.equals(startNode.identity)}`);

141

console.log(`End matches: ${relationship.end.equals(endNode.identity)}`);

142

}

143

```

144

145

### Unbound Relationship Type

146

147

Represents relationship data without specific start/end node references.

148

149

```typescript { .api }

150

interface UnboundRelationship {

151

/** Unique relationship identity within the database */

152

identity: Integer;

153

154

/** Relationship type name */

155

type: string;

156

157

/** Key-value properties stored on the relationship */

158

properties: Record<string, any>;

159

160

/** Convert unbound relationship to string representation */

161

toString(): string;

162

}

163

164

/**

165

* Check if an object is a Neo4j UnboundRelationship

166

* @param obj - Object to check

167

* @returns true if object is an UnboundRelationship instance

168

*/

169

function isUnboundRelationship(obj: any): obj is UnboundRelationship;

170

```

171

172

**Usage Examples:**

173

174

```typescript

175

// Unbound relationships typically appear in path segments

176

const result = await session.run(`

177

MATCH path = (start:Person {name: $name})-[*1..3]-(end:Person)

178

RETURN path

179

`, { name: "Alice" });

180

181

result.records.forEach(record => {

182

const path = record.get("path");

183

184

path.segments.forEach(segment => {

185

if (isUnboundRelationship(segment.relationship)) {

186

console.log(`Unbound relationship: ${segment.relationship.type}`);

187

console.log(`Properties:`, segment.relationship.properties);

188

}

189

});

190

});

191

```

192

193

### Path Type

194

195

Represents a path through the graph containing nodes and relationships.

196

197

```typescript { .api }

198

interface Path {

199

/** Starting node of the path */

200

start: Node;

201

202

/** Ending node of the path */

203

end: Node;

204

205

/** Number of relationships in the path */

206

length: number;

207

208

/** Array of path segments (node-relationship pairs) */

209

segments: PathSegment[];

210

211

/** Array of all nodes in the path */

212

nodes: Node[];

213

214

/** Array of all relationships in the path */

215

relationships: Relationship[];

216

217

/** Convert path to string representation */

218

toString(): string;

219

}

220

221

/**

222

* Check if an object is a Neo4j Path

223

* @param obj - Object to check

224

* @returns true if object is a Path instance

225

*/

226

function isPath(obj: any): obj is Path;

227

```

228

229

**Usage Examples:**

230

231

```typescript

232

const result = await session.run(`

233

MATCH path = (start:Person {name: $name})-[:KNOWS*1..3]-(end:Person)

234

WHERE start <> end

235

RETURN path

236

LIMIT 5

237

`, { name: "Alice" });

238

239

result.records.forEach(record => {

240

const path = record.get("path");

241

242

if (isPath(path)) {

243

console.log(`Path from ${path.start.properties.name} to ${path.end.properties.name}`);

244

console.log(`Path length: ${path.length} relationships`);

245

246

// Examine each segment

247

path.segments.forEach((segment, index) => {

248

console.log(`Segment ${index + 1}:`);

249

console.log(` Node: ${segment.start.properties.name}`);

250

console.log(` Relationship: ${segment.relationship.type}`);

251

console.log(` End: ${segment.end.properties.name}`);

252

});

253

254

// Alternative: iterate through nodes and relationships

255

console.log("Path nodes:", path.nodes.map(n => n.properties.name).join(" -> "));

256

console.log("Relationship types:", path.relationships.map(r => r.type).join(", "));

257

}

258

});

259

```

260

261

### Path Segment Type

262

263

Represents a single segment of a path containing a relationship and its connected nodes.

264

265

```typescript { .api }

266

interface PathSegment {

267

/** Starting node of the segment */

268

start: Node;

269

270

/** Relationship in the segment */

271

relationship: Relationship;

272

273

/** Ending node of the segment */

274

end: Node;

275

276

/** Convert path segment to string representation */

277

toString(): string;

278

}

279

280

/**

281

* Check if an object is a Neo4j PathSegment

282

* @param obj - Object to check

283

* @returns true if object is a PathSegment instance

284

*/

285

function isPathSegment(obj: any): obj is PathSegment;

286

```

287

288

**Usage Examples:**

289

290

```typescript

291

const result = await session.run(`

292

MATCH path = (a:Person)-[r:WORKS_FOR]->(c:Company)-[r2:LOCATED_IN]->(city:City)

293

RETURN path

294

LIMIT 1

295

`);

296

297

const path = result.records[0].get("path");

298

299

if (isPath(path)) {

300

path.segments.forEach((segment, index) => {

301

if (isPathSegment(segment)) {

302

console.log(`Segment ${index + 1}:`);

303

console.log(` Start: ${segment.start.labels.join(":")} ${segment.start.properties.name}`);

304

console.log(` Relationship: ${segment.relationship.type}`);

305

console.log(` End: ${segment.end.labels.join(":")} ${segment.end.properties.name}`);

306

307

// Access relationship properties

308

if (Object.keys(segment.relationship.properties).length > 0) {

309

console.log(` Relationship properties:`, segment.relationship.properties);

310

}

311

}

312

});

313

}

314

```

315

316

### Graph Type Utilities

317

318

Utility object containing all graph type checking functions.

319

320

```typescript { .api }

321

declare const graph: {

322

/** Check if object is a Node */

323

isNode: typeof isNode;

324

325

/** Check if object is a Relationship */

326

isRelationship: typeof isRelationship;

327

328

/** Check if object is an UnboundRelationship */

329

isUnboundRelationship: typeof isUnboundRelationship;

330

331

/** Check if object is a Path */

332

isPath: typeof isPath;

333

334

/** Check if object is a PathSegment */

335

isPathSegment: typeof isPathSegment;

336

};

337

```

338

339

**Usage Examples:**

340

341

```typescript

342

import { graph } from "neo4j-driver";

343

344

const result = await session.run(`

345

MATCH path = (p:Person)-[r:KNOWS]->(friend:Person)

346

RETURN p, r, friend, path

347

LIMIT 1

348

`);

349

350

const record = result.records[0];

351

352

// Type checking with utility object

353

if (graph.isNode(record.get("p"))) {

354

console.log("Found a person node");

355

}

356

357

if (graph.isRelationship(record.get("r"))) {

358

console.log("Found a knows relationship");

359

}

360

361

if (graph.isPath(record.get("path"))) {

362

console.log("Found a friendship path");

363

}

364

365

// Generic type checking function

366

function analyzeGraphObject(obj: any, name: string) {

367

if (graph.isNode(obj)) {

368

console.log(`${name} is a Node with labels: ${obj.labels.join(", ")}`);

369

} else if (graph.isRelationship(obj)) {

370

console.log(`${name} is a Relationship of type: ${obj.type}`);

371

} else if (graph.isPath(obj)) {

372

console.log(`${name} is a Path with ${obj.length} relationships`);

373

} else if (graph.isPathSegment(obj)) {

374

console.log(`${name} is a PathSegment`);

375

} else if (graph.isUnboundRelationship(obj)) {

376

console.log(`${name} is an UnboundRelationship of type: ${obj.type}`);

377

} else {

378

console.log(`${name} is not a graph type`);

379

}

380

}

381

382

// Analyze all returned values

383

record.keys.forEach(key => {

384

analyzeGraphObject(record.get(key), key);

385

});

386

```

387

388

### Working with Complex Graph Structures

389

390

**Usage Examples:**

391

392

```typescript

393

// Complex path analysis

394

const result = await session.run(`

395

MATCH path = (person:Person {name: $name})-[:LIVES_IN]->

396

(city:City)-[:LOCATED_IN]->

397

(country:Country)

398

RETURN path, person, city, country

399

`, { name: "Alice" });

400

401

result.records.forEach(record => {

402

const path = record.get("path");

403

404

if (isPath(path)) {

405

// Analyze path structure

406

console.log(`Path: ${path.start.properties.name} lives in ${path.end.properties.name}`);

407

console.log(`Path contains ${path.nodes.length} nodes and ${path.relationships.length} relationships`);

408

409

// Extract specific information

410

const person = path.nodes.find(n => n.labels.includes("Person"));

411

const city = path.nodes.find(n => n.labels.includes("City"));

412

const country = path.nodes.find(n => n.labels.includes("Country"));

413

414

if (person && city && country) {

415

console.log(`${person.properties.name} lives in ${city.properties.name}, ${country.properties.name}`);

416

}

417

418

// Analyze relationships

419

path.relationships.forEach(rel => {

420

if (rel.type === "LIVES_IN") {

421

console.log(`Living since: ${rel.properties.since || "unknown"}`);

422

} else if (rel.type === "LOCATED_IN") {

423

console.log(`City is in country: ${rel.properties.established || "unknown"}`);

424

}

425

});

426

}

427

});

428

```