Documentation Index
Fetch the complete documentation index at: https://docs.omniql.com/llms.txt
Use this file to discover all available pages before exploring further.
MongoDB is a document database that stores data in flexible, JSON-like documents.
Quick Start
import (
"context"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"github.com/omniql-engine/omniql"
)
// Your MongoDB connection
mongoClient, _ := mongo.Connect(context.Background(),
options.Client().ApplyURI("mongodb://localhost:27017"))
db := mongoClient.Database("mydb")
// Wrap with OmniQL
client := oql.WrapMongo(db)
// Query with OmniQL syntax
users, _ := client.Query(":GET User WHERE age > 21")
Type Mappings
| OmniQL | MongoDB |
|---|
AUTO | ObjectId |
BIGAUTO | ObjectId |
STRING | String |
TEXT | String |
CHAR | String |
INT | Int32 |
BIGINT | Int64 |
SMALLINT | Int32 |
DECIMAL | Decimal128 |
NUMERIC | Decimal128 |
FLOAT | Double |
REAL | Double |
BOOLEAN | Boolean |
BOOL | Boolean |
TIMESTAMP | Date |
DATETIME | Date |
DATE | Date |
TIME | String |
JSON | Object |
JSONB | Object |
UUID | UUID |
BINARY | BinData |
BLOB | BinData |
Entity Naming
OmniQL entities become collection names (lowercase):
| OmniQL | MongoDB |
|---|
User | users |
Order | orders |
OrderItem | orderitems |
Translation Examples
CRUD Operations
GET (find)
:GET User WHERE age > 21 AND status = "active"
db.users.find({ age: { $gt: 21 }, status: 'active' })
:GET id, name, email FROM User WHERE active = true
db.users.find({ active: true }, { id: 1, name: 1, email: 1 })
CREATE (insertOne)
:CREATE User WITH name = "John", email = "john@example.com"
db.users.insertOne({ name: 'John', email: 'john@example.com' })
BULK INSERT (insertMany)
:BULK INSERT User WITH [name = "Alice", age = 28] [name = "Bob", age = 32]
db.users.insertMany([
{ name: 'Alice', age: 28 },
{ name: 'Bob', age: 32 }
])
UPDATE (updateOne)
:UPDATE User SET status = "active" WHERE id = 1
db.users.updateOne({ id: 1 }, { $set: { status: 'active' } })
Arithmetic in UPDATE
:UPDATE User SET balance = balance + 100 WHERE id = 1
db.users.updateOne({ id: 1 }, { $inc: { balance: 100 } })
:UPDATE Product SET price = price * 0.9 WHERE category = "sale"
db.products.updateOne({ category: 'sale' }, { $mul: { price: 0.9 } })
DELETE (deleteOne)
:DELETE User WHERE id = 1
db.users.deleteOne({ id: 1 })
UPSERT
:UPSERT User WITH email = "john@example.com", name = "John" ON email
db.users.updateOne(
{ email: 'john@example.com' },
{ $set: { email: 'john@example.com', name: 'John' } },
{ upsert: true }
)
REPLACE (replaceOne)
:REPLACE User WITH id = 1, name = "John", email = "john@example.com"
db.users.replaceOne({ id: 1 }, { name: 'John', email: 'john@example.com' })
Filtering (Operators)
| OmniQL | MongoDB |
|---|
= | $eq |
!= | $ne |
> | $gt |
>= | $gte |
< | $lt |
<= | $lte |
IN | $in |
NOT IN | $nin |
LIKE | $regex |
IS NULL | $eq: null |
IS NOT NULL | $ne: null |
AND | implicit / $and |
OR | $or |
Examples:
:GET User WHERE role IN ("admin", "moderator")
db.users.find({ role: { $in: ['admin', 'moderator'] } })
:GET User WHERE age BETWEEN 18 AND 65
db.users.find({ age: { $gte: 18, $lte: 65 } })
:GET User WHERE name LIKE "John%"
db.users.find({ name: { $regex: /^John/, $options: 'i' } })
:GET User WHERE role = "admin" OR role = "moderator"
db.users.find({ $or: [{ role: 'admin' }, { role: 'moderator' }] })
:GET User ORDER BY created_at DESC LIMIT 10 OFFSET 20
db.users.find({}).sort({ created_at: -1 }).skip(20).limit(10)
Aggregation
COUNT
:COUNT * FROM User WHERE active = true
db.users.aggregate([
{ $match: { active: true } },
{ $group: { _id: null, result: { $sum: 1 } } }
])
GROUP BY
:COUNT * FROM User GROUP BY status
db.users.aggregate([
{ $group: { _id: '$status', result: { $sum: 1 } } }
])
SUM, AVG, MIN, MAX
:SUM total FROM Order WHERE status = "completed"
db.orders.aggregate([
{ $match: { status: 'completed' } },
{ $group: { _id: null, result: { $sum: '$total' } } }
])
HAVING
:COUNT * FROM User GROUP BY status HAVING COUNT(*) > 10
db.users.aggregate([
{ $group: { _id: '$status', result: { $sum: 1 } } },
{ $match: { result: { $gt: 10 } } }
])
Joins ($lookup)
OmniQL joins translate to MongoDB’s $lookup aggregation:
:INNER JOIN Order User ON Order.user_id = User.id
db.orders.aggregate([
{
$lookup: {
from: 'users',
localField: 'user_id',
foreignField: '_id',
as: 'users_joined'
}
},
{ $unwind: '$users_joined' }
])
:LEFT JOIN Order User ON Order.user_id = User.id
db.orders.aggregate([
{
$lookup: {
from: 'users',
localField: 'user_id',
foreignField: '_id',
as: 'users_joined'
}
},
{ $unwind: { path: '$users_joined', preserveNullAndEmptyArrays: true } }
])
Window Functions (MongoDB 5.0+)
:ROW NUMBER OVER (PARTITION BY department ORDER BY salary) FROM Employee
db.employees.aggregate([
{
$setWindowFields: {
partitionBy: '$department',
sortBy: { salary: 1 },
output: {
rowNumber: { $documentNumber: {} }
}
}
}
])
Supported window functions:
- ROW NUMBER →
$documentNumber
- RANK →
$rank
- DENSE RANK →
$denseRank
- LAG/LEAD →
$shift
Set Operations (MongoDB 4.4+)
:UNION (GET User WHERE age > 50) (GET User WHERE role = "premium")
db.users.aggregate([
{ $match: { age: { $gt: 50 } } },
{ $unionWith: { coll: 'users', pipeline: [{ $match: { role: 'premium' } }] } }
])
CASE Expressions
:GET User WITH CASE WHEN age > 25 THEN "adult" ELSE "minor" END AS category
db.users.aggregate([
{
$project: {
category: {
$switch: {
branches: [
{ case: { $gt: ['$age', 25] }, then: 'adult' }
],
default: 'minor'
}
}
}
}
])
Transactions (Replica Set Required)
:BEGIN
:UPDATE Account SET balance = balance - 100 WHERE id = 1
:UPDATE Account SET balance = balance + 100 WHERE id = 2
:COMMIT
session.startTransaction();
db.accounts.updateOne({ id: 1 }, { $inc: { balance: -100 } });
db.accounts.updateOne({ id: 2 }, { $inc: { balance: 100 } });
session.commitTransaction();
Permissions
CREATE USER:
:CREATE USER analyst WITH PASSWORD secret123
db.runCommand({ createUser: 'analyst', pwd: 'secret123', roles: [] })
CREATE ROLE:
db.runCommand({ createRole: 'readonly', privileges: [], roles: [] })
GRANT ROLE:
:ASSIGN ROLE readonly TO analyst
db.runCommand({ grantRolesToUser: 'analyst', roles: ['readonly'] })
Supported Operations
| Category | Operations | Support |
|---|
| CRUD | GET, CREATE, UPDATE, DELETE, UPSERT, BULK INSERT, REPLACE | Full |
| Filtering | All operators (=, !=, IN, BETWEEN, LIKE, IS NULL, etc.) | Full |
| Aggregation | COUNT, SUM, AVG, MIN, MAX | Full |
| Grouping | GROUP BY, HAVING | Full |
| Sorting | ORDER BY, LIMIT, OFFSET | Full |
| Joins | INNER, LEFT, RIGHT, FULL | Via $lookup |
| Window Functions | ROW NUMBER, RANK, DENSE RANK, LAG, LEAD | MongoDB 5.0+ |
| Set Operations | UNION, UNION ALL | MongoDB 4.4+ |
| Expressions | Arithmetic (+, -, *, /, %), CASE WHEN | Full |
| Functions | UPPER, LOWER, CONCAT, LENGTH, ABS, ROUND | Full |
| Transactions | BEGIN, COMMIT, ROLLBACK | Replica set only |
| DDL | CREATE/DROP COLLECTION, RENAME, CREATE VIEW | Full |
| DCL | CREATE/DROP USER, CREATE/DROP ROLE, GRANT, REVOKE | Full |
Limitations
| Feature | Status | Notes |
|---|
| SAVEPOINT | Not supported | MongoDB has no savepoint concept |
| ROLLBACK TO | Not supported | No partial rollback |
| RELEASE SAVEPOINT | Not supported | No savepoints |
| INTERSECT | Not supported | Use aggregation workarounds |
| EXCEPT | Not supported | Use aggregation workarounds |
| CTEs | Not supported | Use aggregation pipelines instead |
| Single-node transactions | Not supported | Requires replica set |
Version Requirements
| Feature | Minimum MongoDB Version |
|---|
| Basic CRUD | 3.6+ |
| Transactions | 4.0+ (replica set) |
| $unionWith | 4.4+ |
| $setWindowFields | 5.0+ |
Next Steps