or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mddatabase-management.mdevents.mdgraph-database.mdgraph-model.mdindex.mdprocedures.mdquery-execution.mdschema.mdspatial.mdtraversal.md

query-execution.mddocs/

0

# Query Execution

1

2

Cypher query execution system providing result handling, parameter binding, execution plan analysis, and performance monitoring with support for both transactional and auto-commit query patterns.

3

4

## Capabilities

5

6

### Result Interface

7

8

Interface for handling query results with iteration, statistics access, and resource management.

9

10

```java { .api }

11

/**

12

* Iterable query result set with resource management

13

*/

14

public interface Result extends AutoCloseable {

15

16

/**

17

* Check if there are more results available

18

* @return true if more results exist, false otherwise

19

*/

20

boolean hasNext();

21

22

/**

23

* Get the next result record

24

* @return Map containing column names and values

25

* @throws NoSuchElementException if no more results

26

*/

27

Map<String, Object> next();

28

29

/**

30

* Process each remaining result with a consumer function

31

* @param action Consumer function to process each result record

32

*/

33

void forEachRemaining(Consumer<Map<String, Object>> action);

34

35

/**

36

* Get the column names in the result set

37

* @return List of column names

38

*/

39

List<String> columns();

40

41

/**

42

* Get query execution statistics

43

* @return Statistics about the query execution

44

*/

45

QueryStatistics getQueryStatistics();

46

47

/**

48

* Get the execution plan description

49

* @return Execution plan details for query optimization analysis

50

*/

51

ExecutionPlanDescription getExecutionPlanDescription();

52

53

/**

54

* Get notifications about query execution

55

* @return List of notifications (warnings, performance hints, etc.)

56

*/

57

Iterable<Notification> getNotifications();

58

59

/**

60

* Convert all results to a list of maps

61

* @return List containing all result records

62

*/

63

List<Map<String, Object>> list();

64

65

/**

66

* Transform results using a function

67

* @param mapper Function to transform each result record

68

* @return Stream of transformed results

69

*/

70

<T> Stream<T> stream(Function<Map<String, Object>, T> mapper);

71

72

/**

73

* Extract a specific column as a typed iterator

74

* @param column Column name to extract

75

* @return ResourceIterator of column values

76

*/

77

<T> ResourceIterator<T> columnAs(String column);

78

79

/**

80

* Convert the entire result to a string representation

81

* @return String representation of all results

82

*/

83

String resultAsString();

84

85

/**

86

* Write the result as a string to a PrintWriter

87

* @param writer PrintWriter to write results to

88

*/

89

void writeAsStringTo(PrintWriter writer);

90

91

/**

92

* Remove operation (explicitly unsupported)

93

* @throws UnsupportedOperationException always

94

*/

95

default void remove() {

96

throw new UnsupportedOperationException("Remove not supported on query results");

97

}

98

99

/**

100

* Close the result set and free associated resources

101

*/

102

@Override

103

void close();

104

}

105

```

106

107

**Usage Examples:**

108

109

```java

110

import org.neo4j.graphdb.Result;

111

import org.neo4j.graphdb.QueryStatistics;

112

import java.util.Map;

113

import java.util.List;

114

115

try (Transaction tx = graphDb.beginTx()) {

116

// Basic query execution and result processing

117

String query = "MATCH (p:Person)-[r:FRIENDS]->(f:Person) " +

118

"RETURN p.name as person, f.name as friend, r.since as since";

119

120

try (Result result = tx.execute(query)) {

121

// Check column names

122

System.out.println("Columns: " + result.columns());

123

124

// Process results one by one

125

while (result.hasNext()) {

126

Map<String, Object> row = result.next();

127

System.out.println(row.get("person") + " is friends with " +

128

row.get("friend") + " since " + row.get("since"));

129

}

130

131

// Get query statistics

132

QueryStatistics stats = result.getQueryStatistics();

133

System.out.println("Nodes created: " + stats.getNodesCreated());

134

System.out.println("Relationships created: " + stats.getRelationshipsCreated());

135

}

136

137

tx.commit();

138

}

139

140

// Using forEachRemaining for functional processing

141

try (Transaction tx = graphDb.beginTx()) {

142

try (Result result = tx.execute("MATCH (p:Person) RETURN p.name, p.age")) {

143

result.forEachRemaining(row -> {

144

System.out.println("Person: " + row.get("p.name") +

145

", Age: " + row.get("p.age"));

146

});

147

}

148

tx.commit();

149

}

150

151

// Convert to list for further processing

152

try (Transaction tx = graphDb.beginTx()) {

153

try (Result result = tx.execute("MATCH (p:Person) RETURN p.name as name")) {

154

List<Map<String, Object>> allResults = result.list();

155

List<String> names = allResults.stream()

156

.map(row -> (String) row.get("name"))

157

.collect(Collectors.toList());

158

}

159

tx.commit();

160

}

161

```

162

163

### Result Transformer

164

165

