or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bulk-operations.mdcustom-types.mddocuments.mdevents-actions.mdfields-types.mdindex.mdinitialization.mdmigrations.mdquery-operations.mdtime-series.md

fields-types.mddocs/

0

# Field Types & Relationships

1

2

Type-safe field definitions with MongoDB-specific types, automatic indexing capabilities, and document relationships with lazy loading support. These components enable rich data modeling with proper validation and efficient queries.

3

4

## Capabilities

5

6

### Object ID Types

7

8

MongoDB ObjectId field types that integrate seamlessly with Pydantic validation and serialization.

9

10

```python { .api }

11

class PydanticObjectId(ObjectId):

12

"""Pydantic-compatible ObjectId field type for document IDs."""

13

14

def __init__(self, value: Union[str, ObjectId, None] = None):

15

"""Initialize ObjectId from string, ObjectId, or generate new one."""

16

...

17

18

def __str__(self) -> str:

19

"""String representation of ObjectId."""

20

...

21

22

def __repr__(self) -> str:

23

"""Developer representation of ObjectId."""

24

...

25

26

@classmethod

27

def __get_validators__(cls):

28

"""Pydantic validators for ObjectId validation."""

29

...

30

31

@classmethod

32

def validate(cls, value: Any) -> "PydanticObjectId":

33

"""Validate and convert input to PydanticObjectId."""

34

...

35

36

# Alias for backward compatibility

37

BeanieObjectId = PydanticObjectId

38

```

39

40

#### Usage Examples

41

42

```python

43

from beanie import Document, PydanticObjectId

44

from typing import Optional

45

46

class Product(Document):

47

id: Optional[PydanticObjectId] = None

48

name: str

49

category_id: PydanticObjectId

50

51

class Settings:

52

collection = "products"

53

54

# Create with ObjectId

55

product = Product(

56

name="Laptop",

57

category_id=PydanticObjectId("507f1f77bcf86cd799439011")

58

)

59

await product.insert()

60

61

# Access as string

62

print(f"Product ID: {product.id}")

63

print(f"Category ID: {str(product.category_id)}")

64

```

65

66

### Expression Fields

67

68

Special field types for building MongoDB queries and operations programmatically.

69

70

```python { .api }

71

class ExpressionField(str):

72

"""String-based field expressions for query building."""

73

74

def __getitem__(self, item: str) -> "ExpressionField":

75

"""Get sub-field for nested document queries."""

76

...

77

78

def __getattr__(self, item: str) -> "ExpressionField":

79

"""Access nested fields using attribute notation."""

80

...

81

```

82

83

#### Usage Examples

84

85

```python

86

from beanie import Document, ExpressionField

87

88

class User(Document):

89

name: str

90

profile: Dict[str, Any]

91

92

# Create expression fields for queries

93

user_name = ExpressionField("name")

94

profile_age = ExpressionField("profile.age")

95

96

# Use in queries

97

users = await User.find(user_name == "Alice").to_list()

98

adults = await User.find(profile_age >= 18).to_list()

99

```

100

101

### Indexed Fields

102

103

Field annotations that automatically create MongoDB indexes during initialization, supporting various index types and options.

104

105

```python { .api }

106

class IndexedAnnotation:

107

"""Internal annotation class for indexed fields."""

108

_indexed: Tuple[int, Dict[str, Any]]

109

```

110

111

```python { .api }

112

def Indexed(

113

annotation: Any,

114

index_type: Optional[str] = None,

115

unique: bool = False,

116

sparse: bool = False,

117

**kwargs

118

) -> Any:

119

"""

120

Create indexed field annotation for automatic index creation.

121

122

Args:

123

annotation: Base field type (str, int, etc.)

124

index_type: MongoDB index type ("text", "2d", "2dsphere", etc.)

125

unique: Create unique index

126

sparse: Create sparse index (skip None values)

127

**kwargs: Additional index options

128

129

Returns:

130

Annotated field type with index metadata

131

"""

132

...

133

```

134

135

#### Usage Examples

136

137

```python

138

from beanie import Document, Indexed

139

from typing import Annotated, Optional

140

141

class User(Document):

142

# Unique index on email

143

email: Annotated[str, Indexed(unique=True)]

144

145

# Text index for full-text search

146

bio: Annotated[str, Indexed(index_type="text")]

147

148

# Compound index (defined in Settings)

149

first_name: str

150

last_name: str

151

152

# Sparse index (ignores None values)

153

phone: Annotated[Optional[str], Indexed(sparse=True)]

154

155

class Settings:

156

collection = "users"

157

indexes = [

158

[("first_name", 1), ("last_name", 1)], # Compound index

159

[("email", 1), ("phone", 1)] # Multi-field index

160

]

161

162

# Alternative syntax

163

class Product(Document):

164

name: str = Indexed(str, unique=True)

165

price: float = Indexed(float)

166

category: str = Indexed(str, index_type="text")

167

```

168

169

### Document Links

170

171

Reference fields that create relationships between documents in different collections with lazy loading and batch fetching capabilities.

172

173

