or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

database.mdexceptions.mdindex.mdnodes.mdproperties.mdqueries.mdrelationships.md

queries.mddocs/

0

# Query and Traversal

1

2

Advanced querying capabilities in neomodel including filtering, ordering, aggregation, and graph traversal operations. Supports complex WHERE clauses, relationship navigation, and both synchronous and asynchronous query patterns.

3

4

## Capabilities

5

6

### NodeSet Query Builder

7

8

Primary interface for querying and filtering node collections with chainable methods.

9

10

```python { .api }

11

class NodeSet:

12

"""

13

Query builder for node collections in synchronous mode.

14

15

Provides filtering, ordering, limiting, and aggregation capabilities.

16

"""

17

18

def filter(self, **kwargs):

19

"""

20

Filter nodes by property values and relationships.

21

22

Args:

23

**kwargs: Filter criteria using Django-style lookups

24

(exact, contains, icontains, startswith, endswith,

25

gt, gte, lt, lte, in, isnull, regex, iregex)

26

27

Returns:

28

NodeSet: Filtered node collection

29

"""

30

31

def exclude(self, **kwargs):

32

"""

33

Exclude nodes matching criteria.

34

35

Args:

36

**kwargs: Exclusion criteria using Django-style lookups

37

38

Returns:

39

NodeSet: Filtered node collection

40

"""

41

42

def get(self, **kwargs):

43

"""

44

Get a single node matching criteria.

45

46

Args:

47

**kwargs: Filter criteria

48

49

Returns:

50

Node instance

51

52

Raises:

53

DoesNotExist: If no node matches

54

MultipleNodesReturned: If multiple nodes match

55

"""

56

57

def get_or_none(self, **kwargs):

58

"""

59

Get a single node or None if not found.

60

61

Args:

62

**kwargs: Filter criteria

63

64

Returns:

65

Node instance or None

66

"""

67

68

def all(self):

69

"""

70

Get all nodes in the collection.

71

72

Returns:

73

list: List of node instances

74

"""

75

76

def order_by(self, *properties):

77

"""

78

Order results by properties.

79

80

Args:

81

*properties: Property names, prefix with '-' for descending

82

83

Returns:

84

NodeSet: Ordered node collection

85

"""

86

87

def limit(self, count):

88

"""

89

Limit the number of results.

90

91

Args:

92

count (int): Maximum number of results

93

94

Returns:

95

NodeSet: Limited node collection

96

"""

97

98

def skip(self, count):

99

"""

100

Skip a number of results.

101

102

Args:

103

count (int): Number of results to skip

104

105

Returns:

106

NodeSet: Node collection with offset

107

"""

108

109

class AsyncNodeSet:

110

"""

111

Query builder for node collections in asynchronous mode.

112

113

Same interface as NodeSet but all methods are async.

114

"""

115

116

async def filter(self, **kwargs):

117

"""Asynchronously filter nodes by property values and relationships."""

118

119

async def exclude(self, **kwargs):

120

"""Asynchronously exclude nodes matching criteria."""

121

122

async def get(self, **kwargs):

123

"""Asynchronously get a single node matching criteria."""

124

125

async def get_or_none(self, **kwargs):

126

"""Asynchronously get a single node or None if not found."""

127

128

async def all(self):

129

"""Asynchronously get all nodes in the collection."""

130

131

def order_by(self, *properties):

132

"""Order results by properties (returns modified NodeSet)."""

133

134

def limit(self, count):

135

"""Limit the number of results (returns modified NodeSet)."""

136

137

def skip(self, count):

138

"""Skip a number of results (returns modified NodeSet)."""

139

```

140

141

### Q Objects for Complex Queries

142

143

Query objects for building complex logical queries with AND, OR, and NOT operations.

144

145

