or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-operations.mdauthentication.mdcore-client.mddocument-modeling.mddsl-queries.mdhelper-functions.mdindex.mdnamespaced-apis.mdplugin-apis.md

dsl-queries.mddocs/

0

# DSL and Query Building

1

2

Domain-specific language for building complex search queries, aggregations, and filters with a Pythonic API that abstracts OpenSearch's JSON-based query syntax. The DSL provides type-safe query construction and chainable operations for intuitive query building.

3

4

## Capabilities

5

6

### Search Builder

7

8

Central class for constructing and executing search requests with fluent interface.

9

10

```python { .api }

11

class Search:

12

def __init__(self, using=None, index=None, doc_type=None):

13

"""

14

Initialize search object.

15

16

Parameters:

17

- using: OpenSearch client instance

18

- index (str/list): Index name(s) to search

19

- doc_type (str/list): Document type(s) (deprecated)

20

"""

21

22

def query(self, query):

23

"""Add query to search. Returns new Search instance."""

24

25

def filter(self, filter):

26

"""Add filter to search. Returns new Search instance."""

27

28

def post_filter(self, post_filter):

29

"""Add post filter to search. Returns new Search instance."""

30

31

def exclude(self, query):

32

"""Add must_not query. Returns new Search instance."""

33

34

def aggs(self, aggs):

35

"""Add aggregations. Returns new Search instance."""

36

37

def sort(self, *keys):

38

"""Add sorting. Returns new Search instance."""

39

40

def source(self, fields=None, **kwargs):

41

"""Configure source filtering. Returns new Search instance."""

42

43

def highlight(self, fields, **kwargs):

44

"""Add highlighting. Returns new Search instance."""

45

46

def suggest(self, name, text, **kwargs):

47

"""Add suggestion. Returns new Search instance."""

48

49

def script_fields(self, **fields):

50

"""Add script fields. Returns new Search instance."""

51

52

def params(self, **kwargs):

53

"""Set search parameters. Returns new Search instance."""

54

55

def execute(self, ignore_cache=False):

56

"""Execute search and return Response object."""

57

58

def scan(self):

59

"""Return generator for scanning all results."""

60

61

def count(self):

62

"""Return document count for the query."""

63

64

def delete(self):

65

"""Delete documents matching the query."""

66

```

67

68

### Query DSL

69

70

Query builders for different types of search queries.

71

72

```python { .api }

73

class Q:

74

@classmethod

75

def match(cls, field=None, query=None, **kwargs):

76

"""

77

Match query for full-text search.

78

79

Parameters:

80

- field (str): Field to search

81

- query (str): Query text

82

- operator (str): 'and' or 'or'

83

- fuzziness (str/int): Fuzziness level

84

- minimum_should_match (str/int): Minimum should match

85

86

Returns:

87

Match query object

88

"""

89

90

@classmethod

91

def match_all(cls, boost=None):

92

"""Match all documents query."""

93

94

@classmethod

95

def match_none(cls):

96

"""Match no documents query."""

97

98

@classmethod

99

def match_phrase(cls, field=None, query=None, **kwargs):

100

"""Match phrase query for exact phrase matching."""

101

102

@classmethod

103

def match_phrase_prefix(cls, field=None, query=None, **kwargs):

104

"""Match phrase prefix query."""

105

106

@classmethod

107

def multi_match(cls, query=None, fields=None, **kwargs):

108

"""Multi-field match query."""

109

110

@classmethod

111

def term(cls, field=None, value=None, **kwargs):

112

"""Term query for exact value matching."""

113

114

@classmethod

115

def terms(cls, field=None, values=None, **kwargs):

116

"""Terms query for multiple exact values."""

117

118

@classmethod

119

def range(cls, field=None, **kwargs):

120

"""Range query for numeric/date ranges."""

121

122

@classmethod

123

def exists(cls, field=None):

124

"""Exists query to check field presence."""

125

126

@classmethod

127

def missing(cls, field=None):

128

"""Missing query to check field absence."""

129

130

@classmethod

131

def bool(cls, must=None, must_not=None, should=None, filter=None, **kwargs):

132

"""Boolean query for combining multiple queries."""

133

134

@classmethod

135

def nested(cls, path=None, query=None, **kwargs):

136

"""Nested query for nested object fields."""

137

138

@classmethod

139

def has_child(cls, type=None, query=None, **kwargs):

140

"""Has child query for parent-child relationships."""

141

142

@classmethod

143

def has_parent(cls, parent_type=None, query=None, **kwargs):

144

"""Has parent query for parent-child relationships."""

145

146

@classmethod

147

def prefix(cls, field=None, value=None, **kwargs):

148

"""Prefix query for prefix matching."""

149

150

@classmethod

151

def wildcard(cls, field=None, value=None, **kwargs):

152

"""Wildcard query with * and ? patterns."""

153

154

@classmethod

155

def regexp(cls, field=None, value=None, **kwargs):

156

"""Regular expression query."""

157

158

@classmethod

159

def fuzzy(cls, field=None, value=None, **kwargs):

160

"""Fuzzy query for approximate matching."""

161

162

@classmethod

163

def ids(cls, values=None, **kwargs):

164

"""IDs query for specific document IDs."""

165

166

@classmethod

167

def constant_score(cls, query=None, boost=None):

168

"""Constant score query."""

169

170

@classmethod

171

def dis_max(cls, queries=None, **kwargs):

172

"""Disjunction max query."""

173

174

@classmethod

175

def function_score(cls, query=None, functions=None, **kwargs):

176

"""Function score query for custom scoring."""

177

178

@classmethod

179

def more_like_this(cls, fields=None, like=None, **kwargs):

180

"""More like this query for similar documents."""

181

182

@classmethod

183

def simple_query_string(cls, query=None, **kwargs):

184

"""Simple query string query."""

185

186

@classmethod

187

def query_string(cls, query=None, **kwargs):

188

"""Full query string query with Lucene syntax."""

189

```

