or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cursors.mddatabase-management.mdindex.mdjson-collections.mdjx9-scripting.mdkey-value.mdtransactions.mdutilities.md

json-collections.mddocs/

0

# JSON Collections

1

2

High-level document store interface for managing JSON documents with querying, filtering, and schema support. Collections provide a NoSQL document database interface built on top of UnQLite's Jx9 scripting engine.

3

4

## Capabilities

5

6

### Collection Management

7

8

Create and manage JSON document collections.

9

10

```python { .api }

11

def collection(self, name):

12

"""Create a wrapper for working with Jx9 collections.

13

Returns Collection object."""

14

...

15

16

class Collection:

17

def __init__(self, unqlite, name):

18

"""Initialize collection with database and collection name."""

19

...

20

21

def create(self):

22

"""Create the named collection. Returns True if created, False if exists."""

23

...

24

25

def drop(self):

26

"""Drop the collection and all associated records. Returns True if dropped."""

27

...

28

29

def exists(self):

30

"""Return boolean indicating whether the collection exists."""

31

...

32

```

33

34

**Usage Example:**

35

36

```python

37

db = unqlite.UnQLite('documents.db')

38

39

# Create collection wrapper

40

users = db.collection('users')

41

42

# Create collection if it doesn't exist

43

if not users.exists():

44

users.create()

45

print("Users collection created")

46

47

# Work with collection

48

print(f"Collection exists: {users.exists()}")

49

50

# Drop collection when done

51

# users.drop()

52

```

53

54

### Document Storage and Retrieval

55

56

Store, fetch, update, and delete JSON documents.

57

58

```python { .api }

59

def store(self, record, return_id=True):

60

"""Create a new JSON document in the collection.

61

Returns record ID if return_id=True, otherwise returns boolean."""

62

...

63

64

def fetch(self, record_id):

65

"""Fetch the document associated with the given ID."""

66

...

67

68

def update(self, record_id, record):

69

"""Update the record identified by the given ID."""

70

...

71

72

def delete(self, record_id):

73

"""Delete the document associated with the given ID."""

74

...

75

76

def all(self):

77

"""Retrieve all records in the given collection."""

78

...

79

```

80

81

**Usage Example:**

82

83

```python

84

db = unqlite.UnQLite('blog.db')

85

posts = db.collection('posts')

86

87

if not posts.exists():

88

posts.create()

89

90

# Store new documents

91

post1_id = posts.store({

92

'title': 'Getting Started with UnQLite',

93

'content': 'UnQLite is a lightweight NoSQL database...',

94

'author': 'Alice',

95

'tags': ['database', 'nosql', 'tutorial'],

96

'published': True

97

})

98

print(f"Created post with ID: {post1_id}")

99

100

post2_id = posts.store({

101

'title': 'Advanced Database Techniques',

102

'content': 'Learn advanced patterns for database design...',

103

'author': 'Bob',

104

'tags': ['database', 'advanced'],

105

'published': False

106

})

107

108

# Fetch specific document

109

post = posts.fetch(post1_id)

110

print(f"Retrieved post: {post['title']}")

111

112

# Update document

113

posts.update(post1_id, {

114

'title': 'Getting Started with UnQLite (Updated)',

115

'content': post['content'] + ' Updated with new examples.',

116

'author': 'Alice',

117

'tags': ['database', 'nosql', 'tutorial', 'updated'],

118

'published': True

119

})

120

121

# Get all documents

122

all_posts = posts.all()

123

print(f"Total posts: {len(all_posts)}")

124

125

# Delete document

126

posts.delete(post2_id)

127

```

128

129

### Dictionary-Style Interface

130

131

Access documents using dictionary-like syntax.

132

133

