{"id":17369,"date":"2025-07-25T10:09:07","date_gmt":"2025-07-25T17:09:07","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=17369"},"modified":"2025-08-13T06:52:59","modified_gmt":"2025-08-13T13:52:59","slug":"choosing-the-right-query-language-sql-vs-mongo","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/","title":{"rendered":"Choosing the Right Query Language: SQL++ vs. Mongo"},"content":{"rendered":"<p>When you\u2019re building apps, the query language you work with makes a big difference. It affects everything from performance to how quickly your team can ship features. In this post, I\u2019ve asked an LLM to create a list of 21 ranked criteria that are most valuable when deciding which query language to use. We\u2019ll walk through each one and show how SQL++, used by Couchbase, and Mongo\u2019s Query API (previously known as MQL) languages stack up.<\/p>\n<p>Whether you\u2019re evaluating databases for a new project, or just curious about the differences between these two approaches, this should give you a clear picture of where each one shines and where it might fall short.<\/p>\n<h2 style=\"font-weight: 400;\">Expressiveness<\/h2>\n<p>SQL++ lets you write rich, complex queries\u2014joins, subqueries, aggregates, window functions\u2014while working with flexible document data. You can express nearly anything you\u2019d expect in SQL, plus native support for JSON.<\/p>\n<p>Mongo\u2019s query language is more limited. You can do a lot with the aggregation pipeline, but expressing multi-collection joins or deep subqueries can become verbose and may require workarounds or advanced pipeline constructs.<\/p>\n<table>\n<tbody>\n<tr>\n<th><strong>SQL++<\/strong><\/th>\n<th><strong>Mongo<\/strong><\/th>\n<\/tr>\n<tr>\n<td>\n<pre>SELECT c.name, o.total\r\nFROM customers c\r\nJOIN orders o ON c.id = o.customer_id\r\nWHERE o.total &gt; 100\r\nORDER BY o.total DESC;<\/pre>\n<\/td>\n<td>Mongo requires a more procedural pipeline:<\/p>\n<pre class=\"\">db.orders.aggregate([\r\n\u00a0 { $match: { total: { $gt: 100 } } },\r\n\u00a0 { $lookup: {\r\n\u00a0 \u00a0 \u00a0 from: \"customers\",\r\n\u00a0 \u00a0 \u00a0 localField: \"customer_id\",\r\n\u00a0 \u00a0 \u00a0 foreignField: \"id\",\r\n\u00a0 \u00a0 \u00a0 as: \"customer\"\r\n\u00a0 \u00a0 }\r\n\u00a0 },\r\n\u00a0 { $unwind: \"$customer\" },\r\n\u00a0 { $project: { name: \"$customer.name\", total: 1 } },\r\n\u00a0 { $sort: { total: -1 } }\r\n]);\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2 style=\"font-weight: 400;\">Readability<\/h2>\n<p>SQL++ is declarative and familiar to anyone with SQL experience. The intent of the query is easy to see.<\/p>\n<pre>SELECT name, age\r\nFROM users\r\nWHERE age &gt;= 21\r\nORDER BY name;\r\n<\/pre>\n<p>Mongo\u2019s pipeline is more verbose and procedural\u2014you have to mentally step through each stage.<\/p>\n<pre>db.users.find(\r\n\u00a0 { age: { $gte: 21 } },\r\n\u00a0 { name: 1, age: 1, _id: 0 }\r\n).sort({ name: 1 });\r\n<\/pre>\n<p>For simple queries this isn\u2019t <b>terrible<\/b>. But as queries grow (joins, subqueries, aggregations), readability can drop quickly in Mongo\u2019s pipeline format.<\/p>\n<h2 style=\"font-weight: 400;\">Consistency<\/h2>\n<p>SQL++ is highly consistent. The syntax and semantics are predictable, and it feels like &#8220;SQL for documents&#8221; across the board.<\/p>\n<p>Example with nested data:<\/p>\n<pre>SELECT u.name, a.city\r\nFROM users u\r\nUNNEST u.addresses AS a\r\nWHERE a.country = \"USA\";\r\n<\/pre>\n<p>In Mongo, querying nested structures often requires switching to dot notation or array operators, and pipelines use a different style than <em>find()<\/em>. You end up learning multiple syntaxes:<\/p>\n<p>Simple query with dot notation:<\/p>\n<pre>db.users.find(\r\n\u00a0 { \"addresses.country\": \"USA\" },\r\n\u00a0 { name: 1, \"addresses.city\": 1, _id: 0 }\r\n);\r\n<\/pre>\n<p>More complex? You\u2019re back in aggregation-land:<\/p>\n<pre>db.users.aggregate([\r\n\u00a0 { $unwind: \"$addresses\" },\r\n\u00a0 { $match: { \"addresses.country\": \"USA\" } },\r\n\u00a0 { $project: { name: 1, city: \"$addresses.city\", _id: 0 } }\r\n]);\r\n<\/pre>\n<h2 style=\"font-weight: 400;\">Performance<\/h2>\n<p>When it comes to raw performance, Couchbase SQL++ consistently outpaces MongoDB\u2019s query language in benchmarks, especially under high-throughput, low-latency workloads.<\/p>\n<p>Couchbase has demonstrated superior scalability and efficiency in various benchmarks. For instance, in the Yahoo! Cloud Serving Benchmark (YCSB), Couchbase exhibited <a href=\"https:\/\/www.couchbase.com\/benchmarks\/\" target=\"_blank\" rel=\"noopener\">significantly better performance at scale\u2014up<\/a> compared to MongoDB.<\/p>\n<p>Beyond benchmarks, Couchbase customers have reported significant performance improvements:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><a href=\"https:\/\/www.couchbase.com\/customers\/fico\/\" target=\"_blank\" rel=\"noopener\">FICO chose Couchbase over MongoDB<\/a> to achieve &lt;1ms response time<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><a href=\"https:\/\/www.couchbase.com\/customers\/linkedin\/\" target=\"_blank\" rel=\"noopener\">LinkedIn chose Couchbase over MongoDB<\/a> to execute 10m+ queries per second<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>MongoDB\u2019s latest release, while improving over its previous versions, still lags behind in certain scenarios. MongoDB 8.0 introduced performance enhancements, achieving faster mixed read\/write workloads compared to MongoDB 7.0. However, these improvements are relative to its own prior performance and may not match the scalability and speed demonstrated by Couchbase in independent benchmarks (like the <a href=\"https:\/\/benchant.com\/ranking\/database-ranking\" target=\"_blank\" rel=\"noopener\">BenchANT Database Ranking<\/a>).<\/p>\n<h2 style=\"font-weight: 400;\">Index Support<\/h2>\n<p>SQL++ supports a <a href=\"https:\/\/www.couchbase.com\/blog\/create-right-index-get-right-performance\/\" target=\"_blank\" rel=\"noopener\">broad set of indexes<\/a>: primary, secondary, composite, array, partial, covering, FTS\u2014all usable from a single language.<\/p>\n<p>Mongo supports primary (<em>on _id<\/em>), secondary, compound, multikey, text, and hashed indexes. It\u2019s strong, but lacks some of the flexibility of SQL++ when it comes to indexing deeply nested fields or expressions.<\/p>\n<p>Example with partial index in SQL++:<\/p>\n<pre>CREATE INDEX idx_active_users ON users(email)\r\nWHERE active = TRUE;\r\n<\/pre>\n<p>Mongo partial index is similar:<\/p>\n<pre>db.users.createIndex(\r\n\u00a0 { email: 1 },\r\n\u00a0 { partialFilterExpression: { active: true } }\r\n);\r\n<\/pre>\n<h2 style=\"font-weight: 400;\">Join Capabilities<\/h2>\n<p>SQL++ supports full JOIN syntax\u2014inner, left outer, <em>UNNEST<\/em>, and combinations. It treats documents as first-class citizens in relational-style queries.<\/p>\n<p>Example:<\/p>\n<pre>SELECT u.name, o.total\r\nFROM users u\r\nJOIN orders o ON u.id = o.user_id\r\nWHERE o.total &gt; 100;\r\n<\/pre>\n<p>Mongo\u2019s <em>$lookup<\/em> supports more expressive pipelines since 5.0, but is still <em>LEFT OUTER<\/em> and lacks full join syntax.<\/p>\n<pre>db.orders.aggregate([\r\n\u00a0 { $match: { total: { $gt: 100 } } },\r\n\u00a0 { $lookup: {\r\n\u00a0 \u00a0 \u00a0 from: \"users\",\r\n\u00a0 \u00a0 \u00a0 localField: \"user_id\",\r\n\u00a0 \u00a0 \u00a0 foreignField: \"id\",\r\n\u00a0 \u00a0 \u00a0 as: \"user\"\r\n\u00a0 \u00a0 }\r\n\u00a0 },\r\n\u00a0 { $unwind: \"$user\" },\r\n\u00a0 { $project: { name: \"$user.name\", total: 1 } }\r\n]);\r\n<\/pre>\n<p>SQL++ also supports multiple joins and joins on expressions\u2014Mongo\u2019s <em>$lookup<\/em> is more limited in comparison.<\/p>\n<h2 style=\"font-weight: 400;\">Aggregation Support<\/h2>\n<p>SQL++ has full GROUP BY, HAVING, window functions, and flexible expressions\u2014just like standard SQL.<\/p>\n<p>Example:<\/p>\n<pre>SELECT department, AVG(salary) AS avg_salary\r\nFROM employees\r\nGROUP BY department\r\nHAVING avg_salary &gt; 75000;\r\n<\/pre>\n<p>Mongo\u2019s aggregation pipeline is capable, but more procedural. You chain stages like <em>$group<\/em>, <em>$match<\/em>, <em>$project<\/em>, etc.:<\/p>\n<pre>db.employees.aggregate([\r\n\u00a0 { $group: { _id: \"$department\", avg_salary: { $avg: \"$salary\" } } },\r\n\u00a0 { $match: { avg_salary: { $gt: 75000 } } }\r\n]);\r\n<\/pre>\n<p>Both are powerful, but SQL++ is typically more concise and familiar for SQL users, and supports features like <a href=\"https:\/\/docs.couchbase.com\/cloud\/n1ql\/n1ql-language-reference\/windowfun.html\" target=\"_blank\" rel=\"noopener\">window functions<\/a> that Mongo\u2019s pipeline lacks.<\/p>\n<h2 style=\"font-weight: 400;\">Filtering and Predicate Logic<\/h2>\n<p>SQL++ has full support for complex filtering with <em>AND<\/em>, <em>OR<\/em>, <em>NOT<\/em>, <em>BETWEEN<\/em>, <em>IN<\/em>, subqueries, and arbitrary expressions.<\/p>\n<p>Example:<\/p>\n<pre>SELECT name\r\nFROM users\r\nWHERE (age BETWEEN 21 AND 65)\r\n\u00a0 AND (email LIKE \"%@example.com\")\r\n\u00a0 AND (status IN [\"active\", \"pending\"]);\r\n<\/pre>\n<p>Mongo supports filtering in <em>find()<\/em> and in <em>$match<\/em> stages, but the syntax is more verbose and JSON-based:<\/p>\n<pre>db.users.find({\r\n\u00a0 age: { $gte: 21, $lte: 65 },\r\n\u00a0 email: { $regex: \"@example\\\\.com$\" },\r\n\u00a0 status: { $in: [\"active\", \"pending\"] }\r\n});\r\n<\/pre>\n<p>Both can express complex predicates, but SQL++ tends to be more readable for highly complex boolean logic.<\/p>\n<h2 style=\"font-weight: 400;\">Subquery Support<\/h2>\n<p>SQL++ supports full subqueries: correlated, uncorrelated, scalar, <em>EXISTS<\/em>\/<em>NOT EXISTS<\/em>\u2014all the patterns you\u2019d expect.<\/p>\n<p>Example:<\/p>\n<pre>SELECT name\r\nFROM users u\r\nWHERE EXISTS (\r\n\u00a0 SELECT 1 FROM orders o\r\n\u00a0 WHERE o.user_id = u.id AND o.total &gt; 100\r\n);\r\n<\/pre>\n<p>Mongo doesn\u2019t support subqueries in the same way. You generally have to rewrite using <em>$lookup<\/em>, <em>$facet<\/em>, or multiple queries in application code. This is one area where SQL++ is much stronger and more natural.<\/p>\n<h2 style=\"font-weight: 400;\">Data Manipulation Support<\/h2>\n<p>SQL++ supports full <em>INSERT<\/em>, <em>UPDATE<\/em>, <em>DELETE<\/em>, <em>MERGE<\/em> \u2014 all standard data manipulation operations.<\/p>\n<p>Example <em>UPDATE<\/em>:<\/p>\n<pre>UPDATE users\r\nSET status = \"inactive\"\r\nWHERE last_login &lt; \"2024-01-01\";\r\n<\/pre>\n<p>Mongo also supports data manipulation via <em>insertOne<\/em>, <em>insertMany<\/em>, <em>updateOne<\/em>, <em>updateMany<\/em>, <em>deleteOne<\/em>, <em>deleteMany<\/em>, and <em>replaceOne<\/em>. The functionality is solid, but operations are separate API calls\u2014not unified under one query language.<\/p>\n<p>Example update:<\/p>\n<pre>db.users.updateMany(\r\n\u00a0 { last_login: { $lt: new Date(\"2024-01-01\") } },\r\n\u00a0 { $set: { status: \"inactive\" } }\r\n);\r\n<\/pre>\n<p>Both are capable, but SQL++ provides a single, consistent language for both querying and modifying data.<\/p>\n<h2 style=\"font-weight: 400;\">Transactions Support<\/h2>\n<p>SQL++ supports multi-statement ACID transactions (with Couchbase\u2019s <em>BEGIN TRANSACTION<\/em>, <em>COMMIT<\/em>, <em>ROLLBACK<\/em>), and transactions can span multiple documents, collections, and even multiple statements.<\/p>\n<p>Example:<\/p>\n<pre>BEGIN TRANSACTION;\r\nUPDATE accounts SET balance = balance - 100 WHERE id = \"user123\";\r\nUPDATE accounts SET balance = balance + 100 WHERE id = \"user456\";\r\nCOMMIT;\r\n<\/pre>\n<p>Mongo introduced multi-document ACID transactions in version 4.0. They are supported, but must be initiated from drivers using a session object, or mongosh, not part of the Mongo query language itself.<\/p>\n<p>Example (driver-based in Node.js):<\/p>\n<pre>const session = client.startSession();\r\nsession.startTransaction();\r\ntry {\r\n\u00a0 db.accounts.updateOne({ id: \"user123\" }, { $inc: { balance: -100 } }, { session });\r\n\u00a0 db.accounts.updateOne({ id: \"user456\" }, { $inc: { balance: 100 } }, { session });\r\n\u00a0 await session.commitTransaction();\r\n} catch (error) {\r\n\u00a0 await session.abortTransaction();\r\n}\r\nsession.endSession();\r\n<\/pre>\n<p>Summary: Both support ACID transactions, but SQL++ lets you express them declaratively inside the query language itself, which is easier and clearer.<\/p>\n<h2 style=\"font-weight: 400;\">Error Handling<\/h2>\n<p>SQL++ surfaces structured error codes and messages to the client when a query fails \u2014 these are accessible through the SDKs and query metadata. You can also write queries defensively (e.g. IF EXISTS, IF MISSING, CASE expressions) to control behavior.<\/p>\n<p>Example (defensive logic):<\/p>\n<pre>UPDATE users\r\nSET last_login = CURRENT_TIMESTAMP\r\nWHERE user_id = \"user123\"\r\nAND last_login IS NOT MISSING;\r\n<\/pre>\n<p>Error codes are documented here: <a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/n1ql-error-codes.html\" target=\"_blank\" rel=\"noopener\">Couchbase SQL++ Error Codes<\/a>.<\/p>\n<p>Mongo also relies on driver-level error handling \u2014 errors are raised to the client when queries or commands fail. Mongo\u2019s aggregation pipeline does not support in-query error handling either.<\/p>\n<p>Example (Mongo defensive update):<\/p>\n<pre>db.users.updateOne(\r\n\u00a0 { user_id: \"user123\", last_login: { $exists: true } },\r\n\u00a0 { $set: { last_login: new Date() } }\r\n);\r\n<\/pre>\n<p>Summary: Both SQL++ and Mongo rely on external (driver-level) error handling. You can use defensive query patterns to mitigate common errors.<\/p>\n<h2 style=\"font-weight: 400;\">Extensibility<\/h2>\n<p>SQL++ allows user-defined functions (UDFs) written in SQL++ itself. These can encapsulate complex logic, reuse expressions, and simplify queries.<\/p>\n<p>Example UDF:<\/p>\n<pre>CREATE FUNCTION get_discount(total FLOAT)\r\nRETURNS FLOAT\r\nAS\r\n\u00a0 CASE WHEN total &gt; 500 THEN 0.10\r\n \u00a0 \u00a0 \u00a0 WHEN total &gt; 100 THEN 0.05\r\n \u00a0 \u00a0 \u00a0 ELSE 0.0\r\n\u00a0 END;\r\n<\/pre>\n<p>Usage:<\/p>\n<pre>SELECT customer_id, total, get_discount(total) AS discount\r\nFROM orders;\r\n<\/pre>\n<p>Mongo has no in-query UDFs in its query language or aggregation pipeline. You can use <em>$function<\/em> (introduced in MongoDB 4.4), which lets you run JavaScript functions inside aggregation \u2014 but this is less efficient and limited in portability:<\/p>\n<pre>db.orders.aggregate([\r\n\u00a0 {\r\n\u00a0 \u00a0 $addFields: {\r\n\u00a0 \u00a0 \u00a0 discount: {\r\n\u00a0 \u00a0 \u00a0 \u00a0 $function: {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 body: function(total) {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 if (total &gt; 500) return 0.10;\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 if (total &gt; 100) return 0.05;\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 return 0.0;\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 },\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 args: [\"$total\"],\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 lang: \"js\"\r\n\u00a0 \u00a0 \u00a0 \u00a0 }\r\n\u00a0 \u00a0 \u00a0 }\r\n\u00a0 \u00a0 }\r\n\u00a0 }\r\n]);\r\n<\/pre>\n<p>Summary: SQL++ UDFs are native, efficient, and portable; Mongo\u2019s <em>$function<\/em> uses JavaScript and may have performance trade-offs.<\/p>\n<h2 style=\"font-weight: 400;\">Declarative Nature<\/h2>\n<p>SQL++ is fully declarative \u2014 you express what you want, not how to compute it. You rely on the query optimizer to determine the best execution plan. This makes queries simpler to write and maintain.<\/p>\n<p>Mongo\u2019s aggregation pipeline is more procedural \u2014 you specify the exact sequence of operations (<em>$match<\/em>, <em>$group<\/em>, <em>$project<\/em>, <em>$sort<\/em>, etc.). For complex logic, this often requires thinking in terms of data flow, not desired result.<\/p>\n<h2 style=\"font-weight: 400;\">Portability<\/h2>\n<p>SQL++ is based on SQL with JSON extensions. If you know SQL, it\u2019s easy to learn SQL++, and much of your knowledge carries over. The language is also designed to be portable across Couchbase deployments \u2014 cloud, self-managed, edge.<\/p>\n<p>Mongo\u2019s query language is specific to MongoDB. Its syntax is JSON-based, not SQL-like, and most of it doesn\u2019t transfer to other databases. While it\u2019s great inside the Mongo ecosystem, it\u2019s harder to port to systems like relational databases, Couchbase, or cloud data warehouses.<\/p>\n<h2 style=\"font-weight: 400;\">Pagination Support<\/h2>\n<p>SQL++ supports pagination using <em>LIMIT<\/em> and <em>OFFSET<\/em> \u2014 standard SQL-style:<\/p>\n<pre>SELECT name\r\nFROM users\r\nORDER BY name\r\nLIMIT 10 OFFSET 20;\r\n<\/pre>\n<p>Mongo also supports pagination with <em>.limit()<\/em> and <em>.skip()<\/em>:<\/p>\n<pre>db.users.find({})\r\n\u00a0 .sort({ name: 1 })\r\n\u00a0 .skip(20)\r\n\u00a0 .limit(10);\r\n<\/pre>\n<p>Both handle basic pagination well.<\/p>\n<p>However \u2014 SQL++ also supports window functions (e.g. <em>ROW_NUMBER() OVER (\u2026\u200b)<\/em>), which allows for more advanced pagination and cursor-based patterns, whereas Mongo requires additional pipeline stages or application logic to simulate those.<\/p>\n<h2 style=\"font-weight: 400;\">Schema Introspection<\/h2>\n<p>SQL++ \/ Couchbase supports automatic schema discovery via the <em>INFER<\/em> command. Since Couchbase is schema-flexible, <em>INFER<\/em> lets you analyze documents in a collection and generate a probabilistic schema \u2014 showing what fields exist, their types, nesting, and occurrence percentages.<\/p>\n<p>Example:<\/p>\n<pre>INFER `travel-sample`.inventory.airline WITH { \"sample_size\": 1000 };\r\n<\/pre>\n<p>Returns information about the airline collection, including field names, types, and occurrence percentages:<\/p>\n<pre>[\r\n\u00a0 [\r\n\u00a0 \u00a0 {\r\n\u00a0 \u00a0 \u00a0 \"#docs\": 187,\r\n\u00a0 \u00a0 \u00a0 \"$schema\": \"https:\/\/json-schema.org\/draft-06\/schema\",\r\n\u00a0 \u00a0 \u00a0 \"Flavor\": \"`type` = \\\"airline\\\"\",\r\n\u00a0 \u00a0 \u00a0 \"properties\": {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \"callsign\": { ... }, \"country\": { ... }, \"name\": { ... }, ...\r\n\u00a0 \u00a0 \u00a0 },\r\n\u00a0 \u00a0 \u00a0 \"type\": \"object\"\r\n\u00a0 \u00a0 }\r\n\u00a0 ]\r\n]\r\n<\/pre>\n<p>Mongo has no direct query language equivalent to <em>INFER<\/em>, though MongoDB Atlas offers Schema Explorer in the UI.<\/p>\n<p>Closest options:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><em>db.collection.aggregate([ { $sample: { size: N } } ]) + manual inspection<\/em><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\">Third-party tools<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h2 style=\"font-weight: 400;\">Tooling and IDE Support<\/h2>\n<p>SQL++ is supported in:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\">Couchbase Web UI Query Workbench<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\">VS Code SQL++ extension<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\">JetBrains IDEs (plugin)<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\">REST API \/ CLI<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\">Couchbase Shell<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Mongo\u2019s tooling includes:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\">MongoDB Compass (GUI)<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\">Mongo Shell \/ mongosh<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\">MongoDB Atlas UI<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\">VS Code MongoDB extension<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>There are other tools as well. Both have good tooling. SQL++ integrates better with SQL-friendly tools (DataGrip, BI tools, etc.). Mongo tools are more Mongo-specific.<\/p>\n<h2 style=\"font-weight: 400;\">Community and Documentation<\/h2>\n<p>SQL++ \/ Couchbase:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\">Official Docs: <a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-language-reference\/index.html\" target=\"_blank\" rel=\"noopener\">Couchbase SQL++ Reference<\/a><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\">Active Couchbase developer community<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\">Blogs, forums, Stack Overflow, Discord<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\">SQL++ is based on familiar SQL, so existing SQL resources also apply<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Mongo:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\">Official Docs: MongoDB Query Language Reference<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\">Large community<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\">Many tutorials, courses, books<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\">Heavily used in web dev \/ JavaScript communities<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Mongo has a bigger community (simply due to broader adoption), but SQL++ benefits from SQL familiarity and an increasingly active Couchbase developer ecosystem.<\/p>\n<h2 style=\"font-weight: 400;\">Integration with App Frameworks<\/h2>\n<p>SQL++ \/ Couchbase is supported via:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\">SDKs in major languages: Java, .NET (C#), Node.js, Python, Go, C++, Scala<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\">ODBC \/ JDBC drivers \u2192 works with BI tools (Tableau, Power BI, Excel, Looker)<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\">REST API<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\">A growing ecosystem of <a href=\"https:\/\/www.couchbase.com\/developers\/integrations\/\" target=\"_blank\" rel=\"noopener\">integrations<\/a>, including Spring Data, EF Core, Quarkus, and more<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Mongo has:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\">Official drivers for nearly every major language<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\">Strong ecosystem for developers<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Mongo has a larger ecosystem, but SQL++ is more familiar to SQL developers in general.<\/p>\n<h2 style=\"font-weight: 400;\">Standards Compliance<\/h2>\n<p>SQL++ is a SQL-derived language:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\">Based on ANSI SQL with extensions for JSON documents, arrays, nesting<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\">You can take standard SQL skills and use them right away<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\">Many existing SQL-based tools and patterns apply<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Mongo&#8217;s query language is non-standard:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\">Based on JSON syntax and operators<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\">No direct mapping to ANSI SQL<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\">Requires learning Mongo-specific query patterns<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>If you want SQL compatibility and standards alignment, look to SQL++. If you\u2019re fine with a Mongo-specific language, Mongo\u2019s approach works, but is harder to port.<\/p>\n<hr \/>\n<h2 style=\"font-weight: 400;\">Summary<\/h2>\n<p>SQL++ is a natural fit for developers familiar with SQL. It\u2019s a superset of SQL, so existing SQL knowledge carries over.<\/p>\n<p>MongoDB\u2019s query language is more specialized and procedural, which can be powerful but also requires a different mindset.<\/p>\n<p>Here\u2019s the complete criteria listing:<\/p>\n<table>\n<tbody>\n<tr>\n<td><strong>Rank<\/strong><\/td>\n<td><strong>Name of Criteria<\/strong><\/td>\n<td><strong>How to Apply It<\/strong><\/td>\n<td><strong>Why It\u2019s Important<\/strong><\/td>\n<\/tr>\n<tr>\n<td>1<\/td>\n<td>Expressiveness<\/td>\n<td>Assess how many types of queries can be written<\/td>\n<td>Determines flexibility in handling data tasks<\/td>\n<\/tr>\n<tr>\n<td>2<\/td>\n<td>Readability<\/td>\n<td>Review sample queries for clarity<\/td>\n<td>Impacts learning curve and maintenance<\/td>\n<\/tr>\n<tr>\n<td>3<\/td>\n<td>Consistency<\/td>\n<td>Look for consistent syntax and semantics<\/td>\n<td>Reduces bugs and surprises<\/td>\n<\/tr>\n<tr>\n<td>4<\/td>\n<td>Performance<\/td>\n<td>Benchmark query execution on real workloads<\/td>\n<td>Affects speed and scalability<\/td>\n<\/tr>\n<tr>\n<td>5<\/td>\n<td>Index Support<\/td>\n<td>Check range of index types and usage options<\/td>\n<td>Critical for optimizing query speed<\/td>\n<\/tr>\n<tr>\n<td>6<\/td>\n<td>Join Capabilities<\/td>\n<td>Test support for different join types<\/td>\n<td>Key for working with related data<\/td>\n<\/tr>\n<tr>\n<td>7<\/td>\n<td>Aggregation Support<\/td>\n<td>Evaluate support for grouping and aggregation<\/td>\n<td>Necessary for analytics and reporting<\/td>\n<\/tr>\n<tr>\n<td>8<\/td>\n<td>Filtering and Predicate Logic<\/td>\n<td>Test complex WHERE and HAVING clauses<\/td>\n<td>Enables precise data retrieval<\/td>\n<\/tr>\n<tr>\n<td>9<\/td>\n<td>Subquery Support<\/td>\n<td>Verify support for correlated and nested subqueries<\/td>\n<td>Adds depth to querying<\/td>\n<\/tr>\n<tr>\n<td>10<\/td>\n<td>Data Manipulation Support<\/td>\n<td>Test INSERT, UPDATE, DELETE, MERGE functionality<\/td>\n<td>Important for data maintenance<\/td>\n<\/tr>\n<tr>\n<td>11<\/td>\n<td>Transactions Support<\/td>\n<td>Check support for multi-statement transactions<\/td>\n<td>Ensures data consistency and atomicity<\/td>\n<\/tr>\n<tr>\n<td>12<\/td>\n<td>Error Handling<\/td>\n<td>Review mechanisms for detecting and reporting errors<\/td>\n<td>Helps with debugging and reliability<\/td>\n<\/tr>\n<tr>\n<td>13<\/td>\n<td>Extensibility<\/td>\n<td>Check ability to add user-defined functions (UDFs)<\/td>\n<td>Allows customization for advanced needs<\/td>\n<\/tr>\n<tr>\n<td>14<\/td>\n<td>Declarative Nature<\/td>\n<td>Determine if the language specifies <b>what<\/b> to do, not <b>how<\/b><\/td>\n<td>Simplifies development and optimization<\/td>\n<\/tr>\n<tr>\n<td>15<\/td>\n<td>Portability<\/td>\n<td>See how easily queries migrate across systems<\/td>\n<td>Reduces vendor lock-in and aids flexibility<\/td>\n<\/tr>\n<tr>\n<td>16<\/td>\n<td>Pagination Support<\/td>\n<td>Test LIMIT, OFFSET, or windowing support<\/td>\n<td>Critical for APIs and UI-driven data access<\/td>\n<\/tr>\n<tr>\n<td>17<\/td>\n<td>Schema Introspection<\/td>\n<td>Check querying of schema\/catalog metadata<\/td>\n<td>Supports automation and tooling<\/td>\n<\/tr>\n<tr>\n<td>18<\/td>\n<td>Tooling and IDE Support<\/td>\n<td>Survey ecosystem of query editors, plugins, etc.<\/td>\n<td>Impacts developer productivity<\/td>\n<\/tr>\n<tr>\n<td>19<\/td>\n<td>Community and Documentation<\/td>\n<td>Review quality of docs, community forums, tutorials<\/td>\n<td>Affects ease of learning and troubleshooting<\/td>\n<\/tr>\n<tr>\n<td>20<\/td>\n<td>Integration with App Frameworks<\/td>\n<td>Check library and driver support in popular languages<\/td>\n<td>Eases app development<\/td>\n<\/tr>\n<tr>\n<td>21<\/td>\n<td>Standards Compliance<\/td>\n<td>Compare with industry standards (e.g. SQL)<\/td>\n<td>Helps with portability and interoperability<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When you\u2019re building apps, the query language you work with makes a big difference. It affects everything from performance to how quickly your team can ship features. In this post, I\u2019ve asked an LLM to create a list of 21 [&hellip;]<\/p>\n","protected":false},"author":71,"featured_media":17371,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1814,1812],"tags":[9639],"ppma_author":[8937],"class_list":["post-17369","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-application-design","category-n1ql-query","tag-mongodb-query"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.7.1 (Yoast SEO v25.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Choosing the Right Query Language: SQL++ vs. Mongo - The Couchbase Blog<\/title>\n<meta name=\"description\" content=\"Show how SQL++, used by Couchbase, and Mongo\u2019s Query API (previously known as MQL) languages stack up on the most popular types of query capabilities.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Choosing the Right Query Language: SQL++ vs. Mongo\" \/>\n<meta property=\"og:description\" content=\"Show how SQL++, used by Couchbase, and Mongo\u2019s Query API (previously known as MQL) languages stack up on the most popular types of query capabilities.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2025-07-25T17:09:07+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-08-13T13:52:59+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/07\/blog-sql-vs-mongo-mql.png\" \/>\n\t<meta property=\"og:image:width\" content=\"2400\" \/>\n\t<meta property=\"og:image:height\" content=\"1256\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Matthew Groves\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@mgroves\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Matthew Groves\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/\"},\"author\":{\"name\":\"Matthew Groves\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/3929663e372020321b0152dc4fa65a58\"},\"headline\":\"Choosing the Right Query Language: SQL++ vs. Mongo\",\"datePublished\":\"2025-07-25T17:09:07+00:00\",\"dateModified\":\"2025-08-13T13:52:59+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/\"},\"wordCount\":2040,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/07\/blog-sql-vs-mongo-mql.png\",\"keywords\":[\"mongodb query\"],\"articleSection\":[\"Application Design\",\"SQL++ \/ N1QL Query\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/\",\"name\":\"Choosing the Right Query Language: SQL++ vs. Mongo - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/07\/blog-sql-vs-mongo-mql.png\",\"datePublished\":\"2025-07-25T17:09:07+00:00\",\"dateModified\":\"2025-08-13T13:52:59+00:00\",\"description\":\"Show how SQL++, used by Couchbase, and Mongo\u2019s Query API (previously known as MQL) languages stack up on the most popular types of query capabilities.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/07\/blog-sql-vs-mongo-mql.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/07\/blog-sql-vs-mongo-mql.png\",\"width\":2400,\"height\":1256},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Choosing the Right Query Language: SQL++ vs. Mongo\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/3929663e372020321b0152dc4fa65a58\",\"name\":\"Matthew Groves\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/ba51e6aacc53995c323a634e4502ef54\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/70feb1b28a099ad0112b8d21fe1e81e1a4524beed3e20b7f107d5370e85a07ab?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/70feb1b28a099ad0112b8d21fe1e81e1a4524beed3e20b7f107d5370e85a07ab?s=96&d=mm&r=g\",\"caption\":\"Matthew Groves\"},\"description\":\"Matthew D. Groves is a guy who loves to code. It doesn't matter if it's C#, jQuery, or PHP: he'll submit pull requests for anything. He has been coding professionally ever since he wrote a QuickBASIC point-of-sale app for his parent's pizza shop back in the 90s. He currently works as a Senior Product Marketing Manager for Couchbase. His free time is spent with his family, watching the Reds, and getting involved in the developer community. He is the author of AOP in .NET, Pro Microservices in .NET, a Pluralsight author, and a Microsoft MVP.\",\"sameAs\":[\"https:\/\/crosscuttingconcerns.com\",\"https:\/\/x.com\/mgroves\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/matthew-groves\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Choosing the Right Query Language: SQL++ vs. Mongo - The Couchbase Blog","description":"Show how SQL++, used by Couchbase, and Mongo\u2019s Query API (previously known as MQL) languages stack up on the most popular types of query capabilities.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/","og_locale":"en_US","og_type":"article","og_title":"Choosing the Right Query Language: SQL++ vs. Mongo","og_description":"Show how SQL++, used by Couchbase, and Mongo\u2019s Query API (previously known as MQL) languages stack up on the most popular types of query capabilities.","og_url":"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/","og_site_name":"The Couchbase Blog","article_published_time":"2025-07-25T17:09:07+00:00","article_modified_time":"2025-08-13T13:52:59+00:00","og_image":[{"width":2400,"height":1256,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/07\/blog-sql-vs-mongo-mql.png","type":"image\/png"}],"author":"Matthew Groves","twitter_card":"summary_large_image","twitter_creator":"@mgroves","twitter_misc":{"Written by":"Matthew Groves","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/"},"author":{"name":"Matthew Groves","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/3929663e372020321b0152dc4fa65a58"},"headline":"Choosing the Right Query Language: SQL++ vs. Mongo","datePublished":"2025-07-25T17:09:07+00:00","dateModified":"2025-08-13T13:52:59+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/"},"wordCount":2040,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/07\/blog-sql-vs-mongo-mql.png","keywords":["mongodb query"],"articleSection":["Application Design","SQL++ \/ N1QL Query"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/","url":"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/","name":"Choosing the Right Query Language: SQL++ vs. Mongo - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/07\/blog-sql-vs-mongo-mql.png","datePublished":"2025-07-25T17:09:07+00:00","dateModified":"2025-08-13T13:52:59+00:00","description":"Show how SQL++, used by Couchbase, and Mongo\u2019s Query API (previously known as MQL) languages stack up on the most popular types of query capabilities.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/07\/blog-sql-vs-mongo-mql.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/07\/blog-sql-vs-mongo-mql.png","width":2400,"height":1256},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/choosing-the-right-query-language-sql-vs-mongo\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Choosing the Right Query Language: SQL++ vs. Mongo"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/3929663e372020321b0152dc4fa65a58","name":"Matthew Groves","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/ba51e6aacc53995c323a634e4502ef54","url":"https:\/\/secure.gravatar.com\/avatar\/70feb1b28a099ad0112b8d21fe1e81e1a4524beed3e20b7f107d5370e85a07ab?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/70feb1b28a099ad0112b8d21fe1e81e1a4524beed3e20b7f107d5370e85a07ab?s=96&d=mm&r=g","caption":"Matthew Groves"},"description":"Matthew D. Groves is a guy who loves to code. It doesn't matter if it's C#, jQuery, or PHP: he'll submit pull requests for anything. He has been coding professionally ever since he wrote a QuickBASIC point-of-sale app for his parent's pizza shop back in the 90s. He currently works as a Senior Product Marketing Manager for Couchbase. His free time is spent with his family, watching the Reds, and getting involved in the developer community. He is the author of AOP in .NET, Pro Microservices in .NET, a Pluralsight author, and a Microsoft MVP.","sameAs":["https:\/\/crosscuttingconcerns.com","https:\/\/x.com\/mgroves"],"url":"https:\/\/www.couchbase.com\/blog\/author\/matthew-groves\/"}]}},"authors":[{"term_id":8937,"user_id":71,"is_guest":0,"slug":"matthew-groves","display_name":"Matthew Groves","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/70feb1b28a099ad0112b8d21fe1e81e1a4524beed3e20b7f107d5370e85a07ab?s=96&d=mm&r=g","author_category":"","last_name":"Groves","first_name":"Matthew","job_title":"","user_url":"https:\/\/crosscuttingconcerns.com","description":"Matthew D. Groves is a guy who loves to code.  It doesn't matter if it's C#, jQuery, or PHP: he'll submit pull requests for anything.  He has been coding professionally ever since he wrote a QuickBASIC point-of-sale app for his parent's pizza shop back in the 90s.  He currently works as a Senior Product Marketing Manager for Couchbase. His free time is spent with his family, watching the Reds, and getting involved in the developer community.  He is the author of AOP in .NET, Pro Microservices in .NET, a Pluralsight author, and a Microsoft MVP."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/17369","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/71"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=17369"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/17369\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/17371"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=17369"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=17369"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=17369"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=17369"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}