@@ -231,6 +231,12 @@ def negate(self):
231
231
def __hash__ (self ):
232
232
return hash (self .operator )
233
233
234
+ def __str__ (self ):
235
+ return self .operator
236
+
237
+ def __repr__ (self ):
238
+ return self .operator
239
+
234
240
235
241
class SearchCombinable :
236
242
def _combine (self , other , connector ):
@@ -283,12 +289,12 @@ def _get_query_index(self, fields, compiler):
283
289
return search_indexes ["name" ]
284
290
return "default"
285
291
286
- def search_operator (self , compiler , connection ):
292
+ def search_operator (self ):
287
293
raise NotImplementedError
288
294
289
295
def as_mql (self , compiler , connection ):
290
296
index = self ._get_query_index (self .get_search_fields (), compiler )
291
- return {"$search" : {** self .search_operator (compiler , connection ), "index" : index }}
297
+ return {"$search" : {** self .search_operator (), "index" : index }}
292
298
293
299
294
300
class SearchAutocomplete (SearchExpression ):
@@ -302,7 +308,7 @@ def __init__(self, path, query, fuzzy=None, score=None):
302
308
def get_search_fields (self ):
303
309
return {self .path }
304
310
305
- def search_operator (self , compiler , connection ):
311
+ def search_operator (self ):
306
312
params = {
307
313
"path" : self .path ,
308
314
"query" : self .query ,
@@ -324,7 +330,7 @@ def __init__(self, path, value, score=None):
324
330
def get_search_fields (self ):
325
331
return {self .path }
326
332
327
- def search_operator (self , compiler , connection ):
333
+ def search_operator (self ):
328
334
params = {
329
335
"path" : self .path ,
330
336
"value" : self .value ,
@@ -343,7 +349,7 @@ def __init__(self, path, score=None):
343
349
def get_search_fields (self ):
344
350
return {self .path }
345
351
346
- def search_operator (self , compiler , connection ):
352
+ def search_operator (self ):
347
353
params = {
348
354
"path" : self .path ,
349
355
}
@@ -362,7 +368,7 @@ def __init__(self, path, value, score=None):
362
368
def get_search_fields (self ):
363
369
return {self .path }
364
370
365
- def search_operator (self , compiler , connection ):
371
+ def search_operator (self ):
366
372
params = {
367
373
"path" : self .path ,
368
374
"value" : self .value ,
@@ -384,7 +390,7 @@ def __init__(self, path, query, slop=None, synonyms=None, score=None):
384
390
def get_search_fields (self ):
385
391
return {self .path }
386
392
387
- def search_operator (self , compiler , connection ):
393
+ def search_operator (self ):
388
394
params = {
389
395
"path" : self .path ,
390
396
"query" : self .query ,
@@ -408,7 +414,7 @@ def __init__(self, path, query, score=None):
408
414
def get_search_fields (self ):
409
415
return {self .path }
410
416
411
- def search_operator (self , compiler , connection ):
417
+ def search_operator (self ):
412
418
params = {
413
419
"defaultPath" : self .path ,
414
420
"query" : self .query ,
@@ -431,7 +437,7 @@ def __init__(self, path, lt=None, lte=None, gt=None, gte=None, score=None):
431
437
def get_search_fields (self ):
432
438
return {self .path }
433
439
434
- def search_operator (self , compiler , connection ):
440
+ def search_operator (self ):
435
441
params = {
436
442
"path" : self .path ,
437
443
}
@@ -459,7 +465,7 @@ def __init__(self, path, query, allow_analyzed_field=None, score=None):
459
465
def get_search_fields (self ):
460
466
return {self .path }
461
467
462
- def search_operator (self , compiler , connection ):
468
+ def search_operator (self ):
463
469
params = {
464
470
"path" : self .path ,
465
471
"query" : self .query ,
@@ -484,7 +490,7 @@ def __init__(self, path, query, fuzzy=None, match_criteria=None, synonyms=None,
484
490
def get_search_fields (self ):
485
491
return {self .path }
486
492
487
- def search_operator (self , compiler , connection ):
493
+ def search_operator (self ):
488
494
params = {
489
495
"path" : self .path ,
490
496
"query" : self .query ,
@@ -511,7 +517,7 @@ def __init__(self, path, query, allow_analyzed_field=None, score=None):
511
517
def get_search_fields (self ):
512
518
return {self .path }
513
519
514
- def search_operator (self , compiler , connection ):
520
+ def search_operator (self ):
515
521
params = {
516
522
"path" : self .path ,
517
523
"query" : self .query ,
@@ -534,7 +540,7 @@ def __init__(self, path, relation, geometry, score=None):
534
540
def get_search_fields (self ):
535
541
return {self .path }
536
542
537
- def search_operator (self , compiler , connection ):
543
+ def search_operator (self ):
538
544
params = {
539
545
"path" : self .path ,
540
546
"relation" : self .relation ,
@@ -553,7 +559,7 @@ def __init__(self, path, kind, geo_object, score=None):
553
559
self .score = score
554
560
super ().__init__ ()
555
561
556
- def search_operator (self , compiler , connection ):
562
+ def search_operator (self ):
557
563
params = {
558
564
"path" : self .path ,
559
565
self .kind : self .geo_object ,
@@ -572,7 +578,7 @@ def __init__(self, documents, score=None):
572
578
self .score = score
573
579
super ().__init__ ()
574
580
575
- def search_operator (self , compiler , connection ):
581
+ def search_operator (self ):
576
582
params = {
577
583
"like" : self .documents ,
578
584
}
@@ -665,29 +671,23 @@ def get_search_fields(self):
665
671
fields .update (clause .get_search_fields ())
666
672
return fields
667
673
668
- def search_operator (self , compiler , connection ):
674
+ def search_operator (self ):
669
675
params = {}
670
676
if self .must :
671
- params ["must" ] = [clause .search_operator (compiler , connection ) for clause in self .must ]
677
+ params ["must" ] = [clause .search_operator () for clause in self .must ]
672
678
if self .must_not :
673
- params ["mustNot" ] = [
674
- clause .search_operator (compiler , connection ) for clause in self .must_not
675
- ]
679
+ params ["mustNot" ] = [clause .search_operator () for clause in self .must_not ]
676
680
if self .should :
677
- params ["should" ] = [
678
- clause .search_operator (compiler , connection ) for clause in self .should
679
- ]
681
+ params ["should" ] = [clause .search_operator () for clause in self .should ]
680
682
if self .filter :
681
- params ["filter" ] = [
682
- clause .search_operator (compiler , connection ) for clause in self .filter
683
- ]
683
+ params ["filter" ] = [clause .search_operator () for clause in self .filter ]
684
684
if self .minimum_should_match is not None :
685
685
params ["minimumShouldMatch" ] = self .minimum_should_match
686
686
687
687
return {"compound" : params }
688
688
689
689
def negate (self ):
690
- return CompoundExpression (must = self . must_not , must_not = self . must + self . filter )
690
+ return CompoundExpression (must_not = [ self ] )
691
691
692
692
693
693
class CombinedSearchExpression (SearchExpression ):
@@ -697,7 +697,7 @@ def __init__(self, lhs, operator, rhs):
697
697
self .rhs = rhs
698
698
699
699
@staticmethod
700
- def _flatten (node , negated = False ):
700
+ def resolve (node , negated = False ):
701
701
if node is None :
702
702
return None
703
703
# Leaf, resolve the compoundExpression
@@ -706,25 +706,24 @@ def _flatten(node, negated=False):
706
706
# Apply De Morgan's Laws.
707
707
operator = node .operator .negate () if negated else node .operator
708
708
negated = negated != (node .operator == Operator .NOT )
709
- lhs_compound = node ._flatten (node .lhs , negated )
710
- rhs_compound = node ._flatten (node .rhs , negated )
709
+ lhs_compound = node .resolve (node .lhs , negated )
710
+ rhs_compound = node .resolve (node .rhs , negated )
711
711
if operator == Operator .OR :
712
712
return CompoundExpression (should = [lhs_compound , rhs_compound ], minimum_should_match = 1 )
713
- if node .operator == Operator .AND :
714
- return CompoundExpression (
715
- must = lhs_compound .must + rhs_compound .must ,
716
- must_not = lhs_compound .must_not + rhs_compound .must_not ,
717
- should = lhs_compound .should + rhs_compound .should ,
718
- filter = lhs_compound .filter + rhs_compound .filter ,
719
- )
720
- # it also can be written as:
721
- # this way is more consistent with OR, but the above is shorter in the debug query.
722
- # return CompoundExpression(must=[lhs_compound, rhs_compound])
713
+ if operator == Operator .AND :
714
+ # NOTE: we can't just do the code below, think about this case (A | B) & (C | D)
715
+ # return CompoundExpression(
716
+ # must=lhs_compound.must + rhs_compound.must,
717
+ # must_not=lhs_compound.must_not + rhs_compound.must_not,
718
+ # should=lhs_compound.should + rhs_compound.should,
719
+ # filter=lhs_compound.filter + rhs_compound.filter,
720
+ # )
721
+ return CompoundExpression (must = [lhs_compound , rhs_compound ])
723
722
# not operator
724
723
return lhs_compound
725
724
726
725
def as_mql (self , compiler , connection ):
727
- expression = self ._flatten (self )
726
+ expression = self .resolve (self )
728
727
return expression .as_mql (compiler , connection )
729
728
730
729
0 commit comments