or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

client.mdindex.mdreferences.mdresources.mdsearch.mdutilities.md

search.mddocs/

0

# Search and Query

1

2

Advanced FHIR search capabilities with chaining, modifiers, includes, pagination, and complex query building. SearchSets provide a fluent API for building and executing FHIR queries.

3

4

## Capabilities

5

6

### Basic Search Operations

7

8

Core search functionality for building and executing FHIR queries.

9

10

```python { .api }

11

def search(self, **params) -> FHIRSearchSet:

12

"""

13

Add search parameters to the query.

14

15

Parameters:

16

- **params: Search parameters as keyword arguments

17

18

Returns:

19

New SearchSet instance with parameters added

20

"""

21

22

def limit(self, count: int) -> FHIRSearchSet:

23

"""

24

Set maximum number of results to return.

25

26

Parameters:

27

- count: Maximum result count

28

29

Returns:

30

New SearchSet instance with limit applied

31

"""

32

33

def sort(self, *args) -> FHIRSearchSet:

34

"""

35

Set sort parameters for results.

36

37

Parameters:

38

- *args: Sort fields, prefix with '-' for descending order

39

40

Returns:

41

New SearchSet instance with sorting applied

42

"""

43

44

def elements(self, *args, exclude=False) -> FHIRSearchSet:

45

"""

46

Specify which elements to include or exclude in results.

47

48

Parameters:

49

- *args: Element names to include/exclude

50

- exclude: If True, exclude specified elements; if False, include only specified elements

51

52

Returns:

53

New SearchSet instance with element selection

54

"""

55

```

56

57

### Advanced Search Features

58

59

Include, revinclude, and _has parameter support for complex queries.

60

61

```python { .api }

62

def include(

63

self,

64

resource_type: str,

65

attr: str = None,

66

*,

67

iterate: bool = False

68

) -> FHIRSearchSet:

69

"""

70

Add _include parameter to include referenced resources.

71

72

Parameters:

73

- resource_type: Resource type to include

74

- attr: Reference parameter name (required unless resource_type is '*')

75

- iterate: Whether to apply :iterate modifier

76

77

Returns:

78

New SearchSet instance with include added

79

"""

80

81

def revinclude(

82

self,

83

resource_type: str,

84

attr: str = None,

85

*,

86

iterate: bool = False

87

) -> FHIRSearchSet:

88

"""

89

Add _revinclude parameter to include referencing resources.

90

91

Parameters:

92

- resource_type: Resource type that references this type

93

- attr: Reference parameter name (required unless resource_type is '*')

94

- iterate: Whether to apply :iterate modifier

95

96

Returns:

97

New SearchSet instance with revinclude added

98

"""

99

100

def has(self, *args, **kwargs) -> FHIRSearchSet:

101

"""

102

Add _has parameter for reverse chaining.

103

104

Parameters:

105

- *args: Positional _has parameters

106

- **kwargs: Named _has parameters

107

108

Returns:

109

New SearchSet instance with _has parameter added

110

"""

111

```

112

113

### Result Fetching

114

115

Methods for executing queries and retrieving results.

116

117

```python { .api }

118

async def count(self) -> int:

119

"""

120

Get total count of matching resources.

121

122

Returns:

123

Total number of resources matching the query

124

"""

125

126

async def first(self) -> FHIRResource:

127

"""

128

Get the first result from the query.

129

130

Returns:

131

First matching resource or None if no results

132

"""

133

134

async def get(self) -> FHIRResource:

135

"""

136

Get exactly one result from the query.

137

138

Returns:

139

Single matching resource

140

141

Raises:

142

- ResourceNotFound: If no resources match

143

- MultipleResourcesFound: If multiple resources match

144

"""

145

146

async def fetch(self) -> list:

147

"""

148

Fetch all results from current page.

149

150

Returns:

151

List of resources from current page

152

"""

153

154

async def fetch_all(self) -> list:

155

"""

156

Fetch all results from all pages.

157

158

Returns:

159

List of all matching resources across all pages

160

"""

161

162

async def fetch_raw(self) -> dict:

163

"""

164

Fetch raw Bundle response from server.

165

166

Returns:

167

Raw FHIR Bundle dict

168

"""

169

```

