or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bson-types.mdengines.mdfields.mdindex.mdindexes.mdmodels.mdqueries.mdsessions.md

queries.mddocs/

0

# Queries

1

2

ODMantic provides a functional query building system using Python operators and functions to construct MongoDB queries and sort expressions.

3

4

## Capabilities

5

6

### Comparison Operators

7

8

Functions for building comparison queries against model fields.

9

10

```python { .api }

11

def eq(field, value):

12

"""

13

Equality comparison.

14

15

Args:

16

field: FieldProxy for the model field

17

value: Value to compare against

18

19

Returns:

20

QueryExpression: MongoDB equality query

21

"""

22

23

def ne(field, value):

24

"""

25

Not equal comparison.

26

27

Args:

28

field: FieldProxy for the model field

29

value: Value to compare against

30

31

Returns:

32

QueryExpression: MongoDB not equal query

33

"""

34

35

def gt(field, value):

36

"""

37

Greater than comparison.

38

39

Args:

40

field: FieldProxy for the model field

41

value: Value to compare against

42

43

Returns:

44

QueryExpression: MongoDB greater than query

45

"""

46

47

def gte(field, value):

48

"""

49

Greater than or equal comparison.

50

51

Args:

52

field: FieldProxy for the model field

53

value: Value to compare against

54

55

Returns:

56

QueryExpression: MongoDB greater than or equal query

57

"""

58

59

def lt(field, value):

60

"""

61

Less than comparison.

62

63

Args:

64

field: FieldProxy for the model field

65

value: Value to compare against

66

67

Returns:

68

QueryExpression: MongoDB less than query

69

"""

70

71

def lte(field, value):

72

"""

73

Less than or equal comparison.

74

75

Args:

76

field: FieldProxy for the model field

77

value: Value to compare against

78

79

Returns:

80

QueryExpression: MongoDB less than or equal query

81

"""

82

```

83

84

### Set Operators

85

86

Functions for set-based queries.

87

88

```python { .api }

89

def in_(field, sequence):

90

"""

91

Value in sequence query.

92

93

Args:

94

field: FieldProxy for the model field

95

sequence: Iterable of values to match against

96

97

Returns:

98

QueryExpression: MongoDB $in query

99

"""

100

101

def not_in(field, sequence):

102

"""

103

Value not in sequence query.

104

105

Args:

106

field: FieldProxy for the model field

107

sequence: Iterable of values to exclude

108

109

Returns:

110

QueryExpression: MongoDB $nin query

111

"""

112

```

113

114

### Pattern Matching

115

116

Functions for pattern and text matching.

117

118

```python { .api }

119

def match(field, pattern):

120

"""

121

Regular expression pattern matching.

122

123

Args:

124

field: FieldProxy for the model field

125

pattern: Regular expression pattern (str or compiled Pattern)

126

127

Returns:

128

QueryExpression: MongoDB regex query

129

"""

130

```

131

132

### Logical Operators

133

134

Functions for combining multiple query expressions.

135

136

```python { .api }

137

def and_(*elements):

138

"""

139

Logical AND of multiple query expressions.

140

141

Args:

142

*elements: QueryExpression objects to combine with AND

143

144

Returns:

145

QueryExpression: MongoDB $and query

146

"""

147

148

def or_(*elements):

149

"""

150

Logical OR of multiple query expressions.

151

152

Args:

153

*elements: QueryExpression objects to combine with OR

154

155

Returns:

156

QueryExpression: MongoDB $or query

157

"""

158

159

def nor_(*elements):

160

"""

161

Logical NOR of multiple query expressions.

162

163

Args:

164

*elements: QueryExpression objects to combine with NOR

165

166

Returns:

167

QueryExpression: MongoDB $nor query

168

"""

169

```

170

171

### Sort Operations

172

173

Functions for building sort expressions.

174

175

```python { .api }

176

def asc(field):

177

"""

178

Ascending sort order.

179

180

Args:

181

field: FieldProxy for the model field

182

183

Returns:

184

SortExpression: MongoDB ascending sort

185

"""

186

187

def desc(field):

188

"""

189

Descending sort order.

190

191

Args:

192

field: FieldProxy for the model field

193

194

Returns:

195

SortExpression: MongoDB descending sort

196

"""

197

```

