@@ -214,8 +214,7 @@ def value(self, compiler, connection): # noqa: ARG001
214214
215215
216216class SearchExpression (Expression ):
217- def __init__ (self ):
218- super ().__init__ (output_field = FloatField ())
217+ output_field = FloatField ()
219218
220219 def get_source_expressions (self ):
221220 return []
@@ -240,34 +239,37 @@ def _get_query_index(self, fields, compiler):
240239
241240
242241class SearchAutocomplete (SearchExpression ):
243- def __init__ (self , path , query , score = None ):
244- self .path = F (path )
245- self .query = Value (query )
242+ def __init__ (self , path , query , fuzzy = None , score = None ):
243+ self .path = path
244+ self .query = query
245+ self .fuzzy = fuzzy
246246 self .score = score
247247 super ().__init__ ()
248248
249249 def as_mql (self , compiler , connection ):
250250 params = {
251- "path" : self .path . as_mql ( compiler , connection )[ 1 :] ,
252- "query" : self .query . as_mql ( compiler , connection ) ,
251+ "path" : self .path ,
252+ "query" : self .query ,
253253 }
254254 if self .score is not None :
255255 params ["score" ] = self .score
256+ if self .fuzzy is not None :
257+ params ["fuzzy" ] = self .fuzzy
256258 index = self ._get_query_index ([self .path ], compiler )
257259 return {"$search" : {"autocomplete" : params , "index" : index }}
258260
259261
260262class SearchEquals (SearchExpression ):
261263 def __init__ (self , path , value , score = None ):
262- self .path = F ( path )
263- self .value = Value ( query )
264+ self .path = path
265+ self .value = value
264266 self .score = score
265267 super ().__init__ ()
266268
267269 def as_mql (self , compiler , connection ):
268270 params = {
269- "path" : self .path . as_mql ( compiler , connection )[ 1 :] ,
270- "value" : self .value . as_mql ( compiler , connection ) ,
271+ "path" : self .path ,
272+ "value" : self .value ,
271273 }
272274 if self .score is not None :
273275 params ["score" ] = self .score
@@ -277,13 +279,13 @@ def as_mql(self, compiler, connection):
277279
278280class SearchExists (SearchExpression ):
279281 def __init__ (self , path , score = None ):
280- self .path = F ( path )
282+ self .path = path
281283 self .score = score
282284 super ().__init__ ()
283285
284286 def as_mql (self , compiler , connection ):
285287 params = {
286- "path" : self .path . as_mql ( compiler , connection )[ 1 :] ,
288+ "path" : self .path ,
287289 }
288290 if self .score is not None :
289291 params ["score" ] = self .score
@@ -293,15 +295,15 @@ def as_mql(self, compiler, connection):
293295
294296class SearchIn (SearchExpression ):
295297 def __init__ (self , path , value , score = None ):
296- self .path = F ( path )
297- self .value = Value ( value )
298+ self .path = path
299+ self .value = value
298300 self .score = score
299301 super ().__init__ ()
300302
301303 def as_mql (self , compiler , connection ):
302304 params = {
303- "path" : self .path . as_mql ( compiler , connection )[ 1 :] ,
304- "value" : self .value . as_mql ( compiler , connection ) ,
305+ "path" : self .path ,
306+ "value" : self .value ,
305307 }
306308 if self .score is not None :
307309 params ["score" ] = self .score
@@ -310,18 +312,18 @@ def as_mql(self, compiler, connection):
310312
311313
312314class SearchPhrase (SearchExpression ):
313- def __init__ (self , path , value , slop = None , synonyms = None , score = None ):
314- self .path = F ( path )
315- self .value = Value ( value )
315+ def __init__ (self , path , query , slop = None , synonyms = None , score = None ):
316+ self .path = path
317+ self .query = query
316318 self .score = score
317319 self .slop = slop
318320 self .synonyms = synonyms
319321 super ().__init__ ()
320322
321323 def as_mql (self , compiler , connection ):
322324 params = {
323- "path" : self .path . as_mql ( compiler , connection )[ 1 :] ,
324- "value " : self .value . as_mql ( compiler , connection ) ,
325+ "path" : self .path ,
326+ "query " : self .query ,
325327 }
326328 if self .score is not None :
327329 params ["score" ] = self .score
@@ -335,15 +337,15 @@ def as_mql(self, compiler, connection):
335337
336338class SearchQueryString (SearchExpression ):
337339 def __init__ (self , path , query , score = None ):
338- self .path = F ( path )
339- self .query = Value ( query )
340+ self .path = path
341+ self .query = query
340342 self .score = score
341343 super ().__init__ ()
342344
343345 def as_mql (self , compiler , connection ):
344346 params = {
345- "defaultPath" : self .path . as_mql ( compiler , connection )[ 1 :] ,
346- "query" : self .query . as_mql ( compiler , connection ) ,
347+ "defaultPath" : self .path ,
348+ "query" : self .query ,
347349 }
348350 if self .score is not None :
349351 params ["score" ] = self .score
@@ -353,132 +355,138 @@ def as_mql(self, compiler, connection):
353355
354356class SearchRange (SearchExpression ):
355357 def __init__ (self , path , lt = None , lte = None , gt = None , gte = None , score = None ):
356- self .path = F ( path )
357- self .lt = Value ( lt )
358- self .lte = Value ( lte )
359- self .gt = Value ( gt )
360- self .gte = Value ( gte )
358+ self .path = path
359+ self .lt = lt
360+ self .lte = lte
361+ self .gt = gt
362+ self .gte = gte
361363 self .score = score
362364 super ().__init__ ()
363365
364366 def as_mql (self , compiler , connection ):
365367 params = {
366- "path" : self .path . as_mql ( compiler , connection )[ 1 :] ,
368+ "path" : self .path ,
367369 }
368370 if self .score is not None :
369371 params ["score" ] = self .score
370372 if self .lt is not None :
371- params ["lt" ] = self .lt . as_mql ( compiler , connection )
373+ params ["lt" ] = self .lt
372374 if self .lte is not None :
373- params ["lte" ] = self .lte . as_mql ( compiler , connection )
375+ params ["lte" ] = self .lte
374376 if self .gt is not None :
375- params ["gt" ] = self .gt . as_mql ( compiler , connection )
377+ params ["gt" ] = self .gt
376378 if self .gte is not None :
377- params ["gte" ] = self .gte . as_mql ( compiler , connection )
379+ params ["gte" ] = self .gte
378380 index = self ._get_query_index ([self .path ], compiler )
379381 return {"$search" : {"range" : params , "index" : index }}
380382
381383
382384class SearchRegex (SearchExpression ):
383385 def __init__ (self , path , query , allow_analyzed_field = None , score = None ):
384- self .path = F (path )
385- self .allow_analyzed_field = Value (allow_analyzed_field )
386+ self .path = path
387+ self .query = query
388+ self .allow_analyzed_field = allow_analyzed_field
386389 self .score = score
387390 super ().__init__ ()
388391
389392 def as_mql (self , compiler , connection ):
390393 params = {
391- "path" : self .path .as_mql (compiler , connection )[1 :],
394+ "path" : self .path ,
395+ "query" : self .query ,
392396 }
393397 if self .score :
394398 params ["score" ] = self .score
395399 if self .allow_analyzed_field is not None :
396- params ["allowAnalyzedField" ] = self .allow_analyzed_field . as_mql ( compiler , connection )
400+ params ["allowAnalyzedField" ] = self .allow_analyzed_field
397401 index = self ._get_query_index ([self .path ], compiler )
398402 return {"$search" : {"regex" : params , "index" : index }}
399403
400404
401405class SearchText (SearchExpression ):
402406 def __init__ (self , path , query , fuzzy = None , match_criteria = None , synonyms = None , score = None ):
403- self .path = F (path )
404- self .fuzzy = Value (fuzzy )
405- self .match_criteria = Value (match_criteria )
406- self .synonyms = Value (synonyms )
407+ self .path = path
408+ self .query = query
409+ self .fuzzy = fuzzy
410+ self .match_criteria = match_criteria
411+ self .synonyms = synonyms
407412 self .score = score
408413 super ().__init__ ()
409414
410415 def as_mql (self , compiler , connection ):
411416 params = {
412- "path" : self .path .as_mql (compiler , connection )[1 :],
417+ "path" : self .path ,
418+ "query" : self .query ,
413419 }
414420 if self .score :
415421 params ["score" ] = self .score
416422 if self .fuzzy is not None :
417- params ["fuzzy" ] = self .fuzzy . as_mql ( compiler , connection )
423+ params ["fuzzy" ] = self .fuzzy
418424 if self .match_criteria is not None :
419- params ["matchCriteria" ] = self .match_criteria . as_mql ( compiler , connection )
425+ params ["matchCriteria" ] = self .match_criteria
420426 if self .synonyms is not None :
421- params ["synonyms" ] = self .synonyms . as_mql ( compiler , connection )
427+ params ["synonyms" ] = self .synonyms
422428 index = self ._get_query_index ([self .path ], compiler )
423429 return {"$search" : {"text" : params , "index" : index }}
424430
425431
426432class SearchWildcard (SearchExpression ):
427433 def __init__ (self , path , query , allow_analyzed_field = None , score = None ):
428- self .path = F (path )
429- self .allow_analyzed_field = Value (allow_analyzed_field )
434+ self .path = path
435+ self .query = query
436+ self .allow_analyzed_field = allow_analyzed_field
430437 self .score = score
431438 super ().__init__ ()
432439
433440 def as_mql (self , compiler , connection ):
434441 params = {
435- "path" : self .path .as_mql (compiler , connection )[1 :],
442+ "path" : self .path ,
443+ "query" : self .query ,
436444 }
437445 if self .score :
438446 params ["score" ] = self .score
439447 if self .allow_analyzed_field is not None :
440- params ["allowAnalyzedField" ] = self .allow_analyzed_field . as_mql ( compiler , connection )
448+ params ["allowAnalyzedField" ] = self .allow_analyzed_field
441449 index = self ._get_query_index ([self .path ], compiler )
442450 return {"$search" : {"wildcard" : params , "index" : index }}
443451
444452
445453class SearchGeoShape (SearchExpression ):
446454 def __init__ (self , path , relation , geometry , score = None ):
447- self .path = F ( path )
455+ self .path = path
448456 self .relation = relation
449457 self .geometry = geometry
450458 self .score = score
451459 super ().__init__ ()
452460
453461 def as_mql (self , compiler , connection ):
454462 params = {
455- "path" : self .path . as_mql ( compiler , connection )[ 1 :] ,
463+ "path" : self .path ,
456464 "relation" : self .relation ,
457465 "geometry" : self .geometry ,
458466 }
459467 if self .score :
460468 params ["score" ] = self .score
461469 index = self ._get_query_index ([self .path ], compiler )
462- return {"$search" : {"wildcard " : params , "index" : index }}
470+ return {"$search" : {"geoShape " : params , "index" : index }}
463471
464472
465473class SearchGeoWithin (SearchExpression ):
466- def __init__ (self , path , kind , geo_object , geometry , score = None ):
467- self .path = F ( path )
474+ def __init__ (self , path , kind , geo_object , score = None ):
475+ self .path = path
468476 self .kind = kind
469477 self .geo_object = geo_object
470478 self .score = score
471479 super ().__init__ ()
472480
473481 def as_mql (self , compiler , connection ):
474482 params = {
475- "path" : self .path . as_mql ( compiler , connection )[ 1 :] ,
483+ "path" : self .path ,
476484 self .kind : self .geo_object ,
477485 }
478486 if self .score :
479487 params ["score" ] = self .score
480488 index = self ._get_query_index ([self .path ], compiler )
481- return {"$search" : {"wildcard " : params , "index" : index }}
489+ return {"$search" : {"geoWithin " : params , "index" : index }}
482490
483491
484492class SearchMoreLikeThis (SearchExpression ):
@@ -497,7 +505,22 @@ def as_mql(self, compiler, connection):
497505 for doc in self .documents :
498506 needed_fields += list (doc .keys ())
499507 index = self ._get_query_index (needed_fields , compiler )
500- return {"$search" : {"wildcard" : params , "index" : index }}
508+ return {"$search" : {"moreLikeThis" : params , "index" : index }}
509+
510+
511+ class SearchScoreOption :
512+ """Class to mutate scoring on a search operation"""
513+
514+ def __init__ (self , definitions = None ):
515+ self .definitions = definitions
516+
517+
518+ class CombinedSearchExpression (SearchExpression ):
519+ def __init__ (self , lhs , connector , rhs , output_field = None ):
520+ super ().__init__ (output_field = output_field )
521+ self .connector = connector
522+ self .lhs = lhs
523+ self .rhs = rhs
501524
502525
503526def register_expressions ():
0 commit comments