170

171

### SearchSet Utilities

172

173

Helper methods for working with search sets.

174

175

```python { .api }

176

def clone(self) -> FHIRSearchSet:

177

"""

178

Create a copy of the SearchSet.

179

180

Returns:

181

New SearchSet instance with same parameters

182

"""

183

184

async def __aiter__(self):

185

"""

186

Async iteration support for AsyncFHIRSearchSet.

187

188

Allows using 'async for' to iterate through all search results,

189

automatically handling pagination.

190

191

Yields:

192

Individual resources from search results

193

"""

194

```

195

196

### Search Query Builder

197

198

Advanced query building utilities for complex search parameters.

199

200

```python { .api }

201

def SQ(*args, **kwargs) -> dict:

202

"""

203

Build search query parameters with advanced syntax support.

204

205

Supports:

206

- Chained parameters: patient__Patient__name='John'

207

- Search modifiers: name__contains='test'

208

- Date comparisons: date__ge='2020-01-01'

209

- Multiple values: status__in=['active', 'inactive']

210

211

Returns:

212

Dict of properly formatted search parameters

213

"""

214

215

class Raw:

216

def __init__(self, **kwargs):

217

"""

218

Wrapper for raw parameter values that should not be transformed.

219

220

Parameters:

221

- **kwargs: Raw parameter key-value pairs

222

"""

223

```

224

225

## Usage Examples

226

227

### Basic Search Operations

228

229

```python

230

import asyncio

231

from fhirpy import AsyncFHIRClient

232

233

async def basic_search():

234

client = AsyncFHIRClient('https://hapi.fhir.org/baseR4')

235

236

# Simple search

237

patients = client.resources('Patient').search(family='Smith')

238

results = await patients.fetch()

239

240

# Search with multiple parameters

241

patients = client.resources('Patient').search(

242

family='Smith',

243

given='John',

244

active=True

245

)

246

247

# Limit results and sort

248

recent_patients = (client.resources('Patient')

249

.search(active=True)

250

.sort('-_lastUpdated')

251

.limit(10))

252

253

results = await recent_patients.fetch()

254

255

# Get total count

256

total = await patients.count()

257

print(f"Found {total} patients")

258

```

259

260

### Advanced Query Building with SQ

261

262

```python

263

from fhirpy.base.searchset import SQ

264

265

async def advanced_queries():

266

client = AsyncFHIRClient('https://hapi.fhir.org/baseR4')

267

268

# Chained search - find patients with observations

269

query = SQ(patient__Patient__name='John')

270

observations = client.resources('Observation').search(**query)

271

272

# Search modifiers

273

query = SQ(

274

name__contains='John', # :contains modifier

275

birthdate__ge='1990-01-01', # greater than or equal

276

gender__not='unknown' # :not modifier

277

)

278

patients = client.resources('Patient').search(**query)

279

280

# Multiple values

281

query = SQ(status__in=['active', 'inactive'])

282

patients = client.resources('Patient').search(**query)

283

284

# Complex chained parameters

285

query = SQ(

286

patient__Patient__general_practitioner__Organization__name='Hospital'

287

)

288

observations = client.resources('Observation').search(**query)

289

290

results = await observations.fetch()

291

```

292

293

### Includes and References

294

295