198

199

### Query Types

200

201

Core query and sort expression types.

202

203

```python { .api }

204

class QueryExpression(dict):

205

"""MongoDB query expression dictionary."""

206

207

class SortExpression(dict):

208

"""MongoDB sort expression dictionary."""

209

```

210

211

## Usage Examples

212

213

### Basic Comparisons

214

215

```python

216

from odmantic import Model, AIOEngine

217

from odmantic.query import eq, ne, gt, gte, lt, lte

218

219

class Product(Model):

220

name: str

221

price: float

222

category: str

223

stock: int

224

225

async def comparison_examples(engine: AIOEngine):

226

# Equality (can also use == operator)

227

expensive = await engine.find(Product, eq(Product.price, 100.0))

228

# Or: expensive = await engine.find(Product, Product.price == 100.0)

229

230

# Not equal

231

not_electronics = await engine.find(Product, ne(Product.category, "electronics"))

232

# Or: not_electronics = await engine.find(Product, Product.category != "electronics")

233

234

# Greater than

235

expensive_items = await engine.find(Product, gt(Product.price, 50.0))

236

# Or: expensive_items = await engine.find(Product, Product.price > 50.0)

237

238

# Less than or equal

239

affordable = await engine.find(Product, lte(Product.price, 25.0))

240

# Or: affordable = await engine.find(Product, Product.price <= 25.0)

241

242

# Range query

243

mid_range = await engine.find(

244

Product,

245

gte(Product.price, 20.0),

246

lte(Product.price, 50.0)

247

)

248

# Or: mid_range = await engine.find(Product, Product.price >= 20.0, Product.price <= 50.0)

249

```

250

251

### Set Operations

252

253

```python

254

from odmantic.query import in_, not_in

255

256

async def set_examples(engine: AIOEngine):

257

# Find products in specific categories

258

tech_products = await engine.find(

259

Product,

260

in_(Product.category, ["electronics", "computers", "phones"])

261

)

262

263

# Exclude out-of-stock items

264

available_products = await engine.find(

265

Product,

266

not_in(Product.stock, [0])

267

)

268

269

# Find products with specific names

270

featured_products = await engine.find(

271

Product,

272

in_(Product.name, ["iPhone", "MacBook", "iPad"])

273

)

274

```

275

276

### Pattern Matching

277

278

```python

279

from odmantic.query import match

280

import re

281

282

async def pattern_examples(engine: AIOEngine):

283

# Find products with names starting with "Pro"

284

pro_products = await engine.find(

285

Product,

286

match(Product.name, r"^Pro")

287

)

288

289

# Case-insensitive search

290

apple_products = await engine.find(

291

Product,

292

match(Product.name, re.compile(r"apple", re.IGNORECASE))

293

)

294

295

# Find products with email pattern in description (if you had a description field)

296

# email_mentions = await engine.find(Product, match(Product.description, r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b"))

297

```

298

299

### Logical Operations

300

301

```python

302

from odmantic.query import and_, or_, nor_

303

304

async def logical_examples(engine: AIOEngine):

305

# AND: expensive electronics

306

expensive_electronics = await engine.find(

307

Product,

308

and_(

309

eq(Product.category, "electronics"),

310

gt(Product.price, 100.0)

311

)

312

)

313

314

# OR: either cheap or high stock

315

bargain_or_available = await engine.find(

316

Product,

317

or_(

318

lt(Product.price, 20.0),

319

gt(Product.stock, 100)

320

)

321

)

322

323

# NOR: neither expensive nor out of stock

324

reasonable_available = await engine.find(

325

Product,

326

nor_(

327

gt(Product.price, 200.0),

328

eq(Product.stock, 0)

329

)

330

)

331

332

# Complex nested logical operations

333

complex_query = await engine.find(

334

Product,

335

and_(

336

or_(

337

eq(Product.category, "electronics"),

338

eq(Product.category, "computers")

339

),

340

gt(Product.price, 50.0),

341

gt(Product.stock, 0)

342

)

343

)

344

```