```python { .api }

146

class Q:

147

"""

148

Query object for complex filtering with logical operators.

149

150

Supports combining multiple filter conditions with AND, OR, and NOT logic.

151

"""

152

153

def __init__(self, **kwargs):

154

"""

155

Initialize Q object with filter criteria.

156

157

Args:

158

**kwargs: Filter criteria using Django-style lookups

159

"""

160

161

def __and__(self, other):

162

"""

163

Combine with another Q object using AND logic.

164

165

Args:

166

other (Q): Another Q object

167

168

Returns:

169

Q: Combined Q object

170

"""

171

172

def __or__(self, other):

173

"""

174

Combine with another Q object using OR logic.

175

176

Args:

177

other (Q): Another Q object

178

179

Returns:

180

Q: Combined Q object

181

"""

182

183

def __invert__(self):

184

"""

185

Negate the Q object (NOT logic).

186

187

Returns:

188

Q: Negated Q object

189

"""

190

```

191

192

### Traversal Classes

193

194

Classes for advanced graph traversal and path-based operations.

195

196

```python { .api }

197

class Traversal:

198

"""

199

Graph traversal operations for synchronous mode.

200

201

Enables complex path-based queries and graph navigation.

202

"""

203

204

def traverse(self, *relationships):

205

"""

206

Traverse relationships to connected nodes.

207

208

Args:

209

*relationships: Relationship definitions to follow

210

211

Returns:

212

Traversal: Extended traversal path

213

"""

214

215

class AsyncTraversal:

216

"""

217

Graph traversal operations for asynchronous mode.

218

219

Same interface as Traversal but for async operations.

220

"""

221

222

def traverse(self, *relationships):

223

"""

224

Traverse relationships to connected nodes asynchronously.

225

226

Args:

227

*relationships: Relationship definitions to follow

228

229

Returns:

230

AsyncTraversal: Extended traversal path

231

"""

232

```

233

234

### Path Classes

235

236

Classes representing paths through the graph with node and relationship sequences.

237

238

```python { .api }

239

class NeomodelPath:

240

"""

241

Represents Neo4j paths in synchronous mode.

242

243

Contains sequences of nodes and relationships forming a path through the graph.

244

"""

245

246

def nodes(self):

247

"""

248

Get nodes in the path.

249

250

Returns:

251

list: List of node instances in path order

252

"""

253

254

def relationships(self):

255

"""

256

Get relationships in the path.

257

258

Returns:

259

list: List of relationship instances in path order

260

"""

261

262

class AsyncNeomodelPath:

263

"""

264

Represents Neo4j paths in asynchronous mode.

265

266

Same interface as NeomodelPath but for async operations.

267

"""

268

269

def nodes(self):

270

"""Get nodes in the path."""

271

272

def relationships(self):

273

"""Get relationships in the path."""

274

```

275

276

## Usage Examples

277

278

### Basic Filtering and Querying

279

280

```python

281

from neomodel import StructuredNode, StringProperty, IntegerProperty

282

283

class Person(StructuredNode):

284

name = StringProperty(required=True)

285

age = IntegerProperty()

286

email = StringProperty()

287

288

# Basic filtering

289

adults = Person.nodes.filter(age__gte=18)

290

johns = Person.nodes.filter(name__icontains='john')

291

gmail_users = Person.nodes.filter(email__endswith='@gmail.com')

292

293

# Exclusion

294

non_admins = Person.nodes.exclude(email__endswith='@admin.com')

295

296

# Ordering and limiting

297

recent_users = Person.nodes.order_by('-created_at').limit(10)

298

alphabetical = Person.nodes.order_by('name')

299

300

# Get single node

301

alice = Person.nodes.get(name='Alice')

302

maybe_bob = Person.nodes.get_or_none(name='Bob')

303

```

304

305

### Complex Queries with Q Objects

306

307

```python

308

from neomodel import Q

309

310

# Complex logical conditions

311

young_or_senior = Person.nodes.filter(

312

Q(age__lt=25) | Q(age__gt=65)

313

)

314

315

# Multiple conditions

316

tech_professionals = Person.nodes.filter(

317

Q(email__endswith='@tech.com') &

318

Q(age__gte=25) &

319

Q(age__lte=45)

320

)

321

322

# Negation

323

non_gmail_adults = Person.nodes.filter(

324

~Q(email__endswith='@gmail.com') & Q(age__gte=18)

325

)

326

327

# Combining with regular filters

328

filtered_users = Person.nodes.filter(

329

Q(name__startswith='A') | Q(name__startswith='B'),

330

age__gte=21

331

)

332

```