```python { .api }

134

def __getitem__(self, record_id):

135

"""Fetch document using collection[record_id] syntax."""

136

...

137

138

def __setitem__(self, record_id, record):

139

"""Update document using collection[record_id] = record syntax."""

140

...

141

142

def __delitem__(self, record_id):

143

"""Delete document using del collection[record_id] syntax."""

144

...

145

146

def __len__(self):

147

"""Return the number of records in the document collection."""

148

...

149

```

150

151

**Usage Example:**

152

153

```python

154

db = unqlite.UnQLite(':mem:')

155

products = db.collection('products')

156

products.create()

157

158

# Store initial document

159

product_id = products.store({

160

'name': 'Laptop',

161

'price': 999.99,

162

'category': 'electronics',

163

'in_stock': True

164

})

165

166

# Dictionary-style access

167

product = products[product_id]

168

print(f"Product: {product['name']}")

169

170

# Dictionary-style update

171

products[product_id] = {

172

'name': 'Gaming Laptop',

173

'price': 1299.99,

174

'category': 'electronics',

175

'in_stock': True,

176

'features': ['RGB lighting', 'High refresh rate']

177

}

178

179

# Check collection size

180

print(f"Products in collection: {len(products)}")

181

182

# Dictionary-style deletion

183

del products[product_id]

184

print(f"Products after deletion: {len(products)}")

185

```

186

187

### Document Querying and Filtering

188

189

Filter documents using Python callback functions.

190

191

```python { .api }

192

def filter(self, filter_fn):

193

"""Filter the records in the collection using the provided Python callback.

194

Returns list of matching documents."""

195

...

196

```

197

198

**Usage Example:**

199

200

```python

201

db = unqlite.UnQLite(':mem:')

202

employees = db.collection('employees')

203

employees.create()

204

205

# Add sample data

206

sample_employees = [

207

{'name': 'Alice', 'department': 'Engineering', 'salary': 85000, 'active': True},

208

{'name': 'Bob', 'department': 'Marketing', 'salary': 65000, 'active': True},

209

{'name': 'Charlie', 'department': 'Engineering', 'salary': 95000, 'active': False},

210

{'name': 'Diana', 'department': 'Sales', 'salary': 70000, 'active': True},

211

{'name': 'Eve', 'department': 'Engineering', 'salary': 90000, 'active': True}

212

]

213

214

for emp in sample_employees:

215

employees.store(emp)

216

217

# Filter by department

218

def is_engineer(employee):

219

return employee.get('department') == 'Engineering'

220

221

engineers = employees.filter(is_engineer)

222

print(f"Engineers: {len(engineers)}")

223

for eng in engineers:

224

print(f" {eng['name']}: ${eng['salary']}")

225

226

# Filter by salary and status

227

def high_earning_active(employee):

228

return employee.get('salary', 0) > 80000 and employee.get('active', False)

229

230

high_earners = employees.filter(high_earning_active)

231

print(f"High-earning active employees: {len(high_earners)}")

232

233

# Complex filter with multiple conditions

234

def senior_engineer(employee):

235

return (employee.get('department') == 'Engineering' and

236

employee.get('salary', 0) > 90000 and

237

employee.get('active', False))

238

239

senior_engineers = employees.filter(senior_engineer)

240

print(f"Senior engineers: {len(senior_engineers)}")

241

```

242

243

### Schema Management

244

245

Define and manage document schemas for data validation.

246

247

```python { .api }

248

def set_schema(self, _schema=None, **kwargs):

249

"""Set collection schema for document validation."""

250

...

251

252

def get_schema(self):

253

"""Get the current collection schema."""

254

...

255

```

256

257

**Usage Example:**

258

259

