0
# PyES Query DSL
1
2
## Overview
3
4
The PyES Query DSL provides a comprehensive, pythonic interface for constructing ElasticSearch queries. All query classes inherit from the base `Query` class and can be combined using boolean logic to create complex search expressions.
5
6
## Base Classes
7
8
### Query Base Class
9
10
```python { .api }
11
class Query:
12
"""
13
Base class for all ElasticSearch queries.
14
15
All query classes inherit from this base class and implement
16
the serialize() method to convert to ElasticSearch JSON.
17
"""
18
19
def serialize(self):
20
"""
21
Convert query to ElasticSearch JSON format.
22
23
Returns:
24
dict: ElasticSearch query JSON
25
"""
26
pass
27
```
28
29
### Search Builder
30
31
```python { .api }
32
class Search:
33
"""
34
Main search query builder for constructing complete search requests.
35
36
Provides methods to build complex search queries with filters,
37
facets, aggregations, sorting, pagination, and highlighting.
38
"""
39
40
def __init__(self, query=None):
41
"""
42
Initialize search builder.
43
44
Args:
45
query (Query, optional): Initial query object
46
"""
47
pass
48
49
def query(self, query):
50
"""
51
Set the query for search.
52
53
Args:
54
query (Query): Query object
55
56
Returns:
57
Search: Self for method chaining
58
"""
59
pass
60
61
def filter(self, filter):
62
"""
63
Add filter to search.
64
65
Args:
66
filter (Filter): Filter object
67
68
Returns:
69
Search: Self for method chaining
70
"""
71
pass
72
73
def facet(self, facet):
74
"""
75
Add facet to search.
76
77
Args:
78
facet (Facet): Facet object
79
80
Returns:
81
Search: Self for method chaining
82
"""
83
pass
84
85
def add_aggregation(self, agg):
86
"""
87
Add aggregation to search.
88
89
Args:
90
agg (Agg): Aggregation object
91
92
Returns:
93
Search: Self for method chaining
94
"""
95
pass
96
97
def highlight(self, fields, **kwargs):
98
"""
99
Add highlighting to search.
100
101
Args:
102
fields (list|dict): Fields to highlight
103
**kwargs: Highlight options (pre_tags, post_tags, etc.)
104
105
Returns:
106
Search: Self for method chaining
107
"""
108
pass
109
110
def sort(self, field, order="asc"):
111
"""
112
Add sorting to search results.
113
114
Args:
115
field (str): Field to sort by
116
order (str): Sort order ('asc' or 'desc'). Default: 'asc'
117
118
Returns:
119
Search: Self for method chaining
120
"""
121
pass
122
123
def from_value(self, start):
124
"""
125
Set starting position for results.
126
127
Args:
128
start (int): Starting position (0-based)
129
130
Returns:
131
Search: Self for method chaining
132
"""
133
pass
134
135
def size(self, size):
136
"""
137
Set number of results to return.
138
139
Args:
140
size (int): Number of results
141
142
Returns:
143
Search: Self for method chaining
144
"""
145
pass
146
147
def suggest(self, suggest):
148
"""
149
Add suggestions to search.
150
151
Args:
152
suggest (Suggest): Suggest object
153
154
Returns:
155
Search: Self for method chaining
156
"""
157
pass
158
```
159
160
## Basic Usage Examples
161
162
```python { .api }
163
from pyes import Search, TermQuery, RangeQuery, BoolQuery
164
165
# Simple search with single query
166
search = Search(TermQuery("status", "published"))
167
results = es.search(search, indices=["blog"])
168
169
# Complex search with multiple components
170
search = Search(
171
BoolQuery(
172
must=[TermQuery("category", "tutorial")],
173
filter=RangeQuery("published_date", gte="2023-01-01")
174
)
175
).sort("published_date", "desc").size(20).from_value(0)
176
177
# Add highlighting
178
search.highlight(["title", "content"],
179
pre_tags=["<mark>"],
180
post_tags=["</mark>"])
181
182
results = es.search(search, indices=["blog"])
183
```
184
185
## Core Query Types
186
187
### Match All Query
188
189
```python { .api }
190
class MatchAllQuery(Query):
191
"""
192
Query that matches all documents.
193
194
Useful as base query or for filtering-only searches.
195
"""
196
197
def __init__(self, boost=None):
198
"""
199
Initialize MatchAllQuery.
200
201
Args:
202
boost (float, optional): Query boost value
203
"""
204
pass
205
206
# Match all documents
207
from pyes import MatchAllQuery
208
209
query = Search(MatchAllQuery())
210
results = es.search(query, indices=["blog"])
211
212
# Match all with boost
213
boosted_query = Search(MatchAllQuery(boost=2.0))
214
```
215
216
### Term Query
217
218
```python { .api }
219
class TermQuery(Query):
220
"""
221
Query for exact term matching (not analyzed).
222
223
Use for keyword fields, IDs, and exact matches.
224
"""
225
226
def __init__(self, field, value, boost=None):
227
"""
228
Initialize TermQuery.
229
230
Args:
231
field (str): Field name
232
value (str|int|float|bool): Exact value to match
233
boost (float, optional): Query boost value
234
"""
235
pass
236
237
# Exact term matching
238
from pyes import TermQuery
239
240
# Match exact status
241
status_query = Search(TermQuery("status", "published"))
242
243
# Match numeric value
244
view_query = Search(TermQuery("view_count", 1000))
245
246
# Match boolean value
247
featured_query = Search(TermQuery("featured", True))
248
249
# With boost
250
boosted_query = Search(TermQuery("priority", "high", boost=2.0))
251
```
252
253
### Terms Query
254
255
```python { .api }
256
class TermsQuery(Query):
257
"""
258
Query for matching any of multiple exact terms.
259
260
Equivalent to multiple TermQuery with OR logic.
261
"""
262
263
def __init__(self, field, values, minimum_match=None, boost=None):
264
"""
265
Initialize TermsQuery.
266
267
Args:
268
field (str): Field name
269
values (list): List of exact values to match
270
minimum_match (int, optional): Minimum number of terms that must match
271
boost (float, optional): Query boost value
272
"""
273
pass
274
275
# Match multiple categories
276
from pyes import TermsQuery
277
278
categories_query = Search(TermsQuery("category", ["tutorial", "guide", "reference"]))
279
280
# Match multiple tags with minimum match
281
tags_query = Search(TermsQuery("tags", ["python", "elasticsearch", "search"],
282
minimum_match=2))
283
284
# Match multiple IDs
285
ids_query = Search(TermsQuery("_id", ["doc1", "doc2", "doc3"]))
286
```
287
288
### Range Query
289
290
```python { .api }
291
class RangeQuery(Query):
292
"""
293
Query for range-based matching (numeric, date, or string ranges).
294
"""
295
296
def __init__(self, field, from_value=None, to_value=None,
297
include_lower=True, include_upper=True,
298
boost=None, **kwargs):
299
"""
300
Initialize RangeQuery.
301
302
Args:
303
field (str): Field name
304
from_value: Lower bound value (use gte/gt kwargs instead)
305
to_value: Upper bound value (use lte/lt kwargs instead)
306
include_lower (bool): Include lower bound. Default: True
307
include_upper (bool): Include upper bound. Default: True
308
boost (float, optional): Query boost value
309
**kwargs: Range parameters (gte, gt, lte, lt)
310
"""
311
pass
312
313
# Date range queries
314
from pyes import RangeQuery
315
316
# Published this year
317
this_year_query = Search(RangeQuery("published_date", gte="2023-01-01"))
318
319
# Date range (between dates)
320
date_range_query = Search(RangeQuery("published_date",
321
gte="2023-01-01",
322
lt="2024-01-01"))
323
324
# Numeric range
325
view_range_query = Search(RangeQuery("view_count", gte=100, lte=1000))
326
327
# String range (alphabetical)
328
title_range_query = Search(RangeQuery("title.keyword", gte="A", lt="M"))
329
```
330
331
## Boolean Query
332
333
### Complex Query Logic
334
335
```python { .api }
336
class BoolQuery(Query):
337
"""
338
Boolean combination of multiple queries with must/should/must_not/filter clauses.
339
340
Provides full boolean logic for complex search requirements.
341
"""
342
343
def __init__(self, must=None, should=None, must_not=None, filter=None,
344
minimum_should_match=None, boost=None, disable_coord=None):
345
"""
346
Initialize BoolQuery.
347
348
Args:
349
must (Query|list): Queries that must match (AND logic, affects scoring)
350
should (Query|list): Queries that should match (OR logic, affects scoring)
351
must_not (Query|list): Queries that must not match (NOT logic)
352
filter (Query|list): Queries for filtering (no scoring impact)
353
minimum_should_match (int|str): Minimum should queries that must match
354
boost (float, optional): Query boost value
355
disable_coord (bool): Disable coordination factor
356
"""
357
pass
358
359
# Complex boolean search
360
from pyes import BoolQuery, TermQuery, RangeQuery, MatchQuery
361
362
# Blog posts that must be published, should contain python or elasticsearch,
363
# must not be drafts, and filtered by date
364
complex_query = Search(
365
BoolQuery(
366
must=[
367
TermQuery("status", "published"),
368
MatchQuery("content", "programming")
369
],
370
should=[
371
TermQuery("tags", "python"),
372
TermQuery("tags", "elasticsearch"),
373
TermQuery("tags", "tutorial")
374
],
375
must_not=[
376
TermQuery("category", "draft"),
377
TermQuery("author", "spam_user")
378
],
379
filter=[
380
RangeQuery("published_date", gte="2023-01-01"),
381
RangeQuery("view_count", gte=10)
382
],
383
minimum_should_match=1 # At least one should clause must match
384
)
385
)
386
387
results = es.search(complex_query, indices=["blog"])
388
```
389
390
## Text Search Queries
391
392
### Match Query
393
394
```python { .api }
395
class MatchQuery(Query):
396
"""
397
Full-text search query with analysis and relevance scoring.
398
399
Analyzes input text and matches against analyzed field content.
400
"""
401
402
def __init__(self, field, query, boost=None, analyzer=None,
403
fuzziness=None, prefix_length=None, max_expansions=None,
404
operator="OR", minimum_should_match=None, zero_terms_query="NONE"):
405
"""
406
Initialize MatchQuery.
407
408
Args:
409
field (str): Field name to search
410
query (str): Query text to match
411
boost (float, optional): Query boost value
412
analyzer (str, optional): Analyzer to use for query text
413
fuzziness (str|int, optional): Fuzziness for matching (AUTO, 0, 1, 2)
414
prefix_length (int, optional): Number of initial characters not fuzzified
415
max_expansions (int, optional): Maximum term expansions for fuzzy matching
416
operator (str): Boolean operator for terms (OR, AND). Default: "OR"
417
minimum_should_match (str|int): Minimum terms that should match
418
zero_terms_query (str): Behavior when all terms are stop words
419
"""
420
pass
421
422
# Full-text search
423
from pyes import MatchQuery
424
425
# Basic text search
426
search_query = Search(MatchQuery("content", "python elasticsearch tutorial"))
427
428
# Match with specific operator (all terms must match)
429
strict_query = Search(MatchQuery("title", "python programming", operator="AND"))
430
431
# Fuzzy matching for typos
432
fuzzy_query = Search(MatchQuery("content", "elsticsearch", fuzziness="AUTO"))
433
434
# With minimum should match
435
flexible_query = Search(MatchQuery("content", "python tutorial guide advanced",
436
minimum_should_match="75%"))
437
```
438
439
### Multi Match Query
440
441
```python { .api }
442
class MultiMatchQuery(Query):
443
"""
444
Match query across multiple fields with various matching strategies.
445
"""
446
447
def __init__(self, query, fields, boost=None, type="best_fields",
448
analyzer=None, fuzziness=None, prefix_length=None,
449
max_expansions=None, operator="OR", minimum_should_match=None):
450
"""
451
Initialize MultiMatchQuery.
452
453
Args:
454
query (str): Query text
455
fields (list): List of fields to search across
456
boost (float, optional): Query boost value
457
type (str): Multi-match type (best_fields, most_fields, cross_fields,
458
phrase, phrase_prefix). Default: "best_fields"
459
analyzer (str, optional): Analyzer for query text
460
fuzziness (str|int, optional): Fuzziness level
461
prefix_length (int, optional): Prefix length for fuzzy matching
462
max_expansions (int, optional): Max expansions for fuzzy
463
operator (str): Boolean operator (OR, AND). Default: "OR"
464
minimum_should_match (str|int): Minimum should match
465
"""
466
pass
467
468
# Multi-field search
469
from pyes import MultiMatchQuery
470
471
# Search across title and content
472
multi_query = Search(MultiMatchQuery("python programming",
473
["title^2", "content", "tags"]))
474
475
# Cross-fields search (terms can be in different fields)
476
cross_query = Search(MultiMatchQuery("john smith",
477
["first_name", "last_name"],
478
type="cross_fields"))
479
480
# Phrase matching across fields
481
phrase_query = Search(MultiMatchQuery("machine learning",
482
["title", "content", "abstract"],
483
type="phrase"))
484
```
485
486
### Query String Query
487
488
```python { .api }
489
class QueryStringQuery(Query):
490
"""
491
Lucene query string syntax parser for advanced search expressions.
492
493
Supports field-specific search, boolean operators, wildcards,
494
ranges, and phrase queries in a single string.
495
"""
496
497
def __init__(self, query, default_field=None, fields=None,
498
default_operator="OR", analyzer=None, allow_leading_wildcard=True,
499
lowercase_expanded_terms=True, enable_position_increments=True,
500
fuzzy_max_expansions=50, fuzziness=None, fuzzy_prefix_length=0,
501
phrase_slop=0, boost=None, analyze_wildcard=False,
502
auto_generate_phrase_queries=False, minimum_should_match=None):
503
"""
504
Initialize QueryStringQuery.
505
506
Args:
507
query (str): Lucene query string
508
default_field (str, optional): Default field when none specified
509
fields (list, optional): Fields to search when none specified in query
510
default_operator (str): Default operator (OR, AND). Default: "OR"
511
analyzer (str, optional): Analyzer for query
512
allow_leading_wildcard (bool): Allow wildcards at start. Default: True
513
lowercase_expanded_terms (bool): Lowercase wildcard/fuzzy terms. Default: True
514
enable_position_increments (bool): Enable position increments. Default: True
515
fuzzy_max_expansions (int): Max fuzzy expansions. Default: 50
516
fuzziness (str|int, optional): Fuzzy matching level
517
fuzzy_prefix_length (int): Fuzzy prefix length. Default: 0
518
phrase_slop (int): Phrase slop for proximity. Default: 0
519
boost (float, optional): Query boost
520
analyze_wildcard (bool): Analyze wildcard queries. Default: False
521
auto_generate_phrase_queries (bool): Auto phrase detection. Default: False
522
minimum_should_match (str|int): Minimum should match
523
"""
524
pass
525
526
# Lucene query string syntax
527
from pyes import QueryStringQuery
528
529
# Complex query string with field-specific search
530
lucene_query = Search(QueryStringQuery(
531
'title:"python tutorial" AND (tags:elasticsearch OR tags:search) AND published_date:[2023-01-01 TO *]'
532
))
533
534
# Search with wildcards and fuzzy matching
535
wildcard_query = Search(QueryStringQuery(
536
'title:python* AND content:search~2', # Wildcard and fuzzy
537
default_operator="AND"
538
))
539
540
# Multi-field query string
541
multi_field_query = Search(QueryStringQuery(
542
'programming tutorial',
543
fields=["title^2", "content", "tags"],
544
minimum_should_match="50%"
545
))
546
```
547
548
## Fuzzy and Similarity Queries
549
550
### Fuzzy Query
551
552
```python { .api }
553
class FuzzyQuery(Query):
554
"""
555
Fuzzy term matching for handling typos and misspellings.
556
"""
557
558
def __init__(self, field, value, boost=None, fuzziness="AUTO",
559
prefix_length=0, max_expansions=50):
560
"""
561
Initialize FuzzyQuery.
562
563
Args:
564
field (str): Field name
565
value (str): Term to match fuzzily
566
boost (float, optional): Query boost
567
fuzziness (str|int): Fuzziness level (AUTO, 0, 1, 2). Default: "AUTO"
568
prefix_length (int): Characters at start that must match exactly. Default: 0
569
max_expansions (int): Maximum term expansions. Default: 50
570
"""
571
pass
572
573
# Fuzzy term matching
574
from pyes import FuzzyQuery
575
576
# Handle typos in search
577
fuzzy_search = Search(FuzzyQuery("title", "elastcsearch", fuzziness=2))
578
579
# Auto-fuzziness based on term length
580
auto_fuzzy = Search(FuzzyQuery("content", "progamming", fuzziness="AUTO"))
581
```
582
583
### More Like This Query
584
585
```python { .api }
586
class MoreLikeThisQuery(Query):
587
"""
588
Find documents similar to provided text or documents.
589
"""
590
591
def __init__(self, fields, like_text=None, docs=None, ids=None,
592
min_term_freq=2, max_query_terms=25, stop_words=None,
593
min_doc_freq=5, max_doc_freq=None, min_word_len=0,
594
max_word_len=0, analyzer=None, boost=None, include=True):
595
"""
596
Initialize MoreLikeThisQuery.
597
598
Args:
599
fields (list): Fields to use for similarity
600
like_text (str, optional): Text to find similar documents for
601
docs (list, optional): Documents to find similar documents for
602
ids (list, optional): Document IDs to find similar documents for
603
min_term_freq (int): Minimum term frequency. Default: 2
604
max_query_terms (int): Maximum query terms. Default: 25
605
stop_words (list, optional): Stop words to ignore
606
min_doc_freq (int): Minimum document frequency. Default: 5
607
max_doc_freq (int, optional): Maximum document frequency
608
min_word_len (int): Minimum word length. Default: 0
609
max_word_len (int): Maximum word length. Default: 0
610
analyzer (str, optional): Analyzer to use
611
boost (float, optional): Query boost
612
include (bool): Include the original document. Default: True
613
"""
614
pass
615
616
# Find similar documents
617
from pyes import MoreLikeThisQuery
618
619
# Similar to provided text
620
similar_text = Search(MoreLikeThisQuery(
621
fields=["title", "content"],
622
like_text="python elasticsearch tutorial guide",
623
min_term_freq=1,
624
max_query_terms=12
625
))
626
627
# Similar to specific documents
628
similar_docs = Search(MoreLikeThisQuery(
629
fields=["content"],
630
ids=["doc1", "doc2"],
631
min_doc_freq=2,
632
include=False # Exclude original documents
633
))
634
```
635
636
## Specialized Queries
637
638
### Prefix Query
639
640
```python { .api }
641
class PrefixQuery(Query):
642
"""
643
Match documents with terms that start with specified prefix.
644
"""
645
646
def __init__(self, field, prefix, boost=None):
647
"""
648
Initialize PrefixQuery.
649
650
Args:
651
field (str): Field name
652
prefix (str): Prefix to match
653
boost (float, optional): Query boost
654
"""
655
pass
656
657
# Prefix matching for autocomplete
658
from pyes import PrefixQuery
659
660
# Find titles starting with "python"
661
prefix_query = Search(PrefixQuery("title.keyword", "python"))
662
663
# Tag autocomplete
664
tag_autocomplete = Search(PrefixQuery("tags", "elastic"))
665
```
666
667
### Wildcard Query
668
669
```python { .api }
670
class WildcardQuery(Query):
671
"""
672
Wildcard pattern matching (* and ? wildcards).
673
"""
674
675
def __init__(self, field, value, boost=None):
676
"""
677
Initialize WildcardQuery.
678
679
Args:
680
field (str): Field name
681
value (str): Wildcard pattern (* = any chars, ? = single char)
682
boost (float, optional): Query boost
683
"""
684
pass
685
686
# Wildcard pattern matching
687
from pyes import WildcardQuery
688
689
# Match any .py files
690
file_query = Search(WildcardQuery("filename", "*.py"))
691
692
# Phone number patterns
693
phone_query = Search(WildcardQuery("phone", "555-????"))
694
```
695
696
### Regular Expression Query
697
698
```python { .api }
699
class RegexTermQuery(Query):
700
"""
701
Regular expression pattern matching.
702
"""
703
704
def __init__(self, field, value, boost=None, flags=None):
705
"""
706
Initialize RegexTermQuery.
707
708
Args:
709
field (str): Field name
710
value (str): Regular expression pattern
711
boost (float, optional): Query boost
712
flags (str, optional): Regex flags
713
"""
714
pass
715
716
# Regular expression matching
717
from pyes import RegexTermQuery
718
719
# Email pattern matching
720
email_query = Search(RegexTermQuery("email", r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"))
721
722
# Version number patterns
723
version_query = Search(RegexTermQuery("version", r"[0-9]+\.[0-9]+\.[0-9]+"))
724
```
725
726
### IDs Query
727
728
```python { .api }
729
class IdsQuery(Query):
730
"""
731
Match documents by their IDs.
732
"""
733
734
def __init__(self, values, types=None, boost=None):
735
"""
736
Initialize IdsQuery.
737
738
Args:
739
values (list): List of document IDs
740
types (list, optional): Document types to search in
741
boost (float, optional): Query boost
742
"""
743
pass
744
745
# Match specific document IDs
746
from pyes import IdsQuery
747
748
# Get specific documents
749
ids_query = Search(IdsQuery(["doc1", "doc2", "doc3"]))
750
751
# IDs within specific types
752
typed_ids_query = Search(IdsQuery(["post1", "post2"], types=["blog_post"]))
753
```
754
755
## Scoring and Boosting Queries
756
757
### Constant Score Query
758
759
```python { .api }
760
class ConstantScoreQuery(Query):
761
"""
762
Wrap query or filter with constant score (no relevance calculation).
763
"""
764
765
def __init__(self, query=None, filter=None, boost=1.0):
766
"""
767
Initialize ConstantScoreQuery.
768
769
Args:
770
query (Query, optional): Query to wrap
771
filter (Filter, optional): Filter to wrap
772
boost (float): Constant score value. Default: 1.0
773
"""
774
pass
775
776
# Constant scoring for filters
777
from pyes import ConstantScoreQuery, TermFilter
778
779
# All matching documents get same score
780
constant_query = Search(ConstantScoreQuery(
781
filter=TermFilter("category", "tutorial"),
782
boost=1.5
783
))
784
```
785
786
### Function Score Query
787
788
```python { .api }
789
class FunctionScoreQuery(Query):
790
"""
791
Modify document scores using functions (field values, scripts, etc.).
792
"""
793
794
def __init__(self, query, functions=None, score_mode="multiply",
795
boost_mode="multiply", max_boost=None, boost=None):
796
"""
797
Initialize FunctionScoreQuery.
798
799
Args:
800
query (Query): Base query
801
functions (list): List of scoring functions
802
score_mode (str): How to combine function scores. Default: "multiply"
803
boost_mode (str): How to combine with query score. Default: "multiply"
804
max_boost (float, optional): Maximum boost value
805
boost (float, optional): Query boost
806
"""
807
pass
808
809
# Custom scoring based on popularity
810
from pyes import FunctionScoreQuery, MatchQuery
811
812
# Boost popular documents
813
popularity_query = Search(FunctionScoreQuery(
814
query=MatchQuery("content", "python tutorial"),
815
functions=[
816
{
817
"field_value_factor": {
818
"field": "popularity_score",
819
"factor": 1.5,
820
"modifier": "log1p"
821
}
822
},
823
{
824
"gauss": {
825
"published_date": {
826
"origin": "2023-12-01",
827
"scale": "30d",
828
"decay": 0.5
829
}
830
}
831
}
832
],
833
score_mode="sum",
834
boost_mode="multiply"
835
))
836
```
837
838
## Hierarchical Queries
839
840
### Parent-Child Queries
841
842
```python { .api }
843
class HasChildQuery(Query):
844
"""
845
Match parent documents that have child documents matching the query.
846
"""
847
848
def __init__(self, type, query, score_type="none", min_children=None,
849
max_children=None, boost=None):
850
"""
851
Initialize HasChildQuery.
852
853
Args:
854
type (str): Child document type
855
query (Query): Query for child documents
856
score_type (str): How child scores affect parent (none, max, sum, avg)
857
min_children (int, optional): Minimum matching children required
858
max_children (int, optional): Maximum matching children allowed
859
boost (float, optional): Query boost
860
"""
861
pass
862
863
class HasParentQuery(Query):
864
"""
865
Match child documents that have parent documents matching the query.
866
"""
867
868
def __init__(self, parent_type, query, score_type="none", boost=None):
869
"""
870
Initialize HasParentQuery.
871
872
Args:
873
parent_type (str): Parent document type
874
query (Query): Query for parent documents
875
score_type (str): How parent scores affect child (none, score)
876
boost (float, optional): Query boost
877
"""
878
pass
879
880
# Parent-child relationships
881
from pyes import HasChildQuery, HasParentQuery, TermQuery
882
883
# Find blog posts with approved comments
884
posts_with_comments = Search(HasChildQuery(
885
type="comment",
886
query=TermQuery("status", "approved"),
887
min_children=1,
888
score_type="max" # Use highest child score
889
))
890
891
# Find comments on featured posts
892
comments_on_featured = Search(HasParentQuery(
893
parent_type="post",
894
query=TermQuery("featured", True)
895
))
896
```
897
898
### Nested Query
899
900
```python { .api }
901
class NestedQuery(Query):
902
"""
903
Query nested objects within documents.
904
"""
905
906
def __init__(self, path, query, score_mode="avg", boost=None):
907
"""
908
Initialize NestedQuery.
909
910
Args:
911
path (str): Path to nested object
912
query (Query): Query for nested objects
913
score_mode (str): Score mode (avg, max, sum, none). Default: "avg"
914
boost (float, optional): Query boost
915
"""
916
pass
917
918
# Nested object queries
919
from pyes import NestedQuery, BoolQuery, RangeQuery
920
921
# Query nested product variants
922
nested_query = Search(NestedQuery(
923
path="variants",
924
query=BoolQuery(
925
must=[
926
TermQuery("variants.color", "red"),
927
RangeQuery("variants.price", lt=100)
928
]
929
),
930
score_mode="max"
931
))
932
```
933
934
## Span Queries
935
936
### Span Term Query
937
938
```python { .api }
939
class SpanTermQuery(Query):
940
"""
941
Span query for exact term matching with position information.
942
"""
943
944
def __init__(self, field, value, boost=None):
945
"""
946
Initialize SpanTermQuery.
947
948
Args:
949
field (str): Field name
950
value (str): Term to match
951
boost (float, optional): Query boost
952
"""
953
pass
954
955
class SpanNearQuery(Query):
956
"""
957
Match spans that are near each other (proximity search).
958
"""
959
960
def __init__(self, clauses, slop, in_order=True, boost=None):
961
"""
962
Initialize SpanNearQuery.
963
964
Args:
965
clauses (list): List of span queries
966
slop (int): Maximum distance between spans
967
in_order (bool): Whether spans must be in order. Default: True
968
boost (float, optional): Query boost
969
"""
970
pass
971
972
# Proximity search with span queries
973
from pyes import SpanNearQuery, SpanTermQuery
974
975
# Find "python" near "elasticsearch" within 5 positions
976
proximity_query = Search(SpanNearQuery(
977
clauses=[
978
SpanTermQuery("content", "python"),
979
SpanTermQuery("content", "elasticsearch")
980
],
981
slop=5,
982
in_order=False
983
))
984
```
985
986
## Suggestion Queries
987
988
### Suggest Object
989
990
```python { .api }
991
class Suggest:
992
"""
993
Container for multiple suggestion requests.
994
"""
995
996
def __init__(self):
997
pass
998
999
def add(self, text, name, field, type='term', size=None, params=None):
1000
"""
1001
Add suggestion request.
1002
1003
Args:
1004
text (str): Text to get suggestions for
1005
name (str): Suggestion name
1006
field (str): Field to suggest from
1007
type (str): Suggestion type (term, phrase, completion). Default: 'term'
1008
size (int, optional): Number of suggestions
1009
params (dict, optional): Additional parameters
1010
"""
1011
pass
1012
1013
def add_term(self, text, name, field, size=None, params=None):
1014
"""Add term suggestion."""
1015
pass
1016
1017
def add_phrase(self, text, name, field, size=None, params=None):
1018
"""Add phrase suggestion."""
1019
pass
1020
1021
def add_completion(self, text, name, field, size=None, params=None):
1022
"""Add completion suggestion."""
1023
pass
1024
1025
# Multiple suggestion types
1026
from pyes import Suggest
1027
1028
suggest = Suggest()
1029
suggest.add_term("pythno", "term_suggest", "title") # Typo correction
1030
suggest.add_phrase("elatic search", "phrase_suggest", "content") # Phrase correction
1031
suggest.add_completion("pyth", "completion_suggest", "tags.suggest") # Autocomplete
1032
1033
suggestions = es.suggest_from_object(suggest, indices=["blog"])
1034
```
1035
1036
## Advanced Query Patterns
1037
1038
### Filtered Query (Deprecated but Supported)
1039
1040
```python { .api }
1041
class FilteredQuery(Query):
1042
"""
1043
Combine query with filter (deprecated - use BoolQuery with filter instead).
1044
"""
1045
1046
def __init__(self, query, filter, boost=None):
1047
"""
1048
Initialize FilteredQuery.
1049
1050
Args:
1051
query (Query): Main query
1052
filter (Filter): Filter to apply
1053
boost (float, optional): Query boost
1054
"""
1055
pass
1056
1057
# Legacy filtered query (use BoolQuery instead)
1058
from pyes import FilteredQuery, MatchQuery, TermFilter
1059
1060
# Deprecated approach
1061
filtered = Search(FilteredQuery(
1062
query=MatchQuery("content", "python"),
1063
filter=TermFilter("status", "published")
1064
))
1065
1066
# Recommended approach using BoolQuery
1067
recommended = Search(BoolQuery(
1068
must=[MatchQuery("content", "python")],
1069
filter=[TermFilter("status", "published")]
1070
))
1071
```
1072
1073
### Query Composition Patterns
1074
1075
```python { .api }
1076
# Complex query building patterns
1077
from pyes import Search, BoolQuery, TermQuery, RangeQuery, MatchQuery, FunctionScoreQuery
1078
1079
def build_blog_search_query(text=None, categories=None, date_range=None,
1080
author=None, min_views=None, boost_featured=False):
1081
"""
1082
Build complex blog search query with multiple optional parameters.
1083
"""
1084
1085
# Start with base query
1086
must_clauses = []
1087
filter_clauses = []
1088
should_clauses = []
1089
1090
# Add text search if provided
1091
if text:
1092
must_clauses.append(MatchQuery("content", text))
1093
1094
# Filter by categories
1095
if categories:
1096
if isinstance(categories, list):
1097
filter_clauses.append(TermsQuery("category", categories))
1098
else:
1099
filter_clauses.append(TermQuery("category", categories))
1100
1101
# Date range filter
1102
if date_range:
1103
filter_clauses.append(RangeQuery("published_date", **date_range))
1104
1105
# Author filter
1106
if author:
1107
filter_clauses.append(TermQuery("author", author))
1108
1109
# Minimum views filter
1110
if min_views:
1111
filter_clauses.append(RangeQuery("view_count", gte=min_views))
1112
1113
# Build boolean query
1114
bool_query = BoolQuery()
1115
if must_clauses:
1116
bool_query.must = must_clauses
1117
if should_clauses:
1118
bool_query.should = should_clauses
1119
if filter_clauses:
1120
bool_query.filter = filter_clauses
1121
1122
# Add boost for featured posts
1123
if boost_featured:
1124
bool_query.should = bool_query.should or []
1125
bool_query.should.append(TermQuery("featured", True, boost=2.0))
1126
1127
return Search(bool_query)
1128
1129
# Usage examples
1130
search1 = build_blog_search_query(
1131
text="python tutorial",
1132
categories=["programming", "tutorial"],
1133
date_range={"gte": "2023-01-01"},
1134
min_views=100,
1135
boost_featured=True
1136
)
1137
1138
search2 = build_blog_search_query(
1139
author="john_doe",
1140
date_range={"gte": "2023-06-01", "lte": "2023-12-31"}
1141
)
1142
```
1143
1144
The PyES Query DSL provides comprehensive querying capabilities with full ElasticSearch feature support, allowing construction of simple to highly complex search expressions with proper scoring, filtering, and boolean logic.