0
# Search Operations
1
2
Comprehensive search functionality for querying documents in Elasticsearch. Provides full-text search capabilities, query execution, aggregations, scroll operations, and advanced search features.
3
4
## Capabilities
5
6
### Basic Search
7
8
Execute search queries with support for complex queries, filtering, sorting, and result pagination.
9
10
```python { .api }
11
def search(index: str = None, doc_type: str = None, body: dict = None, **params) -> dict:
12
"""
13
Execute a search query against one or more indices.
14
15
Parameters:
16
- index: Index name(s) to search (string or list)
17
- doc_type: Document type(s) to search
18
- body: Search query as Elasticsearch Query DSL
19
- _source: Fields to include/exclude in results
20
- _source_excludes: Fields to exclude from _source
21
- _source_includes: Fields to include in _source
22
- allow_no_indices: Whether to ignore if indices don't exist
23
- analyzer: Analyzer for query string
24
- analyze_wildcard: Analyze wildcard and prefix queries
25
- batched_reduce_size: Number of shard results to reduce at once
26
- default_operator: Default operator for query string ('AND' or 'OR')
27
- df: Default field for query string
28
- expand_wildcards: Expand wildcard expressions ('open', 'closed', 'none', 'all')
29
- from_: Starting document offset (default 0)
30
- ignore_unavailable: Ignore unavailable indices
31
- lenient: Ignore format-based query failures
32
- preference: Node preference for execution
33
- q: Lucene query string
34
- routing: Routing values
35
- scroll: Scroll timeout for pagination
36
- search_type: Search type ('query_then_fetch', 'dfs_query_then_fetch')
37
- size: Maximum number of documents to return (default 10)
38
- sort: Sort specification
39
- terminate_after: Terminate after N documents
40
- timeout: Search timeout
41
- track_scores: Track scores when sorting
42
- version: Include document versions in results
43
44
Returns:
45
dict: Search results with 'hits', 'aggregations', and metadata
46
"""
47
```
48
49
### Document Counting
50
51
Count documents matching a query efficiently without retrieving full results.
52
53
```python { .api }
54
def count(index: str = None, doc_type: str = None, body: dict = None, **params) -> dict:
55
"""
56
Count documents matching a query.
57
58
Parameters:
59
- index: Index name(s) to search
60
- doc_type: Document type(s)
61
- body: Count query (optional, counts all if omitted)
62
- allow_no_indices: Handle missing indices
63
- analyzer: Query analyzer
64
- analyze_wildcard: Analyze wildcards
65
- default_operator: Default query operator
66
- df: Default field
67
- expand_wildcards: Wildcard expansion
68
- ignore_unavailable: Ignore unavailable indices
69
- lenient: Ignore query failures
70
- min_score: Minimum score threshold
71
- preference: Node preference
72
- q: Query string
73
- routing: Routing values
74
- terminate_after: Early termination
75
76
Returns:
77
dict: Count result with 'count' and '_shards' information
78
"""
79
```
80
81
### Scroll Search
82
83
Efficiently iterate through large result sets using scroll context.
84
85
```python { .api }
86
def scroll(scroll_id: str = None, body: dict = None, **params) -> dict:
87
"""
88
Continue a scroll search to retrieve next batch of results.
89
90
Parameters:
91
- scroll_id: Scroll context identifier from previous search/scroll
92
- body: Request body with scroll_id (alternative to parameter)
93
- scroll: Time to keep scroll context alive (e.g., '5m')
94
- rest_total_hits_as_int: Return total hits as integer
95
96
Returns:
97
dict: Next batch of search results with new scroll_id
98
"""
99
100
def clear_scroll(scroll_id: str = None, body: dict = None, **params) -> dict:
101
"""
102
Clear scroll context to free resources.
103
104
Parameters:
105
- scroll_id: Scroll context identifier(s) to clear
106
- body: Request body with scroll_id list
107
108
Returns:
109
dict: Success confirmation
110
"""
111
```
112
113
### Multi-Search
114
115
Execute multiple search queries in a single request for improved performance.
116
117
```python { .api }
118
def msearch(body: list, index: str = None, doc_type: str = None, **params) -> dict:
119
"""
120
Execute multiple search queries in a single request.
121
122
Parameters:
123
- body: List of search requests (header/body pairs)
124
- index: Default index for requests without explicit index
125
- doc_type: Default document type
126
- max_concurrent_searches: Maximum concurrent searches
127
- rest_total_hits_as_int: Return total hits as integer
128
- typed_keys: Add type prefix to aggregation names
129
130
Body format:
131
[
132
{"index": "my_index", "type": "_doc"}, # Header
133
{"query": {"match_all": {}}}, # Body
134
{"index": "other_index"}, # Header
135
{"query": {"term": {"status": "published"}}} # Body
136
]
137
138
Returns:
139
dict: Array of search responses corresponding to each request
140
"""
141
142
def msearch_template(body: list, index: str = None, doc_type: str = None, **params) -> dict:
143
"""
144
Execute multiple search template queries.
145
146
Parameters: Same as msearch
147
Body: Search template specifications instead of direct queries
148
149
Returns:
150
dict: Array of search template responses
151
"""
152
```
153
154
### Search Templates
155
156
Use predefined search templates for reusable queries with parameters.
157
158
```python { .api }
159
def search_template(index: str = None, doc_type: str = None, body: dict = None, **params) -> dict:
160
"""
161
Execute a search using a search template.
162
163
Parameters:
164
- index: Index name(s) to search
165
- doc_type: Document type(s)
166
- body: Template specification with id/source and params
167
- allow_no_indices: Handle missing indices
168
- expand_wildcards: Wildcard expansion
169
- ignore_unavailable: Ignore unavailable indices
170
- preference: Node preference
171
- routing: Routing values
172
- scroll: Scroll timeout
173
- search_type: Search type
174
175
Body structure:
176
{
177
"id": "my_template", # Template ID
178
"params": { # Template parameters
179
"query_string": "search term",
180
"from": 0,
181
"size": 10
182
}
183
}
184
185
Or with inline template:
186
{
187
"source": { # Inline template
188
"query": {
189
"match": {
190
"title": "{{query_string}}"
191
}
192
},
193
"from": "{{from}}",
194
"size": "{{size}}"
195
},
196
"params": {"query_string": "test", "from": 0, "size": 20}
197
}
198
199
Returns:
200
dict: Search results from template execution
201
"""
202
203
def render_search_template(id: str = None, body: dict = None, **params) -> dict:
204
"""
205
Render a search template to see the generated query.
206
207
Parameters:
208
- id: Template ID to render
209
- body: Template specification (if not using stored template)
210
211
Returns:
212
dict: Rendered template showing the final query
213
"""
214
```
215
216
### Query Explanation
217
218
Understand how documents are scored and why they match queries.
219
220
```python { .api }
221
def explain(index: str, doc_type: str, id: str, body: dict = None, **params) -> dict:
222
"""
223
Explain why a document matches or doesn't match a query.
224
225
Parameters:
226
- index: Index name
227
- doc_type: Document type
228
- id: Document identifier
229
- body: Query to explain
230
- _source: Include document source in response
231
- _source_excludes: Source fields to exclude
232
- _source_includes: Source fields to include
233
- analyzer: Query analyzer
234
- analyze_wildcard: Analyze wildcards
235
- default_operator: Default query operator
236
- df: Default field
237
- lenient: Ignore query failures
238
- preference: Node preference
239
- q: Query string
240
- routing: Routing value
241
242
Returns:
243
dict: Explanation of scoring and matching details
244
"""
245
```
246
247
### Search Suggestions
248
249
Get search suggestions and completions based on indexed data.
250
251
```python { .api }
252
def suggest(body: dict, index: str = None, **params) -> dict:
253
"""
254
Get search suggestions using suggestion APIs.
255
256
Parameters:
257
- body: Suggestion request specification
258
- index: Index name(s) to search for suggestions
259
- allow_no_indices: Handle missing indices
260
- expand_wildcards: Wildcard expansion
261
- ignore_unavailable: Ignore unavailable indices
262
- preference: Node preference
263
- routing: Routing values
264
265
Body structure:
266
{
267
"my_suggestion": {
268
"text": "search text",
269
"term": { # Term suggester
270
"field": "title"
271
}
272
},
273
"my_phrase_suggestion": {
274
"text": "search phrase",
275
"phrase": { # Phrase suggester
276
"field": "title",
277
"size": 3
278
}
279
},
280
"my_completion": {
281
"prefix": "sea",
282
"completion": { # Completion suggester
283
"field": "suggest",
284
"size": 5
285
}
286
}
287
}
288
289
Returns:
290
dict: Suggestions organized by suggester name
291
"""
292
```
293
294
### Advanced Search Features
295
296
Additional search capabilities for specialized use cases.
297
298
```python { .api }
299
def field_caps(index: str = None, body: dict = None, **params) -> dict:
300
"""
301
Get field capabilities across indices.
302
303
Parameters:
304
- index: Index name(s) to analyze
305
- body: Field names specification
306
- fields: Field names to analyze
307
- allow_no_indices: Handle missing indices
308
- expand_wildcards: Wildcard expansion
309
- ignore_unavailable: Ignore unavailable indices
310
311
Returns:
312
dict: Field capabilities and types across indices
313
"""
314
315
def search_shards(index: str = None, doc_type: str = None, **params) -> dict:
316
"""
317
Get information about shards that a search request would be executed against.
318
319
Parameters:
320
- index: Index name(s)
321
- doc_type: Document type(s)
322
- allow_no_indices: Handle missing indices
323
- expand_wildcards: Wildcard expansion
324
- ignore_unavailable: Ignore unavailable indices
325
- local: Execute locally on current node
326
- preference: Node preference
327
- routing: Routing values
328
329
Returns:
330
dict: Shard information for the search request
331
"""
332
```
333
334
## Usage Examples
335
336
### Basic Search Queries
337
338
```python
339
from elasticsearch5 import Elasticsearch
340
341
es = Elasticsearch(['localhost:9200'])
342
343
# Simple match query
344
search_body = {
345
'query': {
346
'match': {
347
'title': 'elasticsearch python'
348
}
349
},
350
'size': 20,
351
'from': 0
352
}
353
results = es.search(index='articles', body=search_body)
354
print(f"Found {results['hits']['total']} documents")
355
356
# Boolean query with filters
357
complex_query = {
358
'query': {
359
'bool': {
360
'must': [
361
{'match': {'title': 'python'}},
362
{'range': {'created_at': {'gte': '2023-01-01'}}}
363
],
364
'filter': [
365
{'term': {'status': 'published'}}
366
],
367
'must_not': [
368
{'term': {'category': 'draft'}}
369
]
370
}
371
},
372
'sort': [
373
{'created_at': {'order': 'desc'}},
374
'_score'
375
],
376
'_source': ['title', 'author', 'created_at']
377
}
378
results = es.search(index='articles', body=complex_query)
379
```
380
381
### Aggregations
382
383
```python
384
# Search with aggregations
385
agg_query = {
386
'query': {'match_all': {}},
387
'aggs': {
388
'authors': {
389
'terms': {
390
'field': 'author.keyword',
391
'size': 10
392
}
393
},
394
'publication_dates': {
395
'date_histogram': {
396
'field': 'created_at',
397
'calendar_interval': 'month'
398
}
399
},
400
'avg_score': {
401
'avg': {
402
'field': 'score'
403
}
404
}
405
},
406
'size': 0 # Only return aggregations, no documents
407
}
408
results = es.search(index='articles', body=agg_query)
409
print("Top authors:", results['aggregations']['authors']['buckets'])
410
```
411
412
### Scroll Search for Large Results
413
414
```python
415
# Initial scroll search
416
scroll_query = {
417
'query': {'match_all': {}},
418
'size': 1000 # Documents per batch
419
}
420
response = es.search(
421
index='large_index',
422
body=scroll_query,
423
scroll='5m' # Keep scroll context for 5 minutes
424
)
425
426
# Process initial batch
427
all_docs = response['hits']['hits']
428
scroll_id = response['_scroll_id']
429
430
# Continue scrolling
431
while len(response['hits']['hits']) > 0:
432
response = es.scroll(scroll_id=scroll_id, scroll='5m')
433
all_docs.extend(response['hits']['hits'])
434
scroll_id = response['_scroll_id']
435
436
# Clear scroll context
437
es.clear_scroll(scroll_id=scroll_id)
438
print(f"Retrieved {len(all_docs)} documents total")
439
```
440
441
### Multi-Search
442
443
```python
444
# Execute multiple searches in one request
445
msearch_body = [
446
{'index': 'articles', 'type': '_doc'},
447
{'query': {'match': {'category': 'tech'}}},
448
449
{'index': 'users', 'type': '_doc'},
450
{'query': {'range': {'age': {'gte': 18}}}},
451
452
{'index': 'articles'},
453
{'query': {'match_all': {}}, 'size': 0, 'aggs': {'total': {'value_count': {'field': '_id'}}}}
454
]
455
456
responses = es.msearch(body=msearch_body)
457
for i, response in enumerate(responses['responses']):
458
if 'error' in response:
459
print(f"Query {i} failed: {response['error']}")
460
else:
461
print(f"Query {i} returned {response['hits']['total']} results")
462
```
463
464
### Search Templates
465
466
```python
467
# First, store a search template
468
template_body = {
469
'template': {
470
'query': {
471
'bool': {
472
'must': [
473
{'match': {'{{field}}': '{{query}}'}}
474
],
475
'filter': [
476
{'range': {'{{date_field}}': {'gte': '{{start_date}}'}}}
477
]
478
}
479
},
480
'size': '{{size}}',
481
'from': '{{from}}'
482
}
483
}
484
es.put_template(id='article_search', body=template_body)
485
486
# Use the template
487
template_search = {
488
'id': 'article_search',
489
'params': {
490
'field': 'title',
491
'query': 'elasticsearch',
492
'date_field': 'created_at',
493
'start_date': '2023-01-01',
494
'size': 10,
495
'from': 0
496
}
497
}
498
results = es.search_template(index='articles', body=template_search)
499
```