190

191

### Aggregations DSL

192

193

Builders for various types of aggregations and analytics.

194

195

```python { .api }

196

class A:

197

@classmethod

198

def terms(cls, field=None, **kwargs):

199

"""Terms aggregation for grouping by field values."""

200

201

@classmethod

202

def date_histogram(cls, field=None, **kwargs):

203

"""Date histogram aggregation for time-based grouping."""

204

205

@classmethod

206

def histogram(cls, field=None, **kwargs):

207

"""Histogram aggregation for numeric ranges."""

208

209

@classmethod

210

def range(cls, field=None, **kwargs):

211

"""Range aggregation for custom ranges."""

212

213

@classmethod

214

def date_range(cls, field=None, **kwargs):

215

"""Date range aggregation."""

216

217

@classmethod

218

def nested(cls, path=None):

219

"""Nested aggregation for nested objects."""

220

221

@classmethod

222

def reverse_nested(cls, path=None):

223

"""Reverse nested aggregation."""

224

225

@classmethod

226

def filter(cls, filter=None):

227

"""Filter aggregation."""

228

229

@classmethod

230

def filters(cls, filters=None, **kwargs):

231

"""Filters aggregation for multiple filters."""

232

233

@classmethod

234

def global_agg(cls):

235

"""Global aggregation."""

236

237

@classmethod

238

def missing(cls, field=None):

239

"""Missing aggregation for documents without field."""

240

241

@classmethod

242

def sampler(cls, shard_size=None):

243

"""Sampler aggregation for sampling documents."""

244

245

@classmethod

246

def significant_terms(cls, field=None, **kwargs):

247

"""Significant terms aggregation."""

248

249

@classmethod

250

def cardinality(cls, field=None, **kwargs):

251

"""Cardinality metric aggregation."""

252

253

@classmethod

254

def avg(cls, field=None, **kwargs):

255

"""Average metric aggregation."""

256

257

@classmethod

258

def max(cls, field=None, **kwargs):

259

"""Max metric aggregation."""

260

261

@classmethod

262

def min(cls, field=None, **kwargs):

263

"""Min metric aggregation."""

264

265

@classmethod

266

def sum(cls, field=None, **kwargs):

267

"""Sum metric aggregation."""

268

269

@classmethod

270

def value_count(cls, field=None, **kwargs):

271

"""Value count metric aggregation."""

272

273

@classmethod

274

def stats(cls, field=None, **kwargs):

275

"""Stats metric aggregation (count, min, max, avg, sum)."""

276

277

@classmethod

278

def extended_stats(cls, field=None, **kwargs):

279

"""Extended stats metric aggregation."""

280

281

@classmethod

282

def percentiles(cls, field=None, **kwargs):

283

"""Percentiles metric aggregation."""

284

285

@classmethod

286

def percentile_ranks(cls, field=None, **kwargs):

287

"""Percentile ranks metric aggregation."""

288

289

@classmethod

290

def top_hits(cls, **kwargs):

291

"""Top hits metric aggregation for sample documents."""

292

```

293

294

### Multi Search

295

296

Execute multiple searches in a single request.

297

298

```python { .api }

299

class MultiSearch:

300

def __init__(self, using=None, index=None):

301

"""Initialize multi-search object."""

302

303

def add(self, search):

304

"""Add search to multi-search. Returns self."""

305

306

def execute(self, ignore_cache=False, raise_on_error=True):

307

"""Execute all searches and return list of responses."""

308

```

309

310

## Usage Examples

311

312

### Basic Query Building

313

314

```python

315

from opensearchpy import Search, Q

316

317

# Create search object

318

s = Search(using=client, index='products')

319

320

# Add match query

321

s = s.query(Q('match', title='laptop'))

322

323

# Add filter

324

s = s.filter(Q('range', price={'gte': 100, 'lte': 1000}))

325

326

# Add sorting

327

s = s.sort('-price', 'title.keyword')

328

329

# Execute search

330

response = s.execute()

331

for hit in response:

332

print(f"{hit.title}: ${hit.price}")

333

```

