When you’re 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’ve asked an LLM to create a list of 21 ranked criteria that are most valuable when deciding which query language to use. We’ll walk through each one and show how SQL++, used by Couchbase, and Mongo’s Query API (previously known as MQL) languages stack up.
Whether you’re 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.
표현력
SQL++ lets you write rich, complex queries—joins, subqueries, aggregates, window functions—while working with flexible document data. You can express nearly anything you’d expect in SQL, plus native support for JSON.
Mongo’s 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.
SQL++ | 몽고 | ||||
---|---|---|---|---|---|
|
Mongo requires a more procedural pipeline:
|
가독성
SQL++ is declarative and familiar to anyone with SQL experience. The intent of the query is easy to see.
1 2 3 4 |
선택 이름, 나이 FROM 사용자 어디 나이 >= 21 주문 BY 이름; |
Mongo’s pipeline is more verbose and procedural—you have to mentally step through each stage.
1 2 3 4 |
db.사용자.찾기( { 나이: { $gte: 21 } }, { 이름: 1, 나이: 1, _id: 0 } ).정렬({ 이름: 1 }); |
For simple queries this isn’t terrible. But as queries grow (joins, subqueries, aggregations), readability can drop quickly in Mongo’s pipeline format.
일관성
SQL++ is highly consistent. The syntax and semantics are predictable, and it feels like “SQL for documents” across the board.
Example with nested data:
1 2 3 4 |
선택 u.이름, a.도시 FROM 사용자 u UNNEST u.주소 AS a 어디 a.국가 = "USA"; |
In Mongo, querying nested structures often requires switching to dot notation or array operators, and pipelines use a different style than find(). You end up learning multiple syntaxes:
Simple query with dot notation:
1 2 3 4 |
db.사용자.찾기( { "addresses.country": "USA" }, { 이름: 1, "addresses.city": 1, _id: 0 } ); |
More complex? You’re back in aggregation-land:
1 2 3 4 5 |
db.사용자.집계([ { $긴장을 풀다: "$addresses" }, { $일치: { "addresses.country": "USA" } }, { $프로젝트: { 이름: 1, 도시: "$addresses.city", _id: 0 } } ]); |
성능
When it comes to raw performance, Couchbase SQL++ consistently outpaces MongoDB’s query language in benchmarks, especially under high-throughput, low-latency workloads.
Couchbase has demonstrated superior scalability and efficiency in various benchmarks. For instance, in the Yahoo! Cloud Serving Benchmark (YCSB), Couchbase exhibited significantly better performance at scale—up compared to MongoDB.
Beyond benchmarks, Couchbase customers have reported significant performance improvements:
-
- FICO chose Couchbase over MongoDB to achieve <1ms response time
- LinkedIn chose Couchbase over MongoDB to execute 10m+ queries per second
MongoDB’s 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 BenchANT Database Ranking).
Index Support
SQL++ supports a broad set of indexes: primary, secondary, composite, array, partial, covering, FTS—all usable from a single language.
Mongo supports primary (on _id), secondary, compound, multikey, text, and hashed indexes. It’s strong, but lacks some of the flexibility of SQL++ when it comes to indexing deeply nested fields or expressions.
Example with partial index in SQL++:
1 2 |
만들기 INDEX idx_active_users 켜기 사용자(이메일) 어디 활성 = TRUE; |
Mongo partial index is similar:
1 2 3 4 |
db.사용자.createIndex( { 이메일: 1 }, { partialFilterExpression: { 활성: true } } ); |
Join Capabilities
SQL++ supports full JOIN syntax—inner, left outer, UNNEST, and combinations. It treats documents as first-class citizens in relational-style queries.
예시:
1 2 3 4 |
선택 u.이름, o.합계 FROM 사용자 u JOIN 주문 o 켜기 u.id = o.user_id 어디 o.합계 > 100; |
Mongo’s $조회 supports more expressive pipelines since 5.0, but is still LEFT OUTER and lacks full join syntax.
1 2 3 4 5 6 7 8 9 10 11 12 |
db.주문.집계([ { $일치: { 합계: { $gt: 100 } } }, { $조회: { 에서: "users", localField: "user_id", 외국 필드: "id", as: "user" } }, { $긴장을 풀다: "$user" }, { $프로젝트: { 이름: "$user.name", 합계: 1 } } ]); |
SQL++ also supports multiple joins and joins on expressions—Mongo’s $조회 is more limited in comparison.
Aggregation Support
SQL++ has full GROUP BY, HAVING, window functions, and flexible expressions—just like standard SQL.
예시:
1 2 3 4 |
선택 부서, AVG(급여) AS avg_salary FROM 직원 그룹 BY 부서 보유 avg_salary > 75000; |
Mongo’s aggregation pipeline is capable, but more procedural. You chain stages like $group, $match, $프로젝트, etc.:
1 2 3 4 |
db.직원.집계([ { $그룹: { _id: "$department", avg_salary: { $평균: "$salary" } } }, { $일치: { avg_salary: { $gt: 75000 } } } ]); |
Both are powerful, but SQL++ is typically more concise and familiar for SQL users, and supports features like 창 기능 that Mongo’s pipeline lacks.
Filtering and Predicate Logic
SQL++ has full support for complex filtering with AND, 또는, NOT, 사이, IN, subqueries, and arbitrary expressions.
예시:
1 2 3 4 5 |
선택 이름 FROM 사용자 어디 (나이 사이 21 AND 65) AND (이메일 좋아요 "%@example.com") AND (상태 IN ["active", "pending"]); |
Mongo supports filtering in find() and in $match stages, but the syntax is more verbose and JSON-based:
1 2 3 4 5 |
db.사용자.찾기({ 나이: { $gte: 21, $lte: 65 }, 이메일: { $정규식: "@example\\.com$" }, 상태: { $in: ["active", "pending"] } }); |
Both can express complex predicates, but SQL++ tends to be more readable for highly complex boolean logic.
Subquery Support
SQL++ supports full subqueries: correlated, uncorrelated, scalar, 존재/NOT EXISTS—all the patterns you’d expect.
예시:
1 2 3 4 5 6 |
선택 이름 FROM 사용자 u 어디 존재 ( 선택 1 FROM 주문 o 어디 o.user_id = u.id AND o.합계 > 100 ); |
Mongo doesn’t support subqueries in the same way. You generally have to rewrite using $조회, $facet, or multiple queries in application code. This is one area where SQL++ is much stronger and more natural.
Data Manipulation Support
SQL++ supports full 삽입, 업데이트, 삭제, MERGE — all standard data manipulation operations.
예 업데이트:
1 2 3 |
업데이트 사용자 SET 상태 = "inactive" 어디 last_login < "2024-01-01"; |
Mongo also supports data manipulation via insertOne, insertMany, updateOne, updateMany, deleteOne, deleteMany및 replaceOne. The functionality is solid, but operations are separate API calls—not unified under one query language.
Example update:
1 2 3 4 |
db.사용자.updateMany( { last_login: { $lt: new 날짜("2024-01-01") } }, { $set: { 상태: "inactive" } } ); |
Both are capable, but SQL++ provides a single, consistent language for both querying and modifying data.
Transactions Support
SQL++ supports multi-statement ACID transactions (with Couchbase’s BEGIN TRANSACTION, 커밋, 롤백), and transactions can span multiple documents, collections, and even multiple statements.
예시:
1 2 3 4 |
시작 트랜잭션; 업데이트 계정 SET balance = balance - 100 어디 id = "user123"; 업데이트 계정 SET balance = balance + 100 어디 id = "user456"; 커밋; |
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.
Example (driver-based in Node.js):
1 2 3 4 5 6 7 8 9 10 |
const 세션 = 클라이언트.startSession(); 세션.startTransaction(); 시도 { db.계정.updateOne({ id: "user123" }, { $inc: { balance: -100 } }, { 세션 }); db.계정.updateOne({ id: "user456" }, { $inc: { balance: 100 } }, { 세션 }); 기다림 세션.commitTransaction(); } catch (오류) { 기다림 세션.abortTransaction(); } 세션.endSession(); |
Summary: Both support ACID transactions, but SQL++ lets you express them declaratively inside the query language itself, which is easier and clearer.
오류 처리
SQL++ surfaces structured error codes and messages to the client when a query fails — 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.
Example (defensive logic):
1 2 3 4 |
업데이트 사용자 SET last_login = CURRENT_TIMESTAMP 어디 user_id = "user123" AND last_login IS NOT 누락; |
Error codes are documented here: Couchbase SQL++ Error Codes.
Mongo also relies on driver-level error handling — errors are raised to the client when queries or commands fail. Mongo’s aggregation pipeline does not support in-query error handling either.
Example (Mongo defensive update):
1 2 3 4 |
db.사용자.updateOne( { user_id: "user123", last_login: { $존재: true } }, { $set: { last_login: new 날짜() } } ); |
Summary: Both SQL++ and Mongo rely on external (driver-level) error handling. You can use defensive query patterns to mitigate common errors.
확장성
SQL++ allows user-defined functions (UDFs) written in SQL++ itself. These can encapsulate complex logic, reuse expressions, and simplify queries.
Example UDF:
1 2 3 4 5 6 7 |
만들기 기능 get_discount(합계 FLOAT) RETURNS FLOAT AS 사례 언제 합계 > 500 그때 0.10 언제 합계 > 100 그때 0.05 기타 0.0 END; |
사용법:
1 2 |
선택 customer_id, 합계, get_discount(합계) AS discount FROM 주문; |
Mongo has no in-query UDFs in its query language or aggregation pipeline. You can use $function (introduced in MongoDB 4.4), which lets you run JavaScript functions inside aggregation — but this is less efficient and limited in portability:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
db.주문.집계([ { $addFields: { discount: { $함수: { body: 함수(합계) { 만약 (합계 > 500) 반환 0.10; 만약 (합계 > 100) 반환 0.05; 반환 0.0; }, args: ["$total"], lang: "js" } } } } ]); |
Summary: SQL++ UDFs are native, efficient, and portable; Mongo’s $function uses JavaScript and may have performance trade-offs.
Declarative Nature
SQL++ is fully declarative — 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.
Mongo’s aggregation pipeline is more procedural — you specify the exact sequence of operations ($match, $group, $프로젝트, $sort, etc.). For complex logic, this often requires thinking in terms of data flow, not desired result.
휴대성
SQL++ is based on SQL with JSON extensions. If you know SQL, it’s easy to learn SQL++, and much of your knowledge carries over. The language is also designed to be portable across Couchbase deployments — cloud, self-managed, edge.
Mongo’s query language is specific to MongoDB. Its syntax is JSON-based, not SQL-like, and most of it doesn’t transfer to other databases. While it’s great inside the Mongo ecosystem, it’s harder to port to systems like relational databases, Couchbase, or cloud data warehouses.
Pagination Support
SQL++ supports pagination using LIMIT 그리고 오프셋 — standard SQL-style:
1 2 3 4 |
선택 이름 FROM 사용자 주문 BY 이름 LIMIT 10 오프셋 20; |
Mongo also supports pagination with .limit() 그리고 .skip():
1 2 3 4 |
db.사용자.찾기({}) .정렬({ 이름: 1 }) .건너뛰기(20) .limit(10); |
Both handle basic pagination well.
However — SQL++ also supports window functions (e.g. ROW_NUMBER() OVER (…)), which allows for more advanced pagination and cursor-based patterns, whereas Mongo requires additional pipeline stages or application logic to simulate those.
Schema Introspection
SQL++ / Couchbase supports automatic schema discovery via the INFER command. Since Couchbase is schema-flexible, INFER lets you analyze documents in a collection and generate a probabilistic schema — showing what fields exist, their types, nesting, and occurrence percentages.
예시:
1 |
INFER `여행-샘플`.인벤토리.항공사 WITH { "sample_size": 1000 }; |
Returns information about the airline collection, including field names, types, and occurrence percentages:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[ [ { "#docs": 187, "$schema": "http://json-schema.org/draft-06/schema", "맛": "`유형` = \"항공사\""", "속성": { "콜사인": { ... }, "country": { ... }, "name": { ... }, ... }, "type": "object" } ] ] |
Mongo has no direct query language equivalent to INFER, though MongoDB Atlas offers Schema Explorer in the UI.
Closest options:
-
- db.collection.aggregate([ { $sample: { size: N } } ]) + manual inspection
- Third-party tools
Tooling and IDE Support
SQL++ is supported in:
-
- Couchbase Web UI Query Workbench
- VS Code SQL++ extension
- JetBrains IDEs (plugin)
- REST API / CLI
- 카우치베이스 셸
Mongo’s tooling includes:
-
- MongoDB Compass (GUI)
- Mongo Shell / mongosh
- MongoDB Atlas UI
- VS Code MongoDB extension
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.
Community and Documentation
SQL++ / Couchbase:
-
- Official Docs: Couchbase SQL++ Reference
- Active Couchbase developer community
- Blogs, forums, Stack Overflow, Discord
- SQL++ is based on familiar SQL, so existing SQL resources also apply
Mongo:
-
- Official Docs: MongoDB Query Language Reference
- Large community
- Many tutorials, courses, books
- Heavily used in web dev / JavaScript communities
Mongo has a bigger community (simply due to broader adoption), but SQL++ benefits from SQL familiarity and an increasingly active Couchbase developer ecosystem.
Integration with App Frameworks
SQL++ / Couchbase is supported via:
-
- SDKs in major languages: Java, .NET (C#), Node.js, Python, Go, C++, Scala
- ODBC / JDBC drivers → works with BI tools (Tableau, Power BI, Excel, Looker)
- REST API
- A growing ecosystem of 통합, including Spring Data, EF Core, Quarkus, and more
Mongo has:
-
- Official drivers for nearly every major language
- Strong ecosystem for developers
Mongo has a larger ecosystem, but SQL++ is more familiar to SQL developers in general.
Standards Compliance
SQL++ is a SQL-derived language:
-
- Based on ANSI SQL with extensions for JSON documents, arrays, nesting
- You can take standard SQL skills and use them right away
- Many existing SQL-based tools and patterns apply
Mongo’s query language is non-standard:
-
- Based on JSON syntax and operators
- No direct mapping to ANSI SQL
- Requires learning Mongo-specific query patterns
If you want SQL compatibility and standards alignment, look to SQL++. If you’re fine with a Mongo-specific language, Mongo’s approach works, but is harder to port.
요약
SQL++ is a natural fit for developers familiar with SQL. It’s a superset of SQL, so existing SQL knowledge carries over.
MongoDB’s query language is more specialized and procedural, which can be powerful but also requires a different mindset.
Here’s the complete criteria listing:
순위 | Name of Criteria | How to Apply It | Why It’s Important |
1 | 표현력 | Assess how many types of queries can be written | Determines flexibility in handling data tasks |
2 | 가독성 | Review sample queries for clarity | Impacts learning curve and maintenance |
3 | 일관성 | Look for consistent syntax and semantics | Reduces bugs and surprises |
4 | 성능 | Benchmark query execution on real workloads | Affects speed and scalability |
5 | Index Support | Check range of index types and usage options | Critical for optimizing query speed |
6 | Join Capabilities | Test support for different join types | Key for working with related data |
7 | Aggregation Support | Evaluate support for grouping and aggregation | Necessary for analytics and reporting |
8 | Filtering and Predicate Logic | Test complex WHERE and HAVING clauses | Enables precise data retrieval |
9 | Subquery Support | Verify support for correlated and nested subqueries | Adds depth to querying |
10 | Data Manipulation Support | Test INSERT, UPDATE, DELETE, MERGE functionality | Important for data maintenance |
11 | Transactions Support | Check support for multi-statement transactions | Ensures data consistency and atomicity |
12 | 오류 처리 | Review mechanisms for detecting and reporting errors | Helps with debugging and reliability |
13 | 확장성 | Check ability to add user-defined functions (UDFs) | Allows customization for advanced needs |
14 | Declarative Nature | Determine if the language specifies 무엇 to do, not 어떻게 | Simplifies development and optimization |
15 | 휴대성 | See how easily queries migrate across systems | Reduces vendor lock-in and aids flexibility |
16 | Pagination Support | Test LIMIT, OFFSET, or windowing support | Critical for APIs and UI-driven data access |
17 | Schema Introspection | Check querying of schema/catalog metadata | Supports automation and tooling |
18 | Tooling and IDE Support | Survey ecosystem of query editors, plugins, etc. | Impacts developer productivity |
19 | Community and Documentation | Review quality of docs, community forums, tutorials | Affects ease of learning and troubleshooting |
20 | Integration with App Frameworks | Check library and driver support in popular languages | Eases app development |
21 | Standards Compliance | Compare with industry standards (e.g. SQL) | Helps with portability and interoperability |