MongoDB
MongoDB is a popular Document NoSQL Database. It stores data as JSON-based (BSON) documents. All queries use JSON, so there is almost no MongoDB-specific syntax.
You can use Compass GUI. Otherwise, follow MongoDB install instructions (mongosh
...), or use the cloud database.
π See my notes about the PHP driver and the Node.js driver.
The URL is commonly mongodb://localhost:27017/
.
- β No account required
- π± Easy to learn
- π€ open-source (GitHub, 24.0k β¨)
- π Almost no syntax, it's mainly JSON
- π«οΈ Cloud (free version available) or self-hosted (local)
- π₯ Hard to reference documents (there is no concept of relationship)
Core logic
As MongoDB is a NoSQL database, it's common for documents (e.g. a user) to have missing fields (ex: missing address, if no purchases yet).
In MongoDB, empty databases, empty collections, or attributes with no values, are not shown βοΈ (e.g., in { x = null, y = 4 }, x is not shown).
Databases
Databases are sort of folders in which we store collections.
$ show dbs # list databases
$ use some_database_name # load or create
Collections
A collection is an array of JSON documents (=a table in SQL).
$ show collections # show non-empty collections
$ db.getCollection("name").XXX # do XXX on collection "name"
$ db.name.XXX # do XXX on collection "name"
Documents
A document is a record within a collection (ex: a user). It's a JSON (BJSON) object, and it's the same as a record/tuple in SQL.
{
"name": "John Doe",
"email": "john@example.com",
"addresses": { "main": null }
}
β οΈοΈ JSON documents in a collection may not have the same attributes.
βοΈ JSON keys are mostly called "attributes".
π Each document as a _id
attribute of type ObjectId
π "main" will most likely be an embed document.
Manipulate documents
Add documents
If a collection doesn't exist, it is created.
db.some_collection.insertOne( a_document )
db.some_collection.insertMany( [ a_document, ...] )
Delete documents
See also: deleteMany(JSONArray)
.
db.some_collection.deleteOne({ _id: ObjectId('some_id') })
Update documents
See also: updateMany(JSONArray, JSON)
.
db.some_collection.updateOne(
{ _id: ObjectId('some_id') }, // select
{
$set: { "name": "xxx" } // add or set attributes
}
)
You can use $unset: { "name": true }
to remove an attribute.
For nested documents, use:
$set: {
addresses: {
"main": { /* ... */ }
}
}
Find documents
You will use find
or variants to find documents. They usually take two arguments, and return a list of documents.
db.some_collection.find() // list all documents
db.some_collection.find({}, {}) // list all documents
db.some_collection.find(filter, projection) // ???
π For nested documents, use a dot, such as addresses.main
.
Filter parameter
The filter determined which documents are returned. It's optional, and by default, all documents are returned.
Here are some examples of filters:
{} // no filter
{ _id: ObjectId('id') } // find by ID
{ name: "xxx" } // filter by name ==
{ age: { $gte: 15 } } // filter by age >= 15
// $gt (>) $eq (=) $ne (<>)
// $ne (<>) $lt (<) $lte (<=)
{ name: { $exists: true } } // has an attribute "name"
{ $or: [ // see also: $and, $nor
{ name: 'XXX' },
{ name: 'YYY' }
] }
Projection parameter
The projection determines which attributes are returned. It's optional, and by default, all attributes are returned.
Here are some examples of projections:
{} // all
{ name: true } // name attribute only
Useful method chains
You may call some methods on the find
output.
db.xxx.find().size() // number of documents
db.xxx.find().skip(0) // skip n first results
db.xxx.find().limit(1) // only fetch n documents
db.xxx.find().skip(countPerPage * page).limit(countPerPage)
db.persons.find().sort({name: 1}) // sort ASC
db.persons.find().sort({name: -1}) // sort DESC
// ...
User management
You can create an administrator using:
$ mongo -u username --authenticationDatabase admin -p
use admin
db.createUser({
user: "username",
pwd:"password",
roles:[{ role: "userAdminAnyDatabase", db: "admin" }]
})
Then, you can create normal users using:
use database_name
db.createUser( { user: "myuser", pwd: "password", roles: ["readWrite"] })
π» To-do π»
Stuff that I found, but never read/used yet.
// mixed content
db.xxx.aggregate([
{ $unwind: "$xxx" },
{ $lookup: { from: "xxx", localField: "xxx", foreignField: "_id", as: "xxx" } },
{ $unwind: "$xxx" },
{ $sort: { "xxx": -1 } },
{ $group: { _id: "$xxx", yyy: { $first: "$xxx" } } },
{ $match: { xxx: "xxx" } },
{ $group: { _id: null, yyy: { $avg: "$xxx" } } }
{ $group: { _id: null, yyy: { $sum: { $multiply: ["$xxx", "$xxx"] } } } }
])