Interface for transforming query results in a callback pattern with proper resource management.

166

167

```java { .api }

168

/**

169

* Transform query results in a callback pattern

170

*/

171

@FunctionalInterface

172

public interface ResultTransformer<T> {

173

174

/**

175

* Transform the query result

176

* @param result Query result to transform

177

* @return Transformed result

178

* @throws Exception if transformation fails

179

*/

180

T apply(Result result) throws Exception;

181

}

182

```

183

184

**Usage Examples:**

185

186

```java

187

import org.neo4j.graphdb.ResultTransformer;

188

import java.util.ArrayList;

189

import java.util.List;

190

191

// Extract specific data from query results

192

List<String> personNames = graphDb.executeTransactionally(

193

"MATCH (p:Person) RETURN p.name as name",

194

Map.of(),

195

result -> {

196

List<String> names = new ArrayList<>();

197

result.forEachRemaining(row -> names.add((String) row.get("name")));

198

return names;

199

}

200

);

201

202

// Calculate aggregations

203

Double averageAge = graphDb.executeTransactionally(

204

"MATCH (p:Person) RETURN p.age as age",

205

Map.of(),

206

result -> {

207

List<Integer> ages = new ArrayList<>();

208

result.forEachRemaining(row -> {

209

Integer age = (Integer) row.get("age");

210

if (age != null) ages.add(age);

211

});

212

return ages.stream().mapToInt(Integer::intValue).average().orElse(0.0);

213

}

214

);

215

216

// Complex data transformation

217

Map<String, List<String>> friendships = graphDb.executeTransactionally(

218

"MATCH (p:Person)-[:FRIENDS]->(f:Person) RETURN p.name as person, f.name as friend",

219

Map.of(),

220

result -> {

221

Map<String, List<String>> friendMap = new HashMap<>();

222

result.forEachRemaining(row -> {

223

String person = (String) row.get("person");

224

String friend = (String) row.get("friend");

225

friendMap.computeIfAbsent(person, k -> new ArrayList<>()).add(friend);

226

});

227

return friendMap;

228

}

229

);

230

```

231

232

### Query Statistics

233

234

Interface providing detailed information about query execution and database changes.

235

236

```java { .api }

237

/**

238

* Statistics about query execution and database changes

239

*/

240

public interface QueryStatistics {

241

242

/**

243

* Get the number of nodes created by the query

244

* @return Number of nodes created

245

*/

246

int getNodesCreated();

247

248

/**

249

* Get the number of nodes deleted by the query

250

* @return Number of nodes deleted

251

*/

252

int getNodesDeleted();

253

254

/**

255

* Get the number of relationships created by the query

256

* @return Number of relationships created

257

*/

258

int getRelationshipsCreated();

259

260

/**

261

* Get the number of relationships deleted by the query

262

* @return Number of relationships deleted

263

*/

264

int getRelationshipsDeleted();

265

266

/**

267

* Get the number of properties set by the query

268

* @return Number of properties set

269

*/

270

int getPropertiesSet();

271

272

/**

273

* Get the number of labels added by the query

274

* @return Number of labels added

275

*/

276

int getLabelsAdded();

277

278

/**

279

* Get the number of labels removed by the query

280

* @return Number of labels removed

281

*/

282

int getLabelsRemoved();

283

284

/**

285

* Get the number of indexes added by the query

286

* @return Number of indexes added

287

*/

288

int getIndexesAdded();

289

290

/**

291

* Get the number of indexes removed by the query

292

* @return Number of indexes removed

293

*/

294

int getIndexesRemoved();

295

296

/**

297

* Get the number of constraints added by the query

298

* @return Number of constraints added

299

*/

300

int getConstraintsAdded();

301

302

/**

303

* Get the number of constraints removed by the query

304

* @return Number of constraints removed

305

*/

306

int getConstraintsRemoved();

307

308

/**

309

* Check if the query contained any updates

310

* @return true if any database changes were made

311

*/

312

boolean containsUpdates();

313

314

/**

315

* Check if the query contained system updates

316

* @return true if system-level changes were made

317

*/

318

boolean containsSystemUpdates();

319

}

320

```

321

322

### Execution Plan Description

323

324

Interface for accessing query execution plan information for performance analysis and optimization.

325

326

```java { .api }

327

/**

328

* Access to query execution plan information

329

*/

330

public interface ExecutionPlanDescription {

331

332

/**

333

* Get the name of this execution step

334

* @return Step name (e.g., "NodeByLabelScan", "Expand")

335

*/

336

String getName();

337

338

/**

339

* Get the children of this execution step

340

* @return List of child execution steps

341

*/

342

List<ExecutionPlanDescription> getChildren();

343

344

/**

345

* Get the arguments for this execution step

346

* @return Map of argument names to values

347

*/

348

Map<String, Object> getArguments();

349

350

/**

351

* Get identifiers introduced by this step

352

* @return Set of identifier names

353

*/

354

Set<String> getIdentifiers();

355

356

/**

357

* Check if this execution plan has profile information

358

* @return true if profiling data is available

359

*/

360

boolean hasProfilerStatistics();

361

362

/**

363

* Get profiler statistics for this step

364

* @return Profiler statistics, or null if not available

365

*/

366

ProfilerStatistics getProfilerStatistics();

367

}

368

```

