@@ -236,6 +236,12 @@ def negate(self):
236
236
def __hash__ (self ):
237
237
return hash (self .operator )
238
238
239
+ def __str__ (self ):
240
+ return self .operator
241
+
242
+ def __repr__ (self ):
243
+ return self .operator
244
+
239
245
240
246
class SearchCombinable :
241
247
def _combine (self , other , connector ):
@@ -288,12 +294,12 @@ def _get_query_index(self, fields, compiler):
288
294
return search_indexes ["name" ]
289
295
return "default"
290
296
291
- def search_operator (self , compiler , connection ):
297
+ def search_operator (self ):
292
298
raise NotImplementedError
293
299
294
300
def as_mql (self , compiler , connection ):
295
301
index = self ._get_query_index (self .get_search_fields (), compiler )
296
- return {"$search" : {** self .search_operator (compiler , connection ), "index" : index }}
302
+ return {"$search" : {** self .search_operator (), "index" : index }}
297
303
298
304
299
305
class SearchAutocomplete (SearchExpression ):
@@ -307,7 +313,7 @@ def __init__(self, path, query, fuzzy=None, score=None):
307
313
def get_search_fields (self ):
308
314
return {self .path }
309
315
310
- def search_operator (self , compiler , connection ):
316
+ def search_operator (self ):
311
317
params = {
312
318
"path" : self .path ,
313
319
"query" : self .query ,
@@ -329,7 +335,7 @@ def __init__(self, path, value, score=None):
329
335
def get_search_fields (self ):
330
336
return {self .path }
331
337
332
- def search_operator (self , compiler , connection ):
338
+ def search_operator (self ):
333
339
params = {
334
340
"path" : self .path ,
335
341
"value" : self .value ,
@@ -348,7 +354,7 @@ def __init__(self, path, score=None):
348
354
def get_search_fields (self ):
349
355
return {self .path }
350
356
351
- def search_operator (self , compiler , connection ):
357
+ def search_operator (self ):
352
358
params = {
353
359
"path" : self .path ,
354
360
}
@@ -367,7 +373,7 @@ def __init__(self, path, value, score=None):
367
373
def get_search_fields (self ):
368
374
return {self .path }
369
375
370
- def search_operator (self , compiler , connection ):
376
+ def search_operator (self ):
371
377
params = {
372
378
"path" : self .path ,
373
379
"value" : self .value ,
@@ -389,7 +395,7 @@ def __init__(self, path, query, slop=None, synonyms=None, score=None):
389
395
def get_search_fields (self ):
390
396
return {self .path }
391
397
392
- def search_operator (self , compiler , connection ):
398
+ def search_operator (self ):
393
399
params = {
394
400
"path" : self .path ,
395
401
"query" : self .query ,
@@ -413,7 +419,7 @@ def __init__(self, path, query, score=None):
413
419
def get_search_fields (self ):
414
420
return {self .path }
415
421
416
- def search_operator (self , compiler , connection ):
422
+ def search_operator (self ):
417
423
params = {
418
424
"defaultPath" : self .path ,
419
425
"query" : self .query ,
@@ -436,7 +442,7 @@ def __init__(self, path, lt=None, lte=None, gt=None, gte=None, score=None):
436
442
def get_search_fields (self ):
437
443
return {self .path }
438
444
439
- def search_operator (self , compiler , connection ):
445
+ def search_operator (self ):
440
446
params = {
441
447
"path" : self .path ,
442
448
}
@@ -464,7 +470,7 @@ def __init__(self, path, query, allow_analyzed_field=None, score=None):
464
470
def get_search_fields (self ):
465
471
return {self .path }
466
472
467
- def search_operator (self , compiler , connection ):
473
+ def search_operator (self ):
468
474
params = {
469
475
"path" : self .path ,
470
476
"query" : self .query ,
@@ -489,7 +495,7 @@ def __init__(self, path, query, fuzzy=None, match_criteria=None, synonyms=None,
489
495
def get_search_fields (self ):
490
496
return {self .path }
491
497
492
- def search_operator (self , compiler , connection ):
498
+ def search_operator (self ):
493
499
params = {
494
500
"path" : self .path ,
495
501
"query" : self .query ,
@@ -516,7 +522,7 @@ def __init__(self, path, query, allow_analyzed_field=None, score=None):
516
522
def get_search_fields (self ):
517
523
return {self .path }
518
524
519
- def search_operator (self , compiler , connection ):
525
+ def search_operator (self ):
520
526
params = {
521
527
"path" : self .path ,
522
528
"query" : self .query ,
@@ -539,7 +545,7 @@ def __init__(self, path, relation, geometry, score=None):
539
545
def get_search_fields (self ):
540
546
return {self .path }
541
547
542
- def search_operator (self , compiler , connection ):
548
+ def search_operator (self ):
543
549
params = {
544
550
"path" : self .path ,
545
551
"relation" : self .relation ,
@@ -558,7 +564,7 @@ def __init__(self, path, kind, geo_object, score=None):
558
564
self .score = score
559
565
super ().__init__ ()
560
566
561
- def search_operator (self , compiler , connection ):
567
+ def search_operator (self ):
562
568
params = {
563
569
"path" : self .path ,
564
570
self .kind : self .geo_object ,
@@ -577,7 +583,7 @@ def __init__(self, documents, score=None):
577
583
self .score = score
578
584
super ().__init__ ()
579
585
580
- def search_operator (self , compiler , connection ):
586
+ def search_operator (self ):
581
587
params = {
582
588
"like" : self .documents ,
583
589
}
@@ -670,29 +676,23 @@ def get_search_fields(self):
670
676
fields .update (clause .get_search_fields ())
671
677
return fields
672
678
673
- def search_operator (self , compiler , connection ):
679
+ def search_operator (self ):
674
680
params = {}
675
681
if self .must :
676
- params ["must" ] = [clause .search_operator (compiler , connection ) for clause in self .must ]
682
+ params ["must" ] = [clause .search_operator () for clause in self .must ]
677
683
if self .must_not :
678
- params ["mustNot" ] = [
679
- clause .search_operator (compiler , connection ) for clause in self .must_not
680
- ]
684
+ params ["mustNot" ] = [clause .search_operator () for clause in self .must_not ]
681
685
if self .should :
682
- params ["should" ] = [
683
- clause .search_operator (compiler , connection ) for clause in self .should
684
- ]
686
+ params ["should" ] = [clause .search_operator () for clause in self .should ]
685
687
if self .filter :
686
- params ["filter" ] = [
687
- clause .search_operator (compiler , connection ) for clause in self .filter
688
- ]
688
+ params ["filter" ] = [clause .search_operator () for clause in self .filter ]
689
689
if self .minimum_should_match is not None :
690
690
params ["minimumShouldMatch" ] = self .minimum_should_match
691
691
692
692
return {"compound" : params }
693
693
694
694
def negate (self ):
695
- return CompoundExpression (must = self . must_not , must_not = self . must + self . filter )
695
+ return CompoundExpression (must_not = [ self ] )
696
696
697
697
698
698
class CombinedSearchExpression (SearchExpression ):
@@ -702,7 +702,7 @@ def __init__(self, lhs, operator, rhs):
702
702
self .rhs = rhs
703
703
704
704
@staticmethod
705
- def _flatten (node , negated = False ):
705
+ def resolve (node , negated = False ):
706
706
if node is None :
707
707
return None
708
708
# Leaf, resolve the compoundExpression
@@ -711,25 +711,24 @@ def _flatten(node, negated=False):
711
711
# Apply De Morgan's Laws.
712
712
operator = node .operator .negate () if negated else node .operator
713
713
negated = negated != (node .operator == Operator .NOT )
714
- lhs_compound = node ._flatten (node .lhs , negated )
715
- rhs_compound = node ._flatten (node .rhs , negated )
714
+ lhs_compound = node .resolve (node .lhs , negated )
715
+ rhs_compound = node .resolve (node .rhs , negated )
716
716
if operator == Operator .OR :
717
717
return CompoundExpression (should = [lhs_compound , rhs_compound ], minimum_should_match = 1 )
718
- if node .operator == Operator .AND :
719
- return CompoundExpression (
720
- must = lhs_compound .must + rhs_compound .must ,
721
- must_not = lhs_compound .must_not + rhs_compound .must_not ,
722
- should = lhs_compound .should + rhs_compound .should ,
723
- filter = lhs_compound .filter + rhs_compound .filter ,
724
- )
725
- # it also can be written as:
726
- # this way is more consistent with OR, but the above is shorter in the debug query.
727
- # return CompoundExpression(must=[lhs_compound, rhs_compound])
718
+ if operator == Operator .AND :
719
+ # NOTE: we can't just do the code below, think about this case (A | B) & (C | D)
720
+ # return CompoundExpression(
721
+ # must=lhs_compound.must + rhs_compound.must,
722
+ # must_not=lhs_compound.must_not + rhs_compound.must_not,
723
+ # should=lhs_compound.should + rhs_compound.should,
724
+ # filter=lhs_compound.filter + rhs_compound.filter,
725
+ # )
726
+ return CompoundExpression (must = [lhs_compound , rhs_compound ])
728
727
# not operator
729
728
return lhs_compound
730
729
731
730
def as_mql (self , compiler , connection ):
732
- expression = self ._flatten (self )
731
+ expression = self .resolve (self )
733
732
return expression .as_mql (compiler , connection )
734
733
735
734
0 commit comments