99
1010class QueryOptimizerTests (SimpleTestCase ):
1111 def assertOptimizerEqual (self , input , expected ):
12- result = QueryOptimizer ().optimize (input )
12+ result = QueryOptimizer ().convert_expr_to_match (input )
1313 self .assertEqual (result , expected )
1414
1515 def test_multiple_optimizable_conditions (self ):
@@ -22,15 +22,17 @@ def test_multiple_optimizable_conditions(self):
2222 ]
2323 }
2424 }
25- expected = {
26- "$match" : {
27- "$and" : [
28- {"status" : "active" },
29- {"category" : {"$in" : ["electronics" , "books" ]}},
30- {"verified" : True },
31- ]
25+ expected = [
26+ {
27+ "$match" : {
28+ "$and" : [
29+ {"status" : "active" },
30+ {"category" : {"$in" : ["electronics" , "books" ]}},
31+ {"verified" : True },
32+ ]
33+ }
3234 }
33- }
35+ ]
3436 self .assertOptimizerEqual (expr , expected )
3537
3638 def test_mixed_optimizable_and_non_optimizable_conditions (self ):
@@ -43,21 +45,25 @@ def test_mixed_optimizable_and_non_optimizable_conditions(self):
4345 ]
4446 }
4547 }
46- expected = {
47- "$match" : {
48- "$and" : [{"status" : "active" }, {"category" : {"$in" : ["electronics" ]}}],
49- "$expr" : {"$gt" : ["$price" , 100 ]},
48+ expected = [
49+ {
50+ "$match" : {
51+ "$and" : [{"status" : "active" }, {"category" : {"$in" : ["electronics" ]}}],
52+ "$expr" : {"$gt" : ["$price" , 100 ]},
53+ }
5054 }
51- }
55+ ]
5256 self .assertOptimizerEqual (expr , expected )
5357
5458 def test_non_optimizable_condition (self ):
5559 expr = {"$expr" : {"$gt" : ["$price" , 100 ]}}
56- expected = {
57- "$match" : {
58- "$expr" : {"$gt" : ["$price" , 100 ]},
60+ expected = [
61+ {
62+ "$match" : {
63+ "$expr" : {"$gt" : ["$price" , 100 ]},
64+ }
5965 }
60- }
66+ ]
6167 self .assertOptimizerEqual (expr , expected )
6268
6369 def test_nested_logical_conditions (self ):
@@ -70,18 +76,14 @@ def test_nested_logical_conditions(self):
7076 ]
7177 }
7278 }
73- expected = {
74- "$match" : {
75- "$or" : [
76- {"status" : "active" },
77- {"category" : {"$in" : ["electronics" , "books" ]}},
78- ],
79- "$and" : [
80- {"verified" : True },
81- {"price" : {"$gt" : 50 }},
82- ],
79+ expected = [
80+ {
81+ "$match" : {
82+ "$expr" : {"$and" : [{"$eq" : ["$verified" , True ]}, {"$gt" : ["$price" , 50 ]}]},
83+ "$or" : [{"status" : "active" }, {"category" : {"$in" : ["electronics" , "books" ]}}],
84+ }
8385 }
84- }
86+ ]
8587 self .assertOptimizerEqual (expr , expected )
8688
8789 def test_complex_nested_with_non_optimizable_parts (self ):
@@ -100,30 +102,32 @@ def test_complex_nested_with_non_optimizable_parts(self):
100102 ]
101103 }
102104 }
103- expected = {
104- "$match" : {
105- "$and" : [
106- {"category" : {"$in" : ["electronics" , "books" ]}},
107- {"verified" : True },
108- ],
109- "$expr" : {
105+ expected = [
106+ {
107+ "$match" : {
110108 "$and" : [
111- {
112- "$or" : [
113- {"$eq" : ["$status" , "active" ]},
114- {"$gt" : ["$views" , 1000 ]},
115- ]
116- },
117- {"$gt" : ["$price" , 50 ]},
118- ]
119- },
109+ {"category" : {"$in" : ["electronics" , "books" ]}},
110+ {"verified" : True },
111+ ],
112+ "$expr" : {
113+ "$and" : [
114+ {
115+ "$or" : [
116+ {"$eq" : ["$status" , "active" ]},
117+ {"$gt" : ["$views" , 1000 ]},
118+ ]
119+ },
120+ {"$gt" : ["$price" , 50 ]},
121+ ]
122+ },
123+ }
120124 }
121- }
125+ ]
122126 self .assertOptimizerEqual (expr , expected )
123127
124128 def test_london_in_case (self ):
125129 expr = {"$expr" : {"$in" : ["$author_city" , ["London" ]]}}
126- expected = {"$match" : {"author_city" : {"$in" : ["London" ]}}}
130+ expected = [ {"$match" : {"author_city" : {"$in" : ["London" ]}}}]
127131 self .assertOptimizerEqual (expr , expected )
128132
129133 def test_deeply_nested_logical_operators (self ):
@@ -145,24 +149,26 @@ def test_deeply_nested_logical_operators(self):
145149 ]
146150 }
147151 }
148- expected = {
149- "$match" : {
150- "$and" : [
151- {
152- "$or" : [
153- {"type" : "premium" },
154- {
155- "$and" : [
156- {"type" : "standard" },
157- {"region" : {"$in" : ["US" , "CA" ]}},
158- ]
159- },
160- ]
161- },
162- {"active" : True },
163- ]
152+ expected = [
153+ {
154+ "$match" : {
155+ "$and" : [
156+ {
157+ "$or" : [
158+ {"type" : "premium" },
159+ {
160+ "$and" : [
161+ {"type" : "standard" },
162+ {"region" : {"$in" : ["US" , "CA" ]}},
163+ ]
164+ },
165+ ]
166+ },
167+ {"active" : True },
168+ ]
169+ }
164170 }
165- }
171+ ]
166172 self .assertOptimizerEqual (expr , expected )
167173
168174 def test_deeply_nested_logical_operator_with_variable (self ):
@@ -185,22 +191,24 @@ def test_deeply_nested_logical_operator_with_variable(self):
185191 ]
186192 }
187193 }
188- expected = {
189- "$match" : {
190- "$expr" : {
191- "$and" : [
192- {"$eq" : ["$type" , "premium" ]},
193- {
194- "$and" : [
195- {"$eq" : ["$type" , "$$standard" ]},
196- {"$in" : ["$region" , ["US" , "CA" ]]},
197- ]
198- },
199- ]
200- },
201- "$and" : [{"active" : True }],
194+ expected = [
195+ {
196+ "$match" : {
197+ "$expr" : {
198+ "$or" : [
199+ {"$eq" : ["$type" , "premium" ]},
200+ {
201+ "$and" : [
202+ {"$eq" : ["$type" , "$$standard" ]},
203+ {"$in" : ["$region" , ["US" , "CA" ]]},
204+ ]
205+ },
206+ ]
207+ },
208+ "$and" : [{"active" : True }],
209+ }
202210 }
203- }
211+ ]
204212 self .assertOptimizerEqual (expr , expected )
205213
206214
@@ -210,23 +218,24 @@ def test_in_query(self):
210218 list (Author .objects .filter (author_city__in = ["London" ]))
211219 query = ctx .captured_queries [0 ]["sql" ]
212220 expected = (
213- "db.queries__author.aggregate([{'$match': {'author_city': {'$in': ['London']}}}])"
221+ "db.expression_converter__author.aggregate([{'$match': "
222+ + "{'author_city': {'$in': ('London',)}}}])"
214223 )
215224 self .assertEqual (query , expected )
216225
217226 def test_eq_query (self ):
218227 with self .assertNumQueries (1 ) as ctx :
219228 list (Author .objects .filter (name = "Alice" ))
220229 query = ctx .captured_queries [0 ]["sql" ]
221- expected = "db.queries__author .aggregate([{'$match': {'name': 'Alice'}}])"
230+ expected = "db.expression_converter__author .aggregate([{'$match': {'name': 'Alice'}}])"
222231 self .assertEqual (query , expected )
223232
224233 def test_eq_and_in_query (self ):
225234 with self .assertNumQueries (1 ) as ctx :
226235 list (Author .objects .filter (name = "Alice" , author_city__in = ["London" , "New York" ]))
227236 query = ctx .captured_queries [0 ]["sql" ]
228237 expected = (
229- "db.queries__author .aggregate([{'$match': {'$and': [{'name': 'Alice'}, "
230- " {'author_city': {'$in': [ 'London', 'New York']} }]}}])"
238+ "db.expression_converter__author .aggregate([{'$match': {'$and': "
239+ + "[ {'author_city': {'$in': ( 'London', 'New York')}}, {'name': 'Alice' }]}}])"
231240 )
232241 self .assertEqual (query , expected )
0 commit comments