333

334

### Advanced Filter Lookups

335

336

```python

337

# String lookups

338

exact_match = Person.nodes.filter(name='Alice')

339

contains = Person.nodes.filter(name__contains='ali')

340

case_insensitive = Person.nodes.filter(name__icontains='ALICE')

341

starts_with = Person.nodes.filter(name__startswith='Al')

342

ends_with = Person.nodes.filter(name__endswith='ice')

343

344

# Numeric comparisons

345

young = Person.nodes.filter(age__lt=30)

346

adults = Person.nodes.filter(age__gte=18)

347

middle_aged = Person.nodes.filter(age__gt=30, age__lt=50)

348

349

# List membership

350

names = ['Alice', 'Bob', 'Charlie']

351

selected_people = Person.nodes.filter(name__in=names)

352

353

# Null checks

354

has_email = Person.nodes.filter(email__isnull=False)

355

no_age = Person.nodes.filter(age__isnull=True)

356

357

# Regular expressions

358

phone_pattern = Person.nodes.filter(phone__regex=r'^\+1\d{10}$')

359

```

360

361

### Async Query Operations

362

363

```python

364

from neomodel import AsyncStructuredNode

365

366

class AsyncPerson(AsyncStructuredNode):

367

name = StringProperty(required=True)

368

age = IntegerProperty()

369

370

async def query_people():

371

# Async filtering

372

adults = await AsyncPerson.nodes.filter(age__gte=18).all()

373

alice = await AsyncPerson.nodes.get(name='Alice')

374

375

# Async ordering and limiting

376

recent = await AsyncPerson.nodes.order_by('-created_at').limit(5).all()

377

378

return adults, alice, recent

379

```

380

381

### Relationship-based Queries

382

383

```python

384

class Person(StructuredNode):

385

name = StringProperty(required=True)

386

friends = RelationshipTo('Person', 'FRIENDS_WITH')

387

works_at = RelationshipTo('Company', 'WORKS_AT')

388

389

class Company(StructuredNode):

390

name = StringProperty(required=True)

391

392

# Query through relationships

393

alice = Person.nodes.get(name='Alice')

394

395

# Get all friends

396

alice_friends = alice.friends.all()

397

398

# Filter friends

399

close_friends = alice.friends.filter(name__contains='Bob')

400

401

# Query company employees

402

company = Company.nodes.get(name='TechCorp')

403

employees = company.employees.all()

404

405

# Complex relationship filtering

406

tech_workers = Person.nodes.filter(works_at__name='TechCorp')

407

```

408

409

### Graph Traversal Operations

410

411

```python

412

# Traversal through multiple relationship types

413

alice = Person.nodes.get(name='Alice')

414

415

# Traverse friend-of-friend relationships

416

friends_of_friends = alice.traverse('friends', 'friends').all()

417

418

# Complex path traversals

419

path_results = alice.traverse('works_at', 'employees').filter(age__gt=30)

420

421

# Path objects (when supported)

422

paths = alice.traverse_paths('friends').all()

423

for path in paths:

424

nodes = path.nodes()

425

relationships = path.relationships()

426

```

427

428

### Aggregation and Statistics

429

430

```python

431

# Count results

432

total_users = Person.nodes.count()

433

adult_count = Person.nodes.filter(age__gte=18).count()

434

435

# Check existence

436

has_admin = Person.nodes.filter(email__endswith='@admin.com').exists()

437

438

# First/last

439

oldest = Person.nodes.order_by('-age').first()

440

newest = Person.nodes.order_by('-created_at').first()

441

```

442

443

## Types

444

445

```python { .api }

446

# Query result types

447

NodeCollection = List[StructuredNode]

448

SingleNodeResult = Union[StructuredNode, None]

449

450

# Query filter types

451

FilterLookup = Union[str, int, float, bool, list]

452

QueryDict = Dict[str, FilterLookup]

453

454

# Traversal types

455

PathResult = Union[NeomodelPath, AsyncNeomodelPath]

456

TraversalResult = Union[NodeCollection, PathResult]

457

```