Go library for parsing and executing MongoDB shell syntax using the native MongoDB driver.
gomongo parses MongoDB shell commands (e.g., db.users.find()) and executes them using the Go MongoDB driver, eliminating the need for external mongosh CLI.
go get github.com/bytebase/gomongopackage main
import (
"context"
"fmt"
"log"
"github.com/bytebase/gomongo"
"go.mongodb.org/mongo-driver/v2/mongo"
"go.mongodb.org/mongo-driver/v2/mongo/options"
)
func main() {
ctx := context.Background()
// Connect to MongoDB
client, err := mongo.Connect(options.Client().ApplyURI("mongodb://localhost:27017"))
if err != nil {
log.Fatal(err)
}
defer client.Disconnect(ctx)
// Create gomongo client
gc := gomongo.NewClient(client)
// Execute MongoDB shell commands
result, err := gc.Execute(ctx, "mydb", `db.users.find({ age: { $gt: 25 } })`)
if err != nil {
log.Fatal(err)
}
// Print results (Extended JSON format)
for _, row := range result.Rows {
fmt.Println(row)
}
}The Execute method accepts optional configuration:
Limit the maximum number of rows returned by find() and countDocuments() operations. This is useful to prevent excessive memory usage or network traffic from unbounded queries.
// Cap results at 1000 rows
result, err := gc.Execute(ctx, "mydb", `db.users.find()`, gomongo.WithMaxRows(1000))Behavior:
- If the query includes
.limit(N), the effective limit ismin(N, maxRows) - Query limit 50 + MaxRows 1000 → returns up to 50 rows
- Query limit 5000 + MaxRows 1000 → returns up to 1000 rows
aggregate()operations are not affected (use$limitstage instead)
Results are returned in Extended JSON (Relaxed) format:
{
"_id": {"$oid": "507f1f77bcf86cd799439011"},
"name": "Alice",
"age": 30,
"createdAt": {"$date": "2024-01-01T00:00:00Z"}
}| Command | Syntax | Status |
|---|---|---|
| show dbs | show dbs |
Supported |
| show databases | show databases |
Supported |
| show collections | show collections |
Supported |
| db.getCollectionNames() | db.getCollectionNames() |
Supported |
| db.getCollectionInfos() | db.getCollectionInfos() |
Supported |
| Command | Syntax | Status | Notes |
|---|---|---|---|
| db.collection.find() | find(query, projection) |
Supported | options deferred |
| db.collection.findOne() | findOne(query, projection) |
Supported | |
| db.collection.countDocuments() | countDocuments(filter) |
Supported | options deferred |
| db.collection.estimatedDocumentCount() | estimatedDocumentCount() |
Supported | options deferred |
| db.collection.distinct() | distinct(field, query) |
Supported | options deferred |
| db.collection.getIndexes() | getIndexes() |
Supported |
| Method | Syntax | Status |
|---|---|---|
| cursor.limit() | limit(number) |
Supported |
| cursor.skip() | skip(number) |
Supported |
| cursor.sort() | sort(document) |
Supported |
| cursor.count() | count() |
Deprecated - use countDocuments() |
| Command | Syntax | Status | Notes |
|---|---|---|---|
| db.collection.aggregate() | aggregate(pipeline) |
Supported | options deferred |
| Constructor | Supported Syntax | Unsupported Syntax |
|---|---|---|
| ObjectId() | ObjectId(), ObjectId("hex") |
new ObjectId() |
| ISODate() | ISODate(), ISODate("string") |
new ISODate() |
| Date() | Date(), Date("string"), Date(timestamp) |
new Date() |
| UUID() | UUID("hex") |
new UUID() |
| NumberInt() | NumberInt(value) |
new NumberInt() |
| NumberLong() | NumberLong(value) |
new NumberLong() |
| NumberDecimal() | NumberDecimal("value") |
new NumberDecimal() |
| Timestamp() | Timestamp(t, i) |
new Timestamp() |
| BinData() | BinData(subtype, base64) |
|
| RegExp() | RegExp("pattern", "flags"), /pattern/flags |
| Command | Syntax | Status |
|---|---|---|
| db.collection.insertOne() | insertOne(document, options) |
Supported |
| db.collection.insertMany() | insertMany(documents, options) |
Supported |
| Command | Syntax | Status |
|---|---|---|
| db.collection.updateOne() | updateOne(filter, update, options) |
Supported |
| db.collection.updateMany() | updateMany(filter, update, options) |
Supported |
| db.collection.replaceOne() | replaceOne(filter, replacement, options) |
Supported |
| Command | Syntax | Status |
|---|---|---|
| db.collection.deleteOne() | deleteOne(filter, options) |
Supported |
| db.collection.deleteMany() | deleteMany(filter, options) |
Supported |
| Command | Syntax | Status |
|---|---|---|
| db.collection.findOneAndUpdate() | findOneAndUpdate(filter, update, options) |
Supported |
| db.collection.findOneAndReplace() | findOneAndReplace(filter, replacement, options) |
Supported |
| db.collection.findOneAndDelete() | findOneAndDelete(filter, options) |
Supported |
| Option | Applies To | Description |
|---|---|---|
writeConcern |
All write ops | Write concern settings (w, j, wtimeout*) |
bypassDocumentValidation |
Insert, Update, Replace, FindOneAndUpdate/Replace | Skip schema validation |
comment |
All write ops | Comment for server logs |
ordered |
insertMany | Execute inserts sequentially (default: true) |
upsert |
Update, Replace, FindOneAndUpdate/Replace | Insert if no match found |
hint |
Update, Replace, Delete, FindOneAnd* | Force index usage |
collation |
Update, Replace, Delete, FindOneAnd* | String comparison rules |
arrayFilters |
updateOne, updateMany, findOneAndUpdate | Array element filtering |
let |
Update, Replace, Delete, FindOneAnd* | Variables for expressions |
sort |
updateOne, replaceOne, FindOneAnd* | Document selection order |
projection |
FindOneAnd* | Fields to return |
returnDocument |
FindOneAndUpdate/Replace | Return "before" or "after" |
*Note: wtimeout is parsed but ignored as it's not supported in MongoDB Go driver v2.
| Command | Syntax | Status |
|---|---|---|
| db.collection.createIndex() | createIndex(keys) |
Not yet supported |
| db.collection.createIndexes() | createIndexes(indexSpecs) |
Not yet supported |
| db.collection.dropIndex() | dropIndex(index) |
Not yet supported |
| db.collection.dropIndexes() | dropIndexes() |
Not yet supported |
| Command | Syntax | Status |
|---|---|---|
| db.createCollection() | db.createCollection(name) |
Not yet supported |
| db.collection.drop() | drop() |
Not yet supported |
| db.collection.renameCollection() | renameCollection(newName) |
Not yet supported |
| db.dropDatabase() | db.dropDatabase() |
Not yet supported |
| Command | Syntax | Status |
|---|---|---|
| db.stats() | db.stats() |
Not yet supported |
| db.collection.stats() | stats() |
Not yet supported |
| db.serverStatus() | db.serverStatus() |
Not yet supported |
| db.serverBuildInfo() | db.serverBuildInfo() |
Not yet supported |
| db.version() | db.version() |
Not yet supported |
| db.hostInfo() | db.hostInfo() |
Not yet supported |
| db.listCommands() | db.listCommands() |
Not yet supported |
The following categories are recognized but not planned for support:
| Category | Reason |
|---|---|
Database switching (use <db>, db.getSiblingDB()) |
Database is set at connection time |
Interactive cursor methods (hasNext(), next(), toArray()) |
Not an interactive shell |
JavaScript execution (forEach(), map()) |
No JavaScript engine |
Replication (rs.*) |
Cluster administration |
Sharding (sh.*) |
Cluster administration |
| User/Role management | Security administration |
| Client-side encryption | Security feature |
Atlas Stream Processing (sp.*) |
Atlas-specific |
Native shell functions (cat(), load(), quit()) |
Shell-specific |
For deprecated methods (e.g., db.collection.insert(), db.collection.update()), gomongo returns actionable error messages directing users to modern alternatives.
- No database switching - Database is set at connection time only
- Not an interactive shell - No cursor iteration, REPL-style commands, or stateful operations
- Syntax translator, not validator - Arguments pass directly to the Go driver; the server validates
- Single syntax for constructors - Use
ObjectId(), notnew ObjectId() - Clear error messages - Actionable guidance for unsupported or deprecated syntax