334

335

### Complex Boolean Queries

336

337

```python

338

# Build complex boolean query

339

complex_query = Q('bool',

340

must=[

341

Q('match', title='laptop'),

342

Q('range', price={'gte': 500})

343

],

344

should=[

345

Q('match', brand='Apple'),

346

Q('match', brand='Dell')

347

],

348

must_not=[

349

Q('term', status='discontinued')

350

],

351

filter=[

352

Q('term', category='electronics'),

353

Q('exists', field='in_stock')

354

],

355

minimum_should_match=1

356

)

357

358

s = Search(using=client, index='products')

359

s = s.query(complex_query)

360

response = s.execute()

361

```

362

363

### Aggregations

364

365

```python

366

from opensearchpy import A

367

368

# Terms aggregation with sub-aggregations

369

s = Search(using=client, index='sales')

370

s.aggs.bucket('categories', A('terms', field='category.keyword', size=10)) \

371

.metric('avg_price', A('avg', field='price')) \

372

.metric('total_sales', A('sum', field='amount'))

373

374

# Date histogram aggregation

375

s.aggs.bucket('sales_over_time',

376

A('date_histogram',

377

field='order_date',

378

calendar_interval='1M',

379

format='yyyy-MM'

380

)

381

).metric('monthly_revenue', A('sum', field='amount'))

382

383

response = s.execute()

384

385

# Process aggregation results

386

for bucket in response.aggregations.categories.buckets:

387

print(f"Category: {bucket.key}")

388

print(f" Count: {bucket.doc_count}")

389

print(f" Avg Price: ${bucket.avg_price.value:.2f}")

390

print(f" Total Sales: ${bucket.total_sales.value:.2f}")

391

```

392

393

### Nested Queries

394

395

```python

396

# Query nested objects

397

nested_query = Q('nested',

398

path='reviews',

399

query=Q('bool',

400

must=[

401

Q('range', **{'reviews.rating': {'gte': 4}}),

402

Q('match', **{'reviews.content': 'excellent'})

403

]

404

)

405

)

406

407

s = Search(using=client, index='products')

408

s = s.query(nested_query)

409

response = s.execute()

410

```

411

412

### Function Score Queries

413

414

```python

415

# Custom scoring with function score

416

function_score_query = Q('function_score',

417

query=Q('match', title='laptop'),

418

functions=[

419

{

420

'filter': Q('term', featured=True),

421

'weight': 2.0

422

},

423

{

424

'field_value_factor': {

425

'field': 'popularity_score',

426

'factor': 1.5,

427

'modifier': 'log1p'

428

}

429

},

430

{

431

'gauss': {

432

'price': {

433

'origin': 500,

434

'scale': 200,

435

'decay': 0.5

436

}

437

}

438

}

439

],

440

score_mode='sum',

441

boost_mode='multiply'

442

)

443

444

s = Search(using=client, index='products')

445

s = s.query(function_score_query)

446

response = s.execute()

447

```

448

449

### Multi-Search Operations

450

451

```python

452

from opensearchpy import MultiSearch

453

454

# Create multiple searches

455

ms = MultiSearch(using=client)

456

457

# Add different searches

458

ms = ms.add(Search(index='products').query(Q('match', category='laptops')))

459

ms = ms.add(Search(index='products').query(Q('match', category='phones')))

460

ms = ms.add(Search(index='orders').query(Q('range', order_date={'gte': 'now-1d'})))

461

462

# Execute all searches

463

responses = ms.execute()

464

465

for i, response in enumerate(responses):

466

print(f"Search {i+1}: {response.hits.total.value} hits")

467

```

468

469

### Search Highlighting

470

471

```python

472

# Add highlighting to search

473

s = Search(using=client, index='articles')

474

s = s.query(Q('match', content='machine learning'))

475

s = s.highlight('content', fragment_size=150, number_of_fragments=3)

476

s = s.highlight('title', fragment_size=0, number_of_fragments=0)

477

478

response = s.execute()

479

480

for hit in response:

481

print(f"Title: {hit.title}")

482

if hasattr(hit.meta, 'highlight'):

483

if 'title' in hit.meta.highlight:

484

print(f"Highlighted title: {hit.meta.highlight.title[0]}")

485

if 'content' in hit.meta.highlight:

486

for fragment in hit.meta.highlight.content:

487

print(f" Fragment: {fragment}")

488

```

489

490

### Suggestions

491

492

```python

493

# Add suggestions to search

494

s = Search(using=client, index='products')

495

s = s.suggest('title_suggestion', 'lapto', term={'field': 'title'})

496

s = s.suggest('completion_suggestion', 'lap', completion={'field': 'suggest'})

497

498

response = s.execute()

499

500

# Process suggestions

501

if hasattr(response, 'suggest'):

502

for suggestion in response.suggest.title_suggestion:

503

for option in suggestion.options:

504

print(f"Suggestion: {option.text} (score: {option.score})")

505

```