```python

296

async def include_examples():

297

client = AsyncFHIRClient('https://hapi.fhir.org/baseR4')

298

299

# Include patient data with observations

300

observations = (client.resources('Observation')

301

.search(code='55284-4') # Blood pressure

302

.include('Patient', 'subject'))

303

304

bundle = await observations.fetch_raw()

305

# Bundle contains both observations and referenced patients

306

307

# Reverse include - get patients with their observations

308

patients = (client.resources('Patient')

309

.search(active=True)

310

.revinclude('Observation', 'subject')

311

.limit(5))

312

313

results = await patients.fetch_all()

314

315

# Include with iteration

316

encounters = (client.resources('Encounter')

317

.include('Patient', 'subject', iterate=True)

318

.include('Organization', 'serviceProvider'))

319

320

# Wildcard includes

321

encounters = client.resources('Encounter').include('*')

322

```

323

324

### Pagination and Result Handling

325

326

```python

327

async def pagination_example():

328

client = AsyncFHIRClient('https://hapi.fhir.org/baseR4')

329

330

# Page through results

331

patients = client.resources('Patient').limit(50)

332

333

page1 = await patients.fetch()

334

print(f"Page 1: {len(page1)} patients")

335

336

# Get all results across all pages

337

all_patients = await patients.fetch_all()

338

print(f"Total patients: {len(all_patients)}")

339

340

# Get count without fetching data

341

total_count = await patients.count()

342

print(f"Total count: {total_count}")

343

344

# Get single result safely

345

try:

346

specific_patient = await (client.resources('Patient')

347

.search(identifier='12345')

348

.get())

349

except ResourceNotFound:

350

print("Patient not found")

351

except MultipleResourcesFound:

352

print("Multiple patients found with same identifier")

353

```

354

355

### Complex Search Scenarios

356

357

```python

358

async def complex_search():

359

client = AsyncFHIRClient('https://hapi.fhir.org/baseR4')

360

361

# Find observations for patients in specific organization

362

query = SQ(

363

subject__Patient__organization='Organization/123',

364

code__text__contains='blood',

365

date__ge='2023-01-01',

366

date__lt='2024-01-01'

367

)

368

369

observations = (client.resources('Observation')

370

.search(**query)

371

.include('Patient', 'subject')

372

.include('Practitioner', 'performer')

373

.sort('-date')

374

.limit(100))

375

376

# Use _has for reverse chaining

377

patients_with_conditions = (client.resources('Patient')

378

.has('Condition', 'subject', code='diabetes'))

379

380

# Element selection for performance

381

patients_summary = (client.resources('Patient')

382

.search(active=True)

383

.elements('id', 'name', 'birthDate')

384

.limit(1000))

385

386

# Combine multiple techniques

387

comprehensive_search = (client.resources('Encounter')

388

.search(status='finished')

389

.include('Patient', 'subject')

390

.revinclude('Observation', 'encounter')

391

.has('Condition', 'encounter',

392

category='problem-list-item')

393

.sort('-date')

394

.limit(20))

395

396

results = await comprehensive_search.fetch_raw()

397

398

# Process bundle entries

399

encounters = [entry['resource'] for entry in results['entry']

400

if entry['resource']['resourceType'] == 'Encounter']

401

patients = [entry['resource'] for entry in results['entry']

402

if entry['resource']['resourceType'] == 'Patient']

403

observations = [entry['resource'] for entry in results['entry']

404

if entry['resource']['resourceType'] == 'Observation']

405

```

406

407

### SearchSet Iteration

408

409

```python

410

async def iteration_example():

411

client = AsyncFHIRClient('https://hapi.fhir.org/baseR4')

412

413

# Async iteration over search results

414

patients = client.resources('Patient').search(active=True)

415

416

async for patient in patients:

417

print(f"Patient: {patient.get_by_path('name.0.family')}")

418

419

# Process each patient individually

420

if patient.get('gender') == 'female':

421

# Do something with female patients

422

pass

423

424

# Clone and modify search sets

425

base_search = client.resources('Patient').search(active=True)

426

427

male_patients = base_search.clone().search(gender='male')

428

female_patients = base_search.clone().search(gender='female')

429

430

male_count = await male_patients.count()

431

female_count = await female_patients.count()

432

433

print(f"Male: {male_count}, Female: {female_count}")

434

```