```python { .api }

174

class Link(Generic[T]):

175

"""Reference to documents in other collections with lazy loading."""

176

177

def __init__(self, ref: DBRef, document_class: Type[T]):

178

"""

179

Initialize document link.

180

181

Args:

182

ref: MongoDB DBRef pointing to the linked document

183

document_class: Target document class

184

"""

185

...

186

187

async def fetch(self, fetch_links: bool = False) -> Union[T, "Link[T]"]:

188

"""

189

Load the referenced document.

190

191

Args:

192

fetch_links: Also fetch nested links

193

194

Returns:

195

Referenced document or Link if not found

196

"""

197

...

198

199

@classmethod

200

async def fetch_one(cls, link: "Link[T]") -> Union[T, "Link[T]"]:

201

"""Fetch a single linked document."""

202

...

203

204

@classmethod

205

async def fetch_list(

206

cls,

207

links: List[Union["Link[T]", T]],

208

fetch_links: bool = False,

209

) -> List[Union[T, "Link[T]"]]:

210

"""

211

Load multiple referenced documents.

212

213

Args:

214

links: List of Link objects or documents

215

fetch_links: Also fetch nested links

216

217

Returns:

218

List of referenced documents or Links

219

"""

220

...

221

222

@classmethod

223

async def fetch_many(cls, links: List["Link[T]"]) -> List[Union[T, "Link[T]"]]:

224

"""Fetch multiple linked documents concurrently."""

225

...

226

227

def to_dict(self) -> Dict[str, str]:

228

"""Convert link to dictionary representation with id and collection."""

229

...

230

231

@staticmethod

232

def serialize(value: Union["Link[T]", BaseModel]) -> Dict[str, Any]:

233

"""Serialize link or document for JSON output."""

234

...

235

```

236

237

#### Usage Examples

238

239

```python

240

from beanie import Document, Link

241

from typing import Optional, List

242

243

class Category(Document):

244

name: str

245

description: str

246

247

class Settings:

248

collection = "categories"

249

250

class Product(Document):

251

name: str

252

price: float

253

category: Link[Category] # Single reference

254

related_products: List[Link[Product]] = [] # Multiple references

255

256

class Settings:

257

collection = "products"

258

259

# Create linked documents

260

category = Category(name="Electronics", description="Electronic devices")

261

await category.insert()

262

263

product = Product(

264

name="Smartphone",

265

price=599.99,

266

category=category # Link automatically created

267

)

268

await product.insert()

269

270

# Fetch linked document

271

await product.category.fetch()

272

print(f"Category: {product.category.name}")

273

274

# Fetch with nested links

275

await product.fetch_all_links()

276

```

277

278

### Back Links

279

280

Reverse reference fields that automatically maintain bidirectional relationships between documents.

281

282

```python { .api }

283

class BackLink(Generic[T]):

284

"""Back-reference field for bidirectional relationships."""

285

286

def __init__(

287

self,

288

document_class: Type[T],

289

original_field: str,

290

lazy: bool = True

291

):

292

"""

293

Initialize back link.

294

295

Args:

296

document_class: Source document class

297

original_field: Field name in source document

298

lazy: Enable lazy loading

299

"""

300

...

301

302

async def fetch(self, limit: Optional[int] = None) -> List[T]:

303

"""

304

Fetch documents that reference this document.

305

306

Args:

307

limit: Maximum number of documents to fetch

308

309

Returns:

310

List of referencing documents

311

"""

312

...

313

314

def to_dict(self) -> Dict[str, str]:

315

"""Convert back link to dictionary representation with collection info."""

316

...

317

```

318

319

#### Usage Examples

320

321

```python

322

from beanie import Document, Link, BackLink

323

from typing import List

324

325

class Author(Document):

326

name: str

327

books: List[BackLink["Book"]] = BackLink("Book", "author")

328

329

class Settings:

330

collection = "authors"

331

332

class Book(Document):

333

title: str

334

author: Link[Author]

335

336

class Settings:

337

collection = "books"

338

339

# Create author and books

340

author = Author(name="Jane Doe")

341

await author.insert()

342

343

book1 = Book(title="First Book", author=author)

344

book2 = Book(title="Second Book", author=author)

345

await book1.insert()

346

await book2.insert()

347

348

# Access books through back link

349

books = await author.books.fetch()

350

print(f"Author has {len(books)} books")

351

```

352

353

### Link Rules

354

355

Enumerations that control how linked documents are handled during write and delete operations.

356

357

```python { .api }

358

class WriteRules(Enum):

359

"""Rules for handling linked documents during write operations."""

360

DO_NOTHING = "DO_NOTHING" # Don't save linked documents

361

WRITE = "WRITE" # Save linked documents too

362

363

class DeleteRules(Enum):

364

"""Rules for handling linked documents during delete operations."""

365

DO_NOTHING = "DO_NOTHING" # Leave linked documents unchanged

366

DELETE_LINKS = "DELETE_LINKS" # Delete references to this document

367

```

368

369

#### Usage Examples

370

371

```python

372

from beanie import Document, Link, WriteRules, DeleteRules

373

374

class Author(Document):

375

name: str

376

377

class Settings:

378

collection = "authors"

379

380

class Book(Document):

381

title: str

382

author: Link[Author]

383

384

class Settings:

385

collection = "books"

386

# Configure link behavior

387

write_rules = WriteRules.WRITE

388

delete_rules = DeleteRules.DELETE_LINKS

389

390

# When saving book with WriteRules.WRITE:

391

# - Author will be saved automatically if modified

392

book = Book(title="New Book", author=author)

393

await book.save() # Saves both book and author if needed

394

395

# When deleting author with DeleteRules.DELETE_LINKS:

396

# - All book.author references are removed

397

await author.delete() # Books will have author=None

398

```

399

400

## Types

401

402

```python { .api }

403

from typing import TypeVar, Generic, Optional, List, Dict, Any, Union

404

from enum import Enum

405

from bson import ObjectId

406

407

# Generic type for document links

408

T = TypeVar("T", bound="Document")

409

410

# Link rule enumerations

411

class WriteRules(Enum):

412

DO_NOTHING = "DO_NOTHING"

413

WRITE = "WRITE"

414

415

class DeleteRules(Enum):

416

DO_NOTHING = "DO_NOTHING"

417

DELETE_LINKS = "DELETE_LINKS"

418

419

# Field metadata types

420

IndexInfo = Dict[str, Any]

421

FieldInfo = Dict[str, Any]

422

```