@@ -10,6 +10,45 @@ class BaseConverter:
1010 def convert (cls , expr ):
1111 raise NotImplementedError ("Subclasses must implement this method." )
1212
13+ @classmethod
14+ def is_simple_field_name (cls , field_name ):
15+ return (
16+ isinstance (field_name , str )
17+ and field_name != ""
18+ and field_name .startswith ("$" )
19+ # Special case for _ separated field names
20+ and field_name [1 :].replace ("_" , "" ).isalnum ()
21+ )
22+
23+ @classmethod
24+ def is_simple_get_field (cls , get_field_object ):
25+ if not isinstance (get_field_object , dict ):
26+ return False
27+
28+ get_field_expr = get_field_object .get ("$getField" )
29+
30+ if (
31+ isinstance (get_field_expr , dict )
32+ and "input" in get_field_expr
33+ and "field" in get_field_expr
34+ ):
35+ input_expr = get_field_expr ["input" ]
36+ field_name = get_field_expr ["field" ]
37+ return cls .convert_field_name (input_expr ) and (
38+ isinstance (field_name , str ) and not field_name .startswith ("$" )
39+ )
40+ return False
41+
42+ @classmethod
43+ def convert_field_name (cls , field_name ):
44+ if cls .is_simple_field_name (field_name ):
45+ return field_name [1 :]
46+ if cls .is_simple_get_field (field_name ):
47+ get_field_input = field_name ["$getField" ]["input" ]
48+ get_field_field = field_name ["$getField" ]["field" ]
49+ return f"{ cls .convert_field_name (get_field_input )} .{ get_field_field } "
50+ return None
51+
1352 @classmethod
1453 def is_simple_value (cls , value ):
1554 """Is the value is a simple type (not a dict)?"""
@@ -19,7 +58,6 @@ def is_simple_value(cls, value):
1958 return False
2059 if isinstance (value , (list , tuple , set )):
2160 return all (cls .is_simple_value (v ) for v in value )
22- # TODO: Support `$getField` conversion.
2361 return not isinstance (value , dict )
2462
2563
@@ -35,12 +73,7 @@ def convert(cls, args):
3573 if isinstance (args , list ) and len (args ) == 2 :
3674 field_expr , value = args
3775 # Check if first argument is a simple field reference.
38- if (
39- isinstance (field_expr , str )
40- and field_expr .startswith ("$" )
41- and cls .is_simple_value (value )
42- ):
43- field_name = field_expr [1 :] # Remove the $ prefix.
76+ if (field_name := cls .convert_field_name (field_expr )) and cls .is_simple_value (value ):
4477 if cls .operator == "$eq" :
4578 return {field_name : value }
4679 return {field_name : {cls .operator : value }}
@@ -135,13 +168,12 @@ def convert(cls, in_args):
135168 field_expr , values = in_args
136169
137170 # Check if first argument is a simple field reference
138- if isinstance (field_expr , str ) and field_expr .startswith ("$" ):
139- field_name = field_expr [1 :] # Remove the $ prefix
140- if isinstance (values , (list , tuple , set )) and all (
141- cls .is_simple_value (v ) for v in values
142- ):
143- return {field_name : {"$in" : values }}
144-
171+ # Check if second argument is a list of simple values
172+ if (field_name := cls .convert_field_name (field_expr )) and (
173+ isinstance (values , list | tuple | set )
174+ and all (cls .is_simple_value (v ) for v in values )
175+ ):
176+ return {field_name : {"$in" : values }}
145177 return None
146178
147179
0 commit comments