MongoDB Basics « »
February 10, 2016
Mongo uses BSON format.
Config file
- Specific data directory
- Logging verbosity
- Log file name and location
mongod -f mongod.conf
mongod.conf
# where data files will reside
dbpath=/myfolder/db
# where the log file will be stored
logpath=/myfolder/mongo-server.log
# how verbose the server will be logging
verbose=VVVVV
Basic Commands
mongo
exit //exits cli
show dbs
use foo //use databasename
db //shows currents databse
help
show collections
db.foo.save({_id:1, value:'hello world'}) //save one object to foo collection
db.foo.find() //all documents in foo collection
db.foo.find().pretty() //prettifies the documents got from find collection
ObjectId() // returns a unique identifier any time. It is an object
ObjectId().getTimestamp()
Rules
- A document must have an _id field
- A document size can be not above 16MB
Mongo accepts anything as an ID but an array
Save vs Insert
When working with _ids, insert will prevent us of overwritting a value once is already created. Save, let us update a document once it’s already existing. But in fact they are aweful for concurrency, so it’s recomended to use update command.
Update
Two concurrent updates will be executed one after the other.
db.foo.update(query,update,options);
//query -> which document
//update -> what change
//options -> one?many?upsert? Upsert means we can create a new document if it doesn't exist.
- $inc
- $set
- $rename
db.a.save({_id:1, x:10});
db.a.update({_id:1}, {$inc: {x:1}}) //increments x by one
db.a.find()
// in the following two sentences we are able to touch properties of the document, but not overwritting it all
db.a.update({_id:1}, {$set:{y:3}});
db.a.update({_id:1}, {$inc:{x:1}});
//unsetting a property of the document
db.a.update({_id:1}, {$unset: {y: ''}}) // in this case '' it's arbitrary, any value would be correct
db.a.save({_id:1, Naem: 'bob'})
db.a.update({_id:1}, {$rename: {'Naem': 'Name'}})
Array ops
It doesn’t need to have an array to be able to run this commands:
- push
- addToSet
- pull
- pop
db.a.update({_id:1}, {$push: {things: 'one'}})
db.a.update({_id:1}, {$addToSet: { things: 'four'}}) // only adds the element if does not exist already
db.a.update({_id:1}, {$pull : {things: 'three'}}) //remove all instances of the element 'three'
db.a.update({_id:1}, {$pop: {things: 1}}) //last element in the array
db.a.update({_id:1}, {$pop: {things: -1}}) //first element in the array
Update multiple fields
db.a.uptade({}, {$push: {things: 4}}, {multi:true});
db.a.update({things:2}, {$push: {things:42}}, {multi:true}) //update all the documtns that have an array things with the value 2
Update only one record with the criteria
That’s why we also use the sort param. So if there’s more than one will pick the one
db.foo.findAndModifiy({
quere: <document>,
update: <document>,
upsert: <boolean>, //create a new record if it doesn't exist
remove: <boolean>,
new: <boolean>, //return the new document or the old before the changes
sort: <document>,
fields: <document>
});
var mod = {
"query" : {
"things" : 1
},
"update" : {
"$set" : {
"touched" : true
}
},
"sort" : {
"_id" : -1 //sort by id in descending order
}
};
db.a.findAndModifiy(mod);
mod.update.$set.touched = false;
mod.new = true; // now we are asking to get the modifiet version of the object
Finding Documents
db.foo.find(query, projection); //documents, fields (otherwise all the document will be shown)
db.animals.find({_id: 1});
db.animals.find({_id:1}, {_id:1}) //show only id
db.animals.find({_id: {$gt:5}}, {_id:1}) //fing id greater than 5
db.animals.find({_id: {$gt:2, $lt:4}}, {_id:1})
db.animals.find({_id: {$not: {$gt:2}}}, {_id:1})
db.animals.find({_id: {$in: [1,3]}}, {_id:1}) //values in 1 or 3, shoing id only
db.animals.find({_id: {$nin: [1,3]}}, {_id:1}) //values NOT in 1 or 3
And
db.animals.find({animal: 'bird', tags: 'ocean'}, {name:1}) //both tags and animal
Arrays
db.animals.find({tags: 'cute'}, {name:1})
db.animals.find({tags: {$in: ['cute','ocean']}}, {name:1})
db.animals.find({tags: {$all: ['cute','ocean']}}, {name:1}) //if must be cute and ocean
Nested information
db.animals.find({"info.canFly": true}).pretty()
db.animals.find({"info.canFly": {$exists: true}}, {name:1}) //exists works better for null values
Showing hiding fields
_id always shows implicitly.
db.animals.find({_id:1},{_id:1,name:1}) //show
db.animals.find({_id:1}, {_id:0,name:0,info:0}) //not showing id,name,info
Cursor
var c = db.animals.find({},{name:1})
c.size()
c.hasNext()
c.forEach(function(d){print(d.name)})
Sort
db.animals.find({},{name:1}).sort({name:1}) //ascending
db.animals.find({},{name:1}).sort({name:-1}) //descending
db.animals.find({},{name:1,"info.type":1}).sort({"info.type":1, "name": 1})
Limit
db.animals.find({},{_id:1}).sort({_id:-1}).limit(3);
Skip
Useful for pagination
db.animals.find({},{_id:1}).sort({_id:-1}).skip(1).limit(2);
findOne
db.animals.findOne({_id:1})
Indexing
It’s very important to use indexes.
- Regular (B-Tree)
- Geo (for proximity)
- Text
- Hashed
- TTL (expiring documents)
db.foo.ensureIndex(keys, options)
//keys: which fields, in what order
//options: name? build now? unique? sparse? ttl? language?
db.system.indexes.find({ns:'test.animals'},{key:1})
db.animals.find({name:cat}).explain()
db.animals.ensureIndex({name:1})
Drop Index
There’s always an _id, all the _ids have an index.
db.animals.dropIndex("name_1")
Indexing nested fields and arrays
db.animals.ensureIndex({"info.color": 1})
db.animals.ensureIndex({tags:1}) //we can also create indexes for arrays
Unique
db.animals.ensureIndex({name:1},{unique:true})
Sparse
Sparse indexes only contain entries for documents that have the indexed field, even if the index field contains a null value. The index skips over any document that is missing the indexed field. The index is “sparse” because it does not include all documents of a collection.
db.animals.count()
db.animals.count({"info.color": {$exists:true}})
db.animals.ensureIndex({"info.color":1},{sparse:true})
Compound Indexes
They are useful if the queries match the index definition from left fo right!
db.animals.ensureIndex({tags:1,name:1})