345

346

### Sorting

347

348

```python

349

from odmantic.query import asc, desc

350

351

async def sorting_examples(engine: AIOEngine):

352

# Sort by price ascending

353

cheap_first = await engine.find(Product, sort=asc(Product.price))

354

355

# Sort by price descending

356

expensive_first = await engine.find(Product, sort=desc(Product.price))

357

358

# Multiple sort criteria (tuple of sort expressions)

359

sorted_products = await engine.find(

360

Product,

361

sort=(desc(Product.category), asc(Product.price))

362

)

363

364

# Sort with query

365

electronics_by_price = await engine.find(

366

Product,

367

eq(Product.category, "electronics"),

368

sort=desc(Product.price)

369

)

370

```

371

372

### Complex Query Examples

373

374

```python

375

async def complex_examples(engine: AIOEngine):

376

# Find available, reasonably priced electronics

377

good_electronics = await engine.find(

378

Product,

379

and_(

380

eq(Product.category, "electronics"),

381

gte(Product.price, 10.0),

382

lte(Product.price, 500.0),

383

gt(Product.stock, 0)

384

),

385

sort=asc(Product.price)

386

)

387

388

# Find products that match multiple criteria

389

filtered_products = await engine.find(

390

Product,

391

or_(

392

and_(

393

eq(Product.category, "books"),

394

lt(Product.price, 30.0)

395

),

396

and_(

397

in_(Product.category, ["electronics", "computers"]),

398

gte(Product.stock, 5),

399

lte(Product.price, 200.0)

400

)

401

),

402

sort=(desc(Product.stock), asc(Product.price)),

403

limit=20

404

)

405

406

# Text search with multiple patterns

407

search_results = await engine.find(

408

Product,

409

or_(

410

match(Product.name, r"(?i)(pro|premium|deluxe)"),

411

and_(

412

match(Product.category, r"(?i)electronics"),

413

gt(Product.price, 100.0)

414

)

415

),

416

sort=desc(Product.price)

417

)

418

```

419

420

### Query Building Patterns

421

422

```python

423

def build_product_filter(min_price=None, max_price=None, categories=None, in_stock_only=False):

424

"""Build a dynamic query based on parameters."""

425

conditions = []

426

427

if min_price is not None:

428

conditions.append(gte(Product.price, min_price))

429

430

if max_price is not None:

431

conditions.append(lte(Product.price, max_price))

432

433

if categories:

434

conditions.append(in_(Product.category, categories))

435

436

if in_stock_only:

437

conditions.append(gt(Product.stock, 0))

438

439

if len(conditions) == 1:

440

return conditions[0]

441

elif len(conditions) > 1:

442

return and_(*conditions)

443

else:

444

return {} # No conditions

445

446

async def dynamic_search(engine: AIOEngine):

447

# Use the dynamic filter

448

query = build_product_filter(

449

min_price=20.0,

450

max_price=100.0,

451

categories=["electronics", "books"],

452

in_stock_only=True

453

)

454

455

products = await engine.find(Product, query, sort=asc(Product.price))

456

```

457

458

### Working with Dates and ObjectIds

459

460

```python

461

from datetime import datetime, timedelta

462

from odmantic import ObjectId

463

464

class Order(Model):

465

customer_id: ObjectId

466

created_at: datetime

467

total: float

468

469

async def date_queries(engine: AIOEngine):

470

# Find recent orders

471

week_ago = datetime.utcnow() - timedelta(days=7)

472

recent_orders = await engine.find(

473

Order,

474

gte(Order.created_at, week_ago)

475

)

476

477

# Find orders for specific customer

478

customer_orders = await engine.find(

479

Order,

480

eq(Order.customer_id, ObjectId("507f1f77bcf86cd799439011"))

481

)

482

483

# Find large orders this month

484

month_start = datetime.utcnow().replace(day=1, hour=0, minute=0, second=0, microsecond=0)

485

large_orders = await engine.find(

486

Order,

487

and_(

488

gte(Order.created_at, month_start),

489

gt(Order.total, 500.0)

490

),

491

sort=desc(Order.total)

492

)

493

```