22import datetime
33import logging
44import numbers
5+ import re
56import time
67
78import pytz
@@ -644,6 +645,47 @@ def outdated_queries(cls):
644645
645646 return list (outdated_queries .values ())
646647
648+ @classmethod
649+ def _do_multi_byte_search (cls , all_queries , term , limit = None ):
650+ # term examples:
651+ # - word
652+ # - name:word
653+ # - query:word
654+ # - "multiple words"
655+ # - name:"multiple words"
656+ # - word1 word2 word3
657+ # - word1 "multiple word" query:"select foo"
658+ tokens = re .findall (r'(?:([^:\s]+):)?(?:"([^"]+)"|(\S+))' , term )
659+ conditions = []
660+ for token in tokens :
661+ key = None
662+ if token [0 ]:
663+ key = token [0 ]
664+
665+ if token [1 ]:
666+ value = token [1 ]
667+ else :
668+ value = token [2 ]
669+
670+ pattern = f"%{ value } %"
671+
672+ if key == "id" and value .isdigit ():
673+ conditions .append (cls .id .equal (int (value )))
674+ elif key == "name" :
675+ conditions .append (cls .name .ilike (pattern ))
676+ elif key == "query" :
677+ conditions .append (cls .query_text .ilike (pattern ))
678+ elif key == "description" :
679+ conditions .append (cls .description .ilike (pattern ))
680+ else :
681+ conditions .append (or_ (cls .name .ilike (pattern ), cls .description .ilike (pattern )))
682+
683+ return (
684+ all_queries .filter (and_ (* conditions ))
685+ .order_by (Query .id )
686+ .limit (limit )
687+ )
688+
647689 @classmethod
648690 def search (
649691 cls ,
@@ -664,12 +706,7 @@ def search(
664706
665707 if multi_byte_search :
666708 # Since tsvector doesn't work well with CJK languages, use `ilike` too
667- pattern = "%{}%" .format (term )
668- return (
669- all_queries .filter (or_ (cls .name .ilike (pattern ), cls .description .ilike (pattern )))
670- .order_by (Query .id )
671- .limit (limit )
672- )
709+ return cls ._do_multi_byte_search (all_queries , term , limit )
673710
674711 # sort the result using the weight as defined in the search vector column
675712 return all_queries .search (term , sort = True ).limit (limit )
0 commit comments