```python

260

db = unqlite.UnQLite('structured.db')

261

users = db.collection('users')

262

users.create()

263

264

# Define schema

265

user_schema = {

266

'name': {'type': 'string', 'required': True},

267

'email': {'type': 'string', 'required': True},

268

'age': {'type': 'number', 'required': False},

269

'active': {'type': 'boolean', 'default': True}

270

}

271

272

# Set schema

273

users.set_schema(user_schema)

274

275

# Alternative syntax using kwargs

276

users.set_schema(

277

name={'type': 'string', 'required': True},

278

email={'type': 'string', 'required': True}

279

)

280

281

# Retrieve schema

282

current_schema = users.get_schema()

283

print(f"Current schema: {current_schema}")

284

285

# Store documents (schema validation depends on UnQLite/Jx9 implementation)

286

try:

287

user_id = users.store({

288

'name': 'Alice Johnson',

289

'email': 'alice@example.com',

290

'age': 30

291

})

292

print(f"User stored with ID: {user_id}")

293

except Exception as e:

294

print(f"Schema validation failed: {e}")

295

```

296

297

### Collection Metadata

298

299

Access collection metadata and status information.

300

301

```python { .api }

302

def last_record_id(self):

303

"""Return the ID of the last document to be stored."""

304

...

305

306

def current_record_id(self):

307

"""Return the ID of the current JSON document."""

308

...

309

310

def creation_date(self):

311

"""Return collection creation date."""

312

...

313

314

def error_log(self):

315

"""Return collection error log."""

316

...

317

```

318

319

**Usage Example:**

320

321

```python

322

db = unqlite.UnQLite('metadata.db')

323

logs = db.collection('logs')

324

logs.create()

325

326

# Store some documents

327

log1_id = logs.store({'level': 'info', 'message': 'Application started'})

328

log2_id = logs.store({'level': 'warning', 'message': 'Low disk space'})

329

log3_id = logs.store({'level': 'error', 'message': 'Database connection failed'})

330

331

# Get metadata

332

print(f"Last record ID: {logs.last_record_id()}")

333

print(f"Current record ID: {logs.current_record_id()}")

334

print(f"Creation date: {logs.creation_date()}")

335

336

# Check for errors

337

error_log = logs.error_log()

338

if error_log:

339

print(f"Errors: {error_log}")

340

```

341

342

### Cursor Operations

343

344

Navigate through collection documents with cursor-like operations.

345

346

```python { .api }

347

def fetch_current(self):

348

"""Return current document at cursor position."""

349

...

350

351

def reset_cursor(self):

352

"""Reset collection cursor to beginning."""

353

...

354

```

355

356

**Usage Example:**

357

358

```python

359

db = unqlite.UnQLite(':mem:')

360

news = db.collection('news')

361

news.create()

362

363

# Add articles

364

articles = [

365

{'headline': 'Tech News Update', 'category': 'technology'},

366

{'headline': 'Sports Results', 'category': 'sports'},

367

{'headline': 'Weather Forecast', 'category': 'weather'}

368

]

369

370

for article in articles:

371

news.store(article)

372

373

# Reset cursor and fetch current

374

news.reset_cursor()

375

current = news.fetch_current()

376

if current:

377

print(f"Current article: {current['headline']}")

378

```

379

380

### Collection Iteration

381

382

Iterate through all documents in a collection.

383

384

```python { .api }

385

def iterator(self):

386

"""Return CollectionIterator object."""

387

...

388

389

def __iter__(self):

390

"""Return iterator for collection documents."""

391

...

392

393

class CollectionIterator:

394

def __iter__(self):

395

"""Setup iteration."""

396

...

397

398

def __next__(self):

399

"""Get next document. Raises StopIteration at end."""

400

...

401

```

402

403

**Usage Example:**

404

405

