0
# Search and Queries
1
2
Fluent API for building and executing Elasticsearch queries with comprehensive support for filtering, full-text search, sorting, pagination, and result processing. The query system mirrors Elasticsearch's JSON DSL while providing a Pythonic interface for both simple and complex search operations.
3
4
## Capabilities
5
6
### Search Class
7
8
Main search request builder with fluent API for constructing and executing queries.
9
10
```python { .api }
11
class Search:
12
"""
13
Search request builder with fluent API.
14
"""
15
16
def __init__(self, using=None, index=None, doc_type=None):
17
"""
18
Initialize search request.
19
20
Args:
21
using (str, optional): Connection alias to use
22
index (str or list, optional): Index name(s) to search
23
doc_type (str, optional): Document type (deprecated in ES 7+)
24
"""
25
26
def query(self, query, **kwargs):
27
"""
28
Add query to search request.
29
30
Args:
31
query (str or Query): Query name or Query object
32
**kwargs: Query parameters if query is a string
33
34
Returns:
35
Search: New Search instance with query applied
36
"""
37
38
def filter(self, query, **kwargs):
39
"""
40
Add filter to search request (executed in filter context).
41
42
Args:
43
query (str or Query): Filter name or Query object
44
**kwargs: Filter parameters if query is a string
45
46
Returns:
47
Search: New Search instance with filter applied
48
"""
49
50
def exclude(self, query, **kwargs):
51
"""
52
Add exclusion filter to search request.
53
54
Args:
55
query (str or Query): Filter name or Query object
56
**kwargs: Filter parameters if query is a string
57
58
Returns:
59
Search: New Search instance with exclusion applied
60
"""
61
62
def sort(self, *keys):
63
"""
64
Add sorting to search request.
65
66
Args:
67
*keys: Sort keys (str, dict, or SortField objects)
68
69
Returns:
70
Search: New Search instance with sorting applied
71
"""
72
73
def extra(self, **kwargs):
74
"""
75
Add extra parameters to search request.
76
77
Args:
78
**kwargs: Additional search parameters
79
80
Returns:
81
Search: New Search instance with extra parameters
82
"""
83
84
def params(self, **kwargs):
85
"""
86
Add URL parameters to search request.
87
88
Args:
89
**kwargs: URL parameters
90
91
Returns:
92
Search: New Search instance with parameters
93
"""
94
95
def source(self, fields=None, **kwargs):
96
"""
97
Configure source field filtering.
98
99
Args:
100
fields (list or bool, optional): Fields to include/exclude
101
**kwargs: Source filtering parameters
102
103
Returns:
104
Search: New Search instance with source filtering
105
"""
106
107
def highlight(self, *fields, **kwargs):
108
"""
109
Add highlighting to search request.
110
111
Args:
112
*fields: Fields to highlight
113
**kwargs: Highlighting parameters
114
115
Returns:
116
Search: New Search instance with highlighting
117
"""
118
119
def suggest(self, name, text, **kwargs):
120
"""
121
Add suggestion to search request.
122
123
Args:
124
name (str): Suggestion name
125
text (str): Text to get suggestions for
126
**kwargs: Suggestion parameters
127
128
Returns:
129
Search: New Search instance with suggestion
130
"""
131
132
def from_(self, from_):
133
"""
134
Set starting offset for pagination.
135
136
Args:
137
from_ (int): Starting offset
138
139
Returns:
140
Search: New Search instance with offset
141
"""
142
143
def size(self, size):
144
"""
145
Set number of results to return.
146
147
Args:
148
size (int): Number of results
149
150
Returns:
151
Search: New Search instance with size limit
152
"""
153
154
def execute(self, ignore_cache=False):
155
"""
156
Execute search request.
157
158
Args:
159
ignore_cache (bool): Ignore cached results
160
161
Returns:
162
Response: Search response with results
163
"""
164
165
def scan(self):
166
"""
167
Execute search using scan and scroll for large result sets.
168
169
Returns:
170
generator: Generator yielding Hit objects
171
"""
172
173
def count(self):
174
"""
175
Get total count of matching documents.
176
177
Returns:
178
int: Count of matching documents
179
"""
180
181
def delete(self):
182
"""
183
Delete documents matching the search query.
184
185
Returns:
186
dict: Delete by query response
187
"""
188
189
def to_dict(self):
190
"""
191
Convert search to dictionary representation.
192
193
Returns:
194
dict: Search request as dictionary
195
"""
196
197
@classmethod
198
def from_dict(cls, d):
199
"""
200
Create Search from dictionary.
201
202
Args:
203
d (dict): Search request dictionary
204
205
Returns:
206
Search: Search instance
207
"""
208
```
209
210
### Async Search
211
212
Asynchronous version of Search class for async/await operations.
213
214
```python { .api }
215
class AsyncSearch:
216
"""
217
Async version of Search class.
218
"""
219
220
async def execute(self, ignore_cache=False):
221
"""
222
Async execute search request.
223
224
Args:
225
ignore_cache (bool): Ignore cached results
226
227
Returns:
228
Response: Search response with results
229
"""
230
231
async def count(self):
232
"""
233
Async get total count of matching documents.
234
235
Returns:
236
int: Count of matching documents
237
"""
238
239
async def delete(self):
240
"""
241
Async delete documents matching the search query.
242
243
Returns:
244
dict: Delete by query response
245
"""
246
```
247
248
### Multi-Search Operations
249
250
Execute multiple search requests in a single request for improved performance.
251
252
```python { .api }
253
class MultiSearch:
254
"""
255
Execute multiple search requests in a single request.
256
"""
257
258
def __init__(self, using=None, index=None):
259
"""
260
Initialize multi-search request.
261
262
Args:
263
using (str, optional): Connection alias to use
264
index (str or list, optional): Default index name(s)
265
"""
266
267
def add(self, search):
268
"""
269
Add search request to multi-search.
270
271
Args:
272
search (Search): Search request to add
273
274
Returns:
275
MultiSearch: Current MultiSearch instance
276
"""
277
278
def execute(self, ignore_cache=False, raise_on_error=True):
279
"""
280
Execute all search requests.
281
282
Args:
283
ignore_cache (bool): Ignore cached results
284
raise_on_error (bool): Raise exception on any search error
285
286
Returns:
287
list: List of Response objects for each search
288
"""
289
290
def to_dict(self):
291
"""
292
Convert multi-search to dictionary representation.
293
294
Returns:
295
dict: Multi-search request as dictionary
296
"""
297
298
class AsyncMultiSearch:
299
"""
300
Async version of MultiSearch for async/await operations.
301
"""
302
303
def __init__(self, using=None, index=None):
304
"""
305
Initialize async multi-search request.
306
307
Args:
308
using (str, optional): Connection alias to use
309
index (str or list, optional): Default index name(s)
310
"""
311
312
def add(self, search):
313
"""
314
Add async search request to multi-search.
315
316
Args:
317
search (AsyncSearch): Async search request to add
318
319
Returns:
320
AsyncMultiSearch: Current AsyncMultiSearch instance
321
"""
322
323
async def execute(self, ignore_cache=False, raise_on_error=True):
324
"""
325
Async execute all search requests.
326
327
Args:
328
ignore_cache (bool): Ignore cached results
329
raise_on_error (bool): Raise exception on any search error
330
331
Returns:
332
list: List of Response objects for each search
333
"""
334
```
335
336
### Query Factory Function
337
338
Main query factory function for creating query objects.
339
340
```python { .api }
341
def Q(name=None, **params):
342
"""
343
Create query object.
344
345
Args:
346
name (str, optional): Query type name
347
**params: Query parameters
348
349
Returns:
350
Query: Query object
351
352
Examples:
353
Q('match', title='python')
354
Q('bool', must=[Q('term', status='published')])
355
Q({'match': {'title': 'python'}}) # From dict
356
"""
357
```
358
359
### Common Query Types
360
361
#### Full-Text Queries
362
363
```python { .api }
364
class Match:
365
"""
366
Match query for full-text search.
367
"""
368
def __init__(self, **kwargs):
369
"""
370
Args:
371
**kwargs: Field-value pairs and query parameters
372
373
Parameters:
374
query (str): Query text
375
operator (str): 'and' or 'or' (default: 'or')
376
minimum_should_match (str or int): Minimum should match
377
analyzer (str): Analyzer to use
378
fuzziness (str or int): Fuzziness for fuzzy matching
379
prefix_length (int): Prefix length for fuzzy matching
380
max_expansions (int): Max expansions for fuzzy matching
381
boost (float): Query boost
382
"""
383
384
class MultiMatch:
385
"""
386
Multi-field match query.
387
"""
388
def __init__(self, query, fields=None, **kwargs):
389
"""
390
Args:
391
query (str): Query text
392
fields (list): Fields to search
393
**kwargs: Additional parameters
394
395
Parameters:
396
type (str): Multi-match type ('best_fields', 'most_fields', etc.)
397
operator (str): 'and' or 'or'
398
minimum_should_match (str or int): Minimum should match
399
analyzer (str): Analyzer to use
400
boost (float): Query boost
401
tie_breaker (float): Tie breaker for scoring
402
"""
403
404
class MatchPhrase:
405
"""
406
Match phrase query for exact phrase matching.
407
"""
408
def __init__(self, **kwargs):
409
"""
410
Args:
411
**kwargs: Field-value pairs and query parameters
412
413
Parameters:
414
slop (int): Allowed distance between terms
415
analyzer (str): Analyzer to use
416
boost (float): Query boost
417
"""
418
419
class MatchPhrasePrefix:
420
"""
421
Match phrase prefix query for phrase with prefix matching.
422
"""
423
def __init__(self, **kwargs):
424
"""
425
Args:
426
**kwargs: Field-value pairs and query parameters
427
428
Parameters:
429
slop (int): Allowed distance between terms
430
max_expansions (int): Max expansions for prefix
431
analyzer (str): Analyzer to use
432
boost (float): Query boost
433
"""
434
```
435
436
#### Term-Level Queries
437
438
```python { .api }
439
class Term:
440
"""
441
Exact term match query.
442
"""
443
def __init__(self, **kwargs):
444
"""
445
Args:
446
**kwargs: Field-value pairs and query parameters
447
448
Parameters:
449
boost (float): Query boost
450
case_insensitive (bool): Case insensitive matching
451
"""
452
453
class Terms:
454
"""
455
Multiple exact terms match query.
456
"""
457
def __init__(self, **kwargs):
458
"""
459
Args:
460
**kwargs: Field-list pairs and query parameters
461
462
Parameters:
463
boost (float): Query boost
464
"""
465
466
class Range:
467
"""
468
Range query for numeric and date ranges.
469
"""
470
def __init__(self, **kwargs):
471
"""
472
Args:
473
**kwargs: Field-range pairs and query parameters
474
475
Parameters:
476
gte: Greater than or equal to
477
gt: Greater than
478
lte: Less than or equal to
479
lt: Less than
480
format (str): Date format for date fields
481
time_zone (str): Time zone for date fields
482
boost (float): Query boost
483
"""
484
485
class Exists:
486
"""
487
Check field existence query.
488
"""
489
def __init__(self, field):
490
"""
491
Args:
492
field (str): Field to check for existence
493
"""
494
495
class Prefix:
496
"""
497
Prefix match query.
498
"""
499
def __init__(self, **kwargs):
500
"""
501
Args:
502
**kwargs: Field-prefix pairs and query parameters
503
504
Parameters:
505
boost (float): Query boost
506
case_insensitive (bool): Case insensitive matching
507
"""
508
509
class Wildcard:
510
"""
511
Wildcard pattern query.
512
"""
513
def __init__(self, **kwargs):
514
"""
515
Args:
516
**kwargs: Field-pattern pairs and query parameters
517
518
Parameters:
519
boost (float): Query boost
520
case_insensitive (bool): Case insensitive matching
521
"""
522
523
class Regexp:
524
"""
525
Regular expression query.
526
"""
527
def __init__(self, **kwargs):
528
"""
529
Args:
530
**kwargs: Field-pattern pairs and query parameters
531
532
Parameters:
533
flags (str): Regular expression flags
534
max_determinized_states (int): Max determinized states
535
boost (float): Query boost
536
"""
537
538
class Fuzzy:
539
"""
540
Fuzzy string matching query.
541
"""
542
def __init__(self, **kwargs):
543
"""
544
Args:
545
**kwargs: Field-value pairs and query parameters
546
547
Parameters:
548
fuzziness (str or int): Fuzziness level
549
prefix_length (int): Prefix length
550
max_expansions (int): Max expansions
551
transpositions (bool): Allow transpositions
552
boost (float): Query boost
553
"""
554
```
555
556
#### Compound Queries
557
558
```python { .api }
559
class Bool:
560
"""
561
Boolean query combining must/should/must_not/filter clauses.
562
"""
563
def __init__(self, must=None, should=None, must_not=None, filter=None, **kwargs):
564
"""
565
Args:
566
must (list, optional): Queries that must match
567
should (list, optional): Queries that should match
568
must_not (list, optional): Queries that must not match
569
filter (list, optional): Queries that must match (filter context)
570
**kwargs: Additional parameters
571
572
Parameters:
573
minimum_should_match (str or int): Minimum should match
574
boost (float): Query boost
575
"""
576
577
class DisMax:
578
"""
579
Disjunction max query.
580
"""
581
def __init__(self, queries=None, tie_breaker=None, **kwargs):
582
"""
583
Args:
584
queries (list): List of queries
585
tie_breaker (float): Tie breaker for scoring
586
**kwargs: Additional parameters
587
"""
588
589
class FunctionScore:
590
"""
591
Function score query for custom scoring.
592
"""
593
def __init__(self, query=None, functions=None, **kwargs):
594
"""
595
Args:
596
query (Query, optional): Base query
597
functions (list, optional): Scoring functions
598
**kwargs: Additional parameters
599
600
Parameters:
601
score_mode (str): How to combine function scores
602
boost_mode (str): How to combine with query score
603
max_boost (float): Maximum boost value
604
min_score (float): Minimum score threshold
605
"""
606
607
class Boosting:
608
"""
609
Boosting query for positive and negative boosting.
610
"""
611
def __init__(self, positive=None, negative=None, negative_boost=None, **kwargs):
612
"""
613
Args:
614
positive (Query): Positive query
615
negative (Query): Negative query
616
negative_boost (float): Negative boost factor
617
**kwargs: Additional parameters
618
"""
619
620
class ConstantScore:
621
"""
622
Constant score query that wraps a filter and returns constant score.
623
"""
624
def __init__(self, filter=None, boost=1.0, **kwargs):
625
"""
626
Args:
627
filter (Query): Filter query to wrap
628
boost (float): Constant score to return
629
**kwargs: Additional parameters
630
"""
631
632
class Nested:
633
"""
634
Nested query for nested objects.
635
"""
636
def __init__(self, path=None, query=None, **kwargs):
637
"""
638
Args:
639
path (str): Path to nested object
640
query (Query): Query to run on nested documents
641
**kwargs: Additional parameters
642
643
Parameters:
644
score_mode (str): How to score nested hits ('avg', 'max', 'min', 'sum', 'none')
645
ignore_unmapped (bool): Ignore unmapped fields
646
inner_hits (dict): Inner hits configuration
647
"""
648
649
class HasChild:
650
"""
651
Parent-child has child query.
652
"""
653
def __init__(self, type=None, query=None, **kwargs):
654
"""
655
Args:
656
type (str): Child document type
657
query (Query): Query to run on child documents
658
**kwargs: Additional parameters
659
660
Parameters:
661
score_mode (str): How to score parent docs ('min', 'max', 'sum', 'avg', 'none')
662
min_children (int): Minimum number of matching children
663
max_children (int): Maximum number of matching children
664
ignore_unmapped (bool): Ignore unmapped types
665
inner_hits (dict): Inner hits configuration
666
"""
667
668
class HasParent:
669
"""
670
Parent-child has parent query.
671
"""
672
def __init__(self, parent_type=None, query=None, **kwargs):
673
"""
674
Args:
675
parent_type (str): Parent document type
676
query (Query): Query to run on parent documents
677
**kwargs: Additional parameters
678
679
Parameters:
680
score (bool): Include parent score in child documents
681
ignore_unmapped (bool): Ignore unmapped types
682
inner_hits (dict): Inner hits configuration
683
"""
684
685
class ParentId:
686
"""
687
Parent-child parent ID query.
688
"""
689
def __init__(self, type=None, id=None, **kwargs):
690
"""
691
Args:
692
type (str): Child document type
693
id (str): Parent document ID
694
**kwargs: Additional parameters
695
696
Parameters:
697
ignore_unmapped (bool): Ignore unmapped types
698
"""
699
```
700
701
### Search Response Handling
702
703
```python { .api }
704
class Response:
705
"""
706
Search response wrapper.
707
"""
708
hits: list # List of Hit objects
709
aggregations: dict # Aggregation results
710
suggest: dict # Suggestion results
711
712
def __len__(self):
713
"""Return number of hits."""
714
715
def __iter__(self):
716
"""Iterate over hits."""
717
718
def __getitem__(self, key):
719
"""Get hit by index."""
720
721
class Hit:
722
"""
723
Individual search result wrapper.
724
"""
725
meta: Meta # Hit metadata (score, id, index, etc.)
726
727
def to_dict(self):
728
"""Convert hit to dictionary."""
729
```
730
731
## Usage Examples
732
733
### Basic Search Operations
734
735
```python
736
from elasticsearch_dsl import Search, Q, connections
737
738
# Configure connection
739
connections.create_connection(hosts=['localhost:9200'])
740
741
# Simple search
742
search = Search(index='blog')
743
search = search.query('match', title='python')
744
response = search.execute()
745
746
for hit in response:
747
print(f"Title: {hit.title}, Score: {hit.meta.score}")
748
749
# Complex boolean query
750
search = Search(index='blog')
751
search = search.query(
752
Q('bool',
753
must=[
754
Q('match', title='python'),
755
Q('range', published_date={'gte': '2023-01-01'})
756
],
757
should=[
758
Q('match', tags='tutorial'),
759
Q('match', tags='beginner')
760
],
761
minimum_should_match=1
762
)
763
)
764
765
response = search.execute()
766
print(f"Found {response.hits.total.value} articles")
767
```
768
769
### Filtering and Sorting
770
771
```python
772
# Add filters and sorting
773
search = Search(index='blog')
774
search = search.filter('term', status='published')
775
search = search.filter('range', published_date={'gte': '2023-01-01'})
776
search = search.exclude('term', tags='draft')
777
search = search.sort('-published_date', '_score')
778
779
# Pagination
780
search = search.from_(0).size(10)
781
782
response = search.execute()
783
```
784
785
### Advanced Query Patterns
786
787
```python
788
# Multi-field search with boosting
789
search = Search(index='blog')
790
search = search.query(
791
Q('multi_match',
792
query='python elasticsearch',
793
fields=['title^2', 'content', 'tags^1.5'],
794
type='best_fields',
795
tie_breaker=0.3
796
)
797
)
798
799
# Function score for custom relevance
800
search = Search(index='blog')
801
search = search.query(
802
Q('function_score',
803
query=Q('match', content='python'),
804
functions=[
805
{
806
'filter': Q('range', published_date={'gte': '2023-01-01'}),
807
'weight': 2
808
},
809
{
810
'field_value_factor': {
811
'field': 'view_count',
812
'factor': 0.1,
813
'modifier': 'log1p'
814
}
815
}
816
],
817
score_mode='sum',
818
boost_mode='multiply'
819
)
820
)
821
822
response = search.execute()
823
```
824
825
### Highlighting and Source Filtering
826
827
```python
828
# Add highlighting and source filtering
829
search = Search(index='blog')
830
search = search.query('match', content='python')
831
search = search.highlight(
832
'title', 'content',
833
fragment_size=150,
834
number_of_fragments=3,
835
pre_tags=['<mark>'],
836
post_tags=['</mark>']
837
)
838
search = search.source(['title', 'published_date', 'author'])
839
840
response = search.execute()
841
842
for hit in response:
843
print(f"Title: {hit.title}")
844
if hasattr(hit.meta, 'highlight'):
845
for fragment in hit.meta.highlight.content:
846
print(f" Excerpt: {fragment}")
847
```