Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions world_cup/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,23 @@ def top_scorers(request):
},
}

def _get_query(queryset):
"""Print the collection and aggregation pipeline behind `queryset`."""
if isinstance(queryset, RawQuerySet):
# raw_aggregate() pipelines are already MQL: RawQuery has no compiler,
# it just holds the pipeline that gets handed to collection.aggregate().
collection = queryset.model._meta.db_table
pipeline = queryset.query.pipeline
else:
compiler = queryset.query.get_compiler(using=queryset.db)
# Same steps the backend takes in SQLCompiler.as_sql()/explain_query().
compiler.pre_sql_setup()
# The compiler needs the columns to project.
columns = compiler.get_project_columns(compiler.columns)
mongo_query = compiler.build_query(columns)
collection = compiler.collection_name
pipeline = mongo_query.get_pipeline()
return f'db.world_cup_match.aggregate({pipeline})'

def _execute_query(query_text):
"""Parse and execute a user query, return result dict."""
Expand All @@ -66,6 +83,7 @@ def _execute_query(query_text):
.aggregate(tournament_goals=Sum("total_goals"))
)
return {
"query": _get_query(result),
"results": [{"tournament_goals": result["tournament_goals"] or 0}],
}

Expand All @@ -79,6 +97,7 @@ def _execute_query(query_text):
]
results = Match.objects.raw_aggregate(pipeline)
return {
"query": _get_query(results),
"results": [{"scorer": r.pk, "goals": r.total_goals} for r in results],
}

Expand All @@ -87,7 +106,7 @@ def _execute_query(query_text):
from django.db.models import Q
matches = Match.objects.filter(Q(team1__iexact=team) | Q(team2__iexact=team)).order_by("date")
return {
"query": f'db.world_cup_match.aggregate([{{$match: {{$or: [{{team1: {{$regex: "^{team}$", $options: "i"}}}}, {{team2: {{$regex: "^{team}$", $options: "i"}}}}]}}}}, {{$sort: {{date: 1}}}}])',
"query": _get_query(matches),
"results": [
{
"date": str(m.date),
Expand All @@ -104,7 +123,7 @@ def _execute_query(query_text):
round_name = query_text.strip()[6:].strip()
matches = Match.objects.filter(round__icontains=round_name).order_by("date")
return {
"query": f'db.world_cup_match.aggregate([{{$match: {{round: {{$regex: "{round_name}", $options: "i"}}}}}}, {{$sort: {{date: 1}}}}])',
"query": _get_query(matches),
"results": [
{
"date": str(m.date),
Expand All @@ -128,6 +147,7 @@ def _execute_query(query_text):
]
results = Match.objects.raw_aggregate(pipeline)
return {
"query": _get_query(results),
"results": [{"round": r.pk, "goals": r.total_goals, "matches": r.matches} for r in results],
}

Expand All @@ -150,4 +170,4 @@ def query_shell(request):
context["mongo_query"] = result.get("query", "")
context["results"] = result.get("results", [])

return render(request, "world_cup/shell.html", context)
return render(request, "world_cup/shell.html", context)