SQL to MongoDB

Last updated: March 19, 2026

SQL to MongoDB Converter

Convert SQL queries to MongoDB query syntax. Translates SELECT, WHERE, ORDER BY, GROUP BY, and JOIN operations into equivalent MongoDB find(), aggregate(), and lookup operations.

Basic Conversions

  • SELECT: Becomes projection in find() or $project in aggregate
  • WHERE: Becomes filter object in find() or $match
  • ORDER BY: Becomes sort() or $sort
  • LIMIT: Becomes limit() or $limit
  • GROUP BY: Becomes $group in aggregate pipeline

SQL WHERE to MongoDB Filter

  • WHERE age > 25: {age: {$gt: 25}}
  • WHERE name = 'John': {name: "John"}
  • WHERE age IN (25, 30): {age: {$in: [25, 30]}}
  • WHERE name LIKE '%john%': {name: /john/i}

When to Use

  • Migrating from SQL to MongoDB databases
  • Learning MongoDB query syntax from SQL knowledge
  • Quick reference for SQL-experienced developers

Key Differences

MongoDB does not have traditional JOINs (use $lookup for similar functionality). No schema enforcement by default (use validators if needed). Embedded documents replace many JOIN scenarios.

When Your Brain Still Thinks in SQL but Your Database Is MongoDB

There is a specific kind of frustration that hits every backend developer around week two of working with MongoDB for the first time. You know exactly what data you need. You can write the SQL in your sleep — a straightforward SELECT with a WHERE clause, maybe a GROUP BY for a count. But the moment you open a MongoDB shell, the syntax feels like a foreign alphabet. That gap is precisely what SQL-to-MongoDB converter tools exist to bridge.

These tools are not migration utilities in the heavy sense — they do not move data from PostgreSQL to Atlas or replicate schemas. Their job is narrower and, for the right use case, enormously useful: paste a SQL query, get back syntactically correct MongoDB shell code you can actually run. What separates the good ones from the frustrating ones is how far they handle the structural mismatch between a relational query model and a document model.

What the Conversion Actually Looks Like

The simplest case is almost too clean. Take a basic SELECT:

SELECT name, age FROM users WHERE age > 21 ORDER BY age DESC LIMIT 10

A solid converter — MiniWebtool's SQL to MongoDB Query Converter handles this well — produces:

db.users.find({ age: { $gt: 21 } }, { name: 1, age: 1, _id: 0 }).sort({ age: -1 }).limit(10)

Three things worth noticing here. First, the projection suppresses _id explicitly — that is correct behavior, because MongoDB returns _id by default even when you name specific fields. Tools that miss this generate subtly wrong output that breaks strict schema validation. Second, ORDER BY age DESC maps to .sort({ age: -1 }), which is the right direction encoding. Third, LIMIT 10 chains cleanly. These are not hard problems, but the details matter when you paste the output straight into mongosh.

The WHERE clause is where tools diverge quickly. AND conditions stay simple — they become sibling keys in the filter document. But OR logic requires $or, and nested AND/OR combinations demand careful parenthesis handling. A query like:

SELECT * FROM orders WHERE status = 'pending' OR (total > 500 AND region = 'west')

should produce a $or array where the second element is its own document with both conditions — not a flat structure. Tools like Site24x7's converter and the sql2mongodb.com tool handle this differently, and the difference only shows up with mixed-operator queries that you actually care about in production.

INSERT, UPDATE, DELETE — The Less Glamorous Conversions

Most developers reach for these tools when they are writing query logic, but the DML statements reveal a tool's depth. An INSERT INTO people(user_id, age, status) VALUES ('bcd001', 45, 'A') should become db.people.insertOne({ user_id: "bcd001", age: 45, status: "A" }). The MongoDB docs themselves use this exact mapping in their SQL comparison chart.

UPDATE is more interesting. SQL's UPDATE people SET status = 'C' WHERE age > 25 needs to become db.people.updateMany({ age: { $gt: 25 } }, { $set: { status: "C" } }). The $set operator is non-negotiable — omitting it means replacing the entire document with just { status: "C" }, which would destroy every other field. Good converters always wrap the update payload in $set. Some weaker tools do not, which turns a routine update into a silent data wipe.

For DELETE FROM people WHERE status = 'D', the correct output is db.people.deleteMany({ status: "D" }). The distinction between deleteOne and deleteMany matters enormously, and most converters default to deleteMany — the safer interpretation for a SQL DELETE with a WHERE clause.

GROUP BY and Aggregation Pipelines: Where Things Get Real

This is the test that separates functional tools from genuinely useful ones. SQL aggregation is declarative and compact. MongoDB's aggregation pipeline is powerful but verbose. Converting:

SELECT status, COUNT(*) as total FROM users GROUP BY status HAVING COUNT(*) > 5