369

370

### Profiler Statistics

371

372

Interface for accessing detailed execution statistics when query profiling is enabled.

373

374

```java { .api }

375

/**

376

* Detailed execution statistics for query profiling

377

*/

378

public interface ProfilerStatistics {

379

380

/**

381

* Get the number of rows produced by this step

382

* @return Number of rows

383

*/

384

long getRows();

385

386

/**

387

* Get the number of database hits for this step

388

* @return Number of database hits

389

*/

390

long getDbHits();

391

392

/**

393

* Get the page cache hits for this step

394

* @return Number of page cache hits

395

*/

396

long getPageCacheHits();

397

398

/**

399

* Get the page cache misses for this step

400

* @return Number of page cache misses

401

*/

402

long getPageCacheMisses();

403

404

/**

405

* Get the time spent in this step

406

* @return Time in milliseconds

407

*/

408

long getTime();

409

}

410

```

411

412

### Notification System

413

414

Interface for query execution notifications including warnings and performance hints.

415

416

```java { .api }

417

/**

418

* Notification about query execution

419

*/

420

public interface Notification {

421

422

/**

423

* Get the notification code

424

* @return Notification code

425

*/

426

String getCode();

427

428

/**

429

* Get the notification title

430

* @return Notification title

431

*/

432

String getTitle();

433

434

/**

435

* Get the notification description

436

* @return Detailed description

437

*/

438

String getDescription();

439

440

/**

441

* Get the severity level of this notification

442

* @return Severity level (WARNING, INFORMATION)

443

*/

444

NotificationSeverity getSeverity();

445

446

/**

447

* Get the position in the query where this notification applies

448

* @return Input position, or null if not applicable

449

*/

450

InputPosition getPosition();

451

}

452

453

/**

454

* Severity levels for notifications

455

*/

456

public enum NotificationSeverity {

457

WARNING,

458

INFORMATION

459

}

460

```

461

462

**Advanced Usage Examples:**

463

464

```java

465

// Query with execution plan analysis

466

try (Transaction tx = graphDb.beginTx()) {

467

String query = "PROFILE MATCH (p:Person)-[:FRIENDS]->(f:Person) " +

468

"WHERE p.age > 25 RETURN p.name, f.name";

469

470

try (Result result = tx.execute(query)) {

471

// Process results

472

result.forEachRemaining(row -> {

473

System.out.println(row.get("p.name") + " -> " + row.get("f.name"));

474

});

475

476

// Analyze execution plan

477

ExecutionPlanDescription plan = result.getExecutionPlanDescription();

478

printExecutionPlan(plan, 0);

479

480

// Check for notifications

481

for (Notification notification : result.getNotifications()) {

482

System.out.println("Notification: " + notification.getTitle());

483

System.out.println("Description: " + notification.getDescription());

484

}

485

}

486

487

tx.commit();

488

}

489

490

// Helper method to print execution plan

491

private void printExecutionPlan(ExecutionPlanDescription plan, int indent) {

492

String indentStr = " ".repeat(indent);

493

System.out.println(indentStr + plan.getName());

494

495

if (plan.hasProfilerStatistics()) {

496

ProfilerStatistics stats = plan.getProfilerStatistics();

497

System.out.println(indentStr + " Rows: " + stats.getRows());

498

System.out.println(indentStr + " DB Hits: " + stats.getDbHits());

499

System.out.println(indentStr + " Time: " + stats.getTime() + "ms");

500

}

501

502

for (ExecutionPlanDescription child : plan.getChildren()) {

503

printExecutionPlan(child, indent + 1);

504

}

505

}

506

507

// Parameterized queries with error handling

508

try (Transaction tx = graphDb.beginTx()) {

509

String query = "MATCH (p:Person {name: $name}) " +

510

"CREATE (p)-[:LIVES_IN]->(:City {name: $city}) " +

511

"RETURN p.name as person, $city as city";

512

513

Map<String, Object> parameters = Map.of(

514

"name", "Alice",

515

"city", "New York"

516

);

517

518

try (Result result = tx.execute(query, parameters)) {

519

if (result.hasNext()) {

520

Map<String, Object> row = result.next();

521

System.out.println(row.get("person") + " lives in " + row.get("city"));

522

}

523

524

QueryStatistics stats = result.getQueryStatistics();

525

if (stats.containsUpdates()) {

526

System.out.println("Created " + stats.getRelationshipsCreated() + " relationships");

527

System.out.println("Created " + stats.getNodesCreated() + " nodes");

528

}

529

}

530

531

tx.commit();

532

} catch (Exception e) {

533

System.err.println("Query execution failed: " + e.getMessage());

534

}

535

```