Skip to content

Commit 4c3e891

Browse files
committed
Fix expression_converter tests
1 parent f2ea829 commit 4c3e891

File tree

3 files changed

+128
-108
lines changed

3 files changed

+128
-108
lines changed

django_mongodb_backend/query.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ def __init__(self, compiler):
5757
# $lookup stage that encapsulates the pipeline for performing a nested
5858
# subquery.
5959
self.subquery_lookup = None
60+
self.query_optimizer = QueryOptimizer()
6061

6162
def __repr__(self):
6263
return f"<MongoQuery: {self.match_mql!r} ORDER {self.ordering!r}>"
@@ -89,7 +90,7 @@ def get_pipeline(self):
8990
for query in self.subqueries or ():
9091
pipeline.extend(query.get_pipeline())
9192
if self.match_mql:
92-
pipeline.extend(QueryOptimizer().convert_expr_to_match(self.match_mql))
93+
pipeline.extend(self.query_optimizer.convert_expr_to_match(self.match_mql))
9394
if self.aggregation_pipeline:
9495
pipeline.extend(self.aggregation_pipeline)
9596
if self.project_fields:

tests/expression_converter_/test_match_conversion.py

Lines changed: 92 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
class 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

Comments
 (0)