```python

406

db = unqlite.UnQLite(':mem:')

407

tasks = db.collection('tasks')

408

tasks.create()

409

410

# Add tasks

411

task_data = [

412

{'title': 'Write documentation', 'priority': 'high', 'completed': False},

413

{'title': 'Review code', 'priority': 'medium', 'completed': True},

414

{'title': 'Deploy application', 'priority': 'high', 'completed': False},

415

{'title': 'Update dependencies', 'priority': 'low', 'completed': False}

416

]

417

418

for task in task_data:

419

tasks.store(task)

420

421

# Iterate through all tasks

422

print("All tasks:")

423

for task in tasks:

424

status = "✓" if task['completed'] else "○"

425

print(f" {status} {task['title']} ({task['priority']})")

426

427

# Use explicit iterator

428

print("High-priority tasks:")

429

task_iter = tasks.iterator()

430

for task in task_iter:

431

if task['priority'] == 'high':

432

print(f" {task['title']}")

433

```

434

435

## Advanced Usage

436

437

### Complex Document Structures

438

439

Work with nested documents and complex data structures:

440

441

```python

442

db = unqlite.UnQLite('complex.db')

443

orders = db.collection('orders')

444

orders.create()

445

446

# Complex nested document

447

order = {

448

'order_id': 'ORD-2024-001',

449

'customer': {

450

'name': 'Alice Johnson',

451

'email': 'alice@example.com',

452

'address': {

453

'street': '123 Main St',

454

'city': 'Anytown',

455

'zip': '12345'

456

}

457

},

458

'items': [

459

{'product': 'Laptop', 'quantity': 1, 'price': 999.99},

460

{'product': 'Mouse', 'quantity': 2, 'price': 29.99}

461

],

462

'total': 1059.97,

463

'status': 'pending',

464

'created_at': '2024-01-15T10:30:00Z'

465

}

466

467

order_id = orders.store(order)

468

469

# Filter by nested properties

470

def high_value_orders(order):

471

return order.get('total', 0) > 500

472

473

valuable_orders = orders.filter(high_value_orders)

474

print(f"High-value orders: {len(valuable_orders)}")

475

```

476

477

### Bulk Operations

478

479

Efficiently handle multiple documents:

480

481

```python

482

db = unqlite.UnQLite('bulk.db')

483

inventory = db.collection('inventory')

484

inventory.create()

485

486

# Bulk insert

487

products = [

488

{'sku': 'LAPTOP-001', 'name': 'Gaming Laptop', 'stock': 25},

489

{'sku': 'MOUSE-001', 'name': 'Wireless Mouse', 'stock': 100},

490

{'sku': 'KEYBOARD-001', 'name': 'Mechanical Keyboard', 'stock': 50}

491

]

492

493

# Store all products

494

product_ids = []

495

for product in products:

496

product_id = inventory.store(product, return_id=True)

497

product_ids.append(product_id)

498

499

print(f"Stored {len(product_ids)} products")

500

501

# Bulk update using filter

502

def needs_restock(item):

503

return item.get('stock', 0) < 30

504

505

low_stock_items = inventory.filter(needs_restock)

506

print(f"Items needing restock: {len(low_stock_items)}")

507

508

# Update low stock items

509

for item in low_stock_items:

510

# Note: This requires knowing the record ID

511

# In practice, you'd need to track IDs or use custom logic

512

updated_item = item.copy()

513

updated_item['status'] = 'reorder_needed'

514

# inventory.update(item_id, updated_item)

515

```

516

517

## Performance Considerations

518

519

- **Use appropriate indexing**: While not directly exposed, UnQLite/Jx9 may benefit from proper key design

520

- **Minimize filter complexity**: Complex Python callbacks can be slow for large collections

521

- **Batch operations**: Group related operations when possible

522

- **Consider pagination**: For large result sets, implement pagination patterns

523

524

```python

525

# Efficient: Simple filter conditions

526

def active_users(user):

527

return user.get('active', False)

528

529

# Less efficient: Complex calculations in filter

530

def complex_scoring(user):

531

score = sum(user.get('metrics', {}).values()) * 0.8

532

return score > calculate_threshold(user.get('category'))

533

534

# Better: Pre-calculate and store scores

535

def pre_calculated_filter(user):

536

return user.get('precalculated_score', 0) > user.get('threshold', 0)

537

```