requires generating a multi-stage pipeline:

db.users.aggregate([
  { $group: { _id: "$status", total: { $sum: 1 } } },
  { $match: { total: { $gt: 5 } } }
])

Two things matter here. First, HAVING must come after $group as a separate $match stage — you cannot filter on an aggregated field in the same stage that creates it. Second, the field reference inside $group requires the $ prefix on "$status", which is MongoDB's way of saying "this is a field reference, not a literal string." MiniWebtool's converter handles stage ordering correctly. Simpler tools often flatten the pipeline or misplace the $match.

LIKE pattern matching is another aggregation-adjacent case worth testing. WHERE user_id LIKE '%bc%' translates to { user_id: /bc/ } — a JavaScript regex literal. The percent wildcard maps to .* in regex terms, and the single-character wildcard _ maps to .. Leading wildcards like LIKE '%term' prevent index use in MongoDB just as they do in SQL, which no converter mentions but every production developer eventually learns the hard way.

The JOIN Problem — and Why Converters Cannot Fully Solve It

Here is the honest answer: no lightweight online converter handles JOINs well, and most simply do not support them at all. That is not a criticism — it reflects a genuine architectural gap. SQL JOINs assume normalized tables. MongoDB's document model assumes you either embed related data or use $lookup in an aggregation pipeline.

Devkitr's SQL-to-MongoDB converter is one of the few that attempts JOIN conversion, generating multi-stage $lookup pipelines. For a simple two-table join on a foreign key:

SELECT orders.id, users.name FROM orders JOIN users ON orders.user_id = users.id

it produces something like:

db.orders.aggregate([
  {
    $lookup: {
      from: "users",
      localField: "user_id",
      foreignField: "_id",
      as: "user_data"
    }
  },
  { $project: { id: 1, "user_data.name": 1 } }
])

That is syntactically valid. But whether it is correct for your actual schema depends entirely on whether your MongoDB documents use user_id as a reference field and whether your users collection uses _id as the join target. The converter assumes column names map directly to field names — which is often true after a migration but requires verification. Multi-table JOINs get exponentially messier, and at that point you are better off reading the MongoDB docs on $lookup directly.

Output Format Choices: Shell vs. Driver vs. ORM

One underappreciated difference between tools is what they actually output. The MongoDB shell syntax (db.collection.find(...)) is useful for testing in mongosh but is not what application code looks like. Devkitr's converter offers three output targets: MongoDB shell syntax, Node.js driver code using the official mongodb npm package, and Mongoose ORM syntax.

That last option — Mongoose — is worth pausing on. Mongoose adds a schema layer and uses slightly different method signatures. Model.find() instead of db.collection.find(), callback-or-promise patterns, and model-level middleware are all Mongoose concerns that raw shell output ignores. For teams building Express/Node applications with Mongoose, having Mongoose-specific output saves a translation step that is easy to get wrong under deadline pressure.

What These Tools Do Not Tell You About Data Types

Every converter sidesteps one category of problem: types. In SQL, a column's type is declared at the schema level. MongoDB's BSON has its own type system — and some types, like ObjectId and Date, have no SQL analogs that converters can reliably infer from query syntax alone.

When your SQL query filters on a primary key:

SELECT * FROM users WHERE id = 507f1f77bcf86cd799439011

a converter might produce { id: "507f1f77bcf86cd799439011" } — a string. But if that field is actually stored as an ObjectId, the correct MongoDB filter is { _id: ObjectId("507f1f77bcf86cd799439011") }. No automatic converter can know this without access to your actual schema, so every piece of output involving ID fields or date comparisons needs a manual review pass before it touches production.

The Honest Use Case

SQL-to-MongoDB tools are most valuable in two specific situations: learning MongoDB syntax when you already know SQL, and doing a quick sanity-check on simple query translations during an early-stage migration. They are not production-grade migration tools, and the better ones say as much. For learning, MiniWebtool's clause-by-clause mapping table — which shows exactly which SQL keyword became which MongoDB operator — is genuinely instructive. For quick translation of known-simple queries, Site24x7's converter handles the common cases with minimal friction.

For complex queries involving subqueries, CTEs, window functions, or deeply nested JOINs, the right tool is not a browser-based converter at all — it is MongoDB's Relational Migrator, which uses an AI model aware of your actual schema and generates tested code rather than syntactic approximations.

The mental model shift from relational to document databases is real, and no converter tool eliminates it. What these tools do is give you a working starting point that reads like the pattern you are trying to learn — and for developers making that transition, that starting point is worth quite a bit.

Disclaimer: This article is for general informational and educational purposes only and does not constitute professional, financial, medical, or legal advice. Results from any tool are estimates based on the inputs provided. Always verify important details and consult a qualified professional before making decisions.