CricketStats: Ask Cricket History in Plain English with Qwen AI and MongoDB
This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle. What I Built Cricket questions are deceptively difficult. βWho dismissed Gavaskar most often?β is not just a lookup. T
This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle.
What I Built
Cricket questions are deceptively difficult.
βWho dismissed Gavaskar most often?β is not just a lookup. The system must understand that Gavaskar is the dismissed batter, resolve the common name to SM Gavaskar, choose innings-level dismissal data, group by bowler, and return inspectable evidence. A query can be technically valid and still be completely wrong about cricket.
I built CricketStats, a local AI research assistant for asking cricket questions in everyday language. The open-weight Qwen 2.5 Coder 14B model converts a question into a MongoDB aggregation plan, the application validates that plan, and MongoDBβnot the modelβproduces the statistical result.
The hackathon edition includes:
- a general cricket database with 7 data collections and 2,861,363 documents;
- an IPL database with 17 data collections and 416,416 documents;
- 3,277,779 migrated documents in total;
- match, innings, player, career, opposition, venue, dismissal, and fielding statistics;
- 295,732 IPL ball-by-ball delivery records;
- IPL-specific collections for Orange and Purple Cap winners, hat tricks, and team seasons;
- natural-language assistants for both general cricket and the IPL;
- a browser interface with Test/IPL selection, suggested questions, human-readable answers, and optional aggregation details;
- resumable migration, compound indexes, source metadata, and count verification; and
- JSONL tracing of the question, model prompt, generated plan, validated pipeline, and result.
Who would pay for it?
The target users are cricket writers, podcasters, commentators, fantasy-cricket analysts, and serious fan communities. Their current workflow often involves repeated web searches, manually checking scorecards, or writing one-off spreadsheet formulas.
The side-hustle proposition has two possible forms:
- private installation and dataset setup for people who want a self-service cricket research assistant; and
- custom, evidence-backed statistical reports for match previews, articles, broadcasts, podcasts, and social posts.
The product is not another chatbot that claims to βknow cricket.β Its value is faster research with the generated MongoDB aggregation available for inspection and a database as the factual source of truth.
This is a business hypothesis, not a claim of product-market fit. I do not yet have a paid customer or validated willingness to pay. The current deliverable is a working local prototype and a concrete way to test whether specialist users will pay for installation, data preparation, support, or commissioned reports.
Demo
Video demo: Watch the CricketStats MongoDB demo
The demo uses the real local application, Qwen through Ollama, and the migrated MongoDB databases. It shows the browser workflow, switches between Test and IPL data, asks natural-language questions, and exposes the aggregation pipeline behind each answer.
To run the application locally:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e ".[dev]"
ollama pull qwen2.5-coder:14b
# Start MongoDB, migrate the source data, and verify it
docker compose up -d
cricketstats-migrate-mongodb --source all --drop
cricketstats-mongodb-verify
# Start the local browser interface
cricketstats-web
Then open http://127.0.0.1:8765.
MongoDB Community can run locally, or the application can use MongoDB Atlas by setting MONGODB_URI to an Atlas connection string. The demonstrated and verified migration used MongoDB Community 8.0 on localhost.
The command-line assistant is also available:
ask-cricket-mongodb --question "How many Test hundreds did Sachin Tendulkar score?"
ask-cricket-mongodb --ipl --question "Who won the IPL Orange Cap in 2023?"
Add --trace to record the prompt, generated plan, and result under logs/mongodb/.
Code
GitHub repository: krishnakumar-k1/CricketStats-WithMongoDB
The MongoDB edition is in CricketStats_WithMongoDB. Its main components are:
-
src/cricketstats/mongodb_migrate.pyβ resumable SQLite-to-MongoDB migration and index creation; -
src/cricketstats/mongodb_verify.pyβ collection-by-collection source count verification; -
src/cricketstats/mongodb_client.pyβ local or Atlas connection configuration; -
src/cricketstats/mongodb_assistant.pyβ Qwen prompting, deterministic plans, validation, execution, and tracing; -
src/cricketstats/web_app.pyβ localhost web application and API; -
src/cricketstats/web_static/β browser interface; -
tests/test_mongodb_migrate.pyandtests/test_mongodb_assistant.pyβ MongoDB boundary tests; and -
MIGRATION_REPORT.mdβ migration totals and verification record.
How I Built It
The application follows this pipeline:
Natural-language cricket question
β
Deterministic player-name and common-query resolution
β
Live MongoDB schema summary + prompt rules + recent context
β
Qwen 2.5 Coder 14B through local Ollama
β
JSON MongoDB aggregation plan
β
Collection, stage, operator, size, and result-limit validation
β
MongoDB aggregation with a 60-second timeout
β
Human-readable answer + inspectable pipeline and rows
Migrating the cricket databases
The source datasets were previously stored in SQLite. I built a migration layer that copies each table to a same-named MongoDB collection while preserving field names. SQLite rowid becomes MongoDB _id, and JSON strings containing arrays or objects become native BSON arrays and documents.
Migration runs in batches. After each batch, _migration_state stores a per-collection checkpoint, so an interrupted multi-million-document migration can resume rather than restart. _migration_metadata records source and completion details. Once a collection loads, the application creates compound indexes for frequent patterns such as player + format + date, match + innings, team + innings total, dismissal bowler + kind, and IPL match + innings + over + ball.
| Database | Data collections | Documents |
|---|---|---|
cricketstats |
7 | 2,861,363 |
cricketstats_ipl |
17 | 416,416 |
| Total | 24 | 3,277,779 |
A separate verification command compares every MongoDB collection count with its corresponding SQLite source table. All 24 comparisons matched for the recorded migration.
Open-source AI at the core
Qwen is not asked to memorize cricket records. Its job is to turn flexible language into a structured, read-only MongoDB aggregation plan:
{
"collection": "player_career_stats",
"pipeline": [
{"$match": {
"player_name": "SR Tendulkar",
"format_group": "Test",
"competition_name": "All"
}},
{"$project": {"_id": 0, "player_name": 1, "hundreds": 1}},
{"$limit": 1}
]
}
The application sends Qwen a summary generated from the live MongoDB collections, exact player-name candidates, aggregation rules, and recent session context. Ollama serves the model on the same machine.
Why schema alone is not enough
A schema does not explain that:
- a Test can contain four team innings;
- a batter may bat twice in one match;
- βagainst Australiaβ means opposition, while βin Australiaβ means location;
- βoverseasβ depends on the player's home country;
- batting average is runs divided by dismissals, not balls; or
- a stored career wicket total should be selected instead of counting documents.
These cricket semantics are encoded in prompt rules and deterministic plans for high-value question types.
A hybrid approach for reliable answers
Not every question needs probabilistic planning. Common stored career totals and IPL Orange/Purple Cap questions use deterministic MongoDB pipelines. More open-ended questions use Qwen to create the aggregation.
Player names are also resolved before planning. Fans type βSachin Tendulkar,β while the database stores SR Tendulkar; βSunil Gavaskarβ maps to SM Gavaskar. Known aliases and candidates found in MongoDB are supplied to the planner so the model does not invent a stored identity.
This division of labor keeps retrieval in MongoDB, known high-value patterns in deterministic code, and flexible language interpretation in Qwen.
Read-only validation and bounded execution
Model output is treated as untrusted input. A response must be one JSON object containing only a collection and pipeline. The validator:
- accepts only existing, non-internal collections;
- allows a defined set of read-only aggregation stages;
- blocks
$out,$merge,$function,$accumulator, and$where; - validates
$lookuptargets; - rejects pipelines with more than 30 stages;
- adds a result limit when one is missing;
- bounds an explicit final limit; and
- runs aggregation with a 60-second timeout.
The interface can show the validated aggregation and returned rows, so users do not have to trust a fluent sentence without seeing how it was produced.
An informal comparison with AskCricinfo
Before building the MongoDB edition, I ran a small side-by-side experiment with ESPNcricinfo's AskCricinfo.
I asked both tools two questions:
- βWhich player has hit the maximum number of sixes in an innings in Test cricket?β
- βHow many five-fers has Ashwin taken in Tests?β
In those two spot checks, CricketStats produced the results I judged more useful from the available data. The important difference was not simply the answer text: CricketStats exposed the generated query and made it possible to trace the result back to structured innings records.
This was an informal comparison performed, not a controlled benchmark or a claim that CricketStats is generally more accurate than AskCricinfo. The dataset has also continued to evolve since then. I include it because it helped clarify the product's niche: transparent, locally operated cricket research where the query, filters, aggregation level, and source rows can be inspected.
Current boundaries
CricketStats is a research assistant, not an official scoring authority. A generated pipeline can still be logically wrong, incomplete source data can produce incomplete answers, and historical names or venues may need correction. The local setup also assumes a machine capable of running a 14-billion-parameter model.
Those limitations are visible. Users can inspect the pipeline and result rows, run direct MongoDB checks, and enable tracing when an answer needs investigation. If a plan fails validation, the application reports the error rather than manufacturing an answer.
Why Does Open Innovation Matter?
Open innovation changes both the economics and trust model of this project.
First, inference can run locally. A journalist's unpublished research questions and story ideas do not need to go to an external model API. MongoDB Community and Ollama can both remain bound to localhost.
Second, there is no per-question model API charge. That matters for a small specialist product: a researcher can ask many exploratory questions without turning each attempt into a metered expense. The user still provides hardware and electricity, so βlocalβ does not mean cost-free.
Third, the model is replaceable. Qwen works well for structured plans, but the application is not locked to one hosted AI provider. I can compare another open-weight model, use a different quantization, or eventually fine-tune on reviewed cricket question-to-pipeline examples.
Most importantly, the reasoning boundary is inspectable. The source exposes the prompt, deterministic rules, validator, aggregation plan, migration logic, and verification process. A developer can change the rules, test another model, point the application at local MongoDB or Atlas, and verify an answer directly against the data.
The trade-offs are visible too: local inference requires capable hardware, model downloads are large, and a convincing aggregation may still encode the wrong cricket interpretation. Qwen, deterministic safeguards, MongoDB, and human review work together; none is presented as infallible.
My next commercial experiment would be to give the assistant to cricket writers and analysts, measure how much research time it saves, collect the questions it gets wrong, and ask whether private setup, support, or custom reports are valuable enough to purchase.
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.