- no support for joins
- no support for transactions
- is schemaless
- across multiple collections
- data stored in documents
To Retain Scalability, MongoDB
1. dont support joins,
2. don't support transaction management - Docs are hierarchical, so docs can be accessed automically
scalability and Functionality
High Performance
High Performance
Mongo DB - non-relational json document store
{'firstname':'Andrew',
'lastname':'ericson',
'hobbies':['cycling', 'golf', 'photography']}
mongo shell
use test --- to database test
db.things.save({a:1, b:2}) --save a row
db.things.find() --find all document records of things documents
db.things.save({a:2, b:3, d:4}) --save another row
db.things.find({a:1}) --finds first record
Easy to program because it stored in JSON
array: list of things [...] [red,green]
Dictonary : maps {key:val,} {a:b, c:d}
Top level in document has to be distionary
{fruid:[apple, pear, manogoe]}db.user({'name':'andrew', 'city':'london'})
Changing schema of a document:
var j=db.user.findOne({'name':'andrew'})
j.city='paris'
db.user.save()
allowed size of doc - 16mb
restore command - mongodump mongorestore
connect with shell - mongo
findOne Command
{"name":"andrew"}
{"a":4, "b":5, "c":7}
{a:6, b:7, fruit:["apple", "pear", banana"]}
Connecting MongoDB
MongoShell<->MongoDB->
Java Code
->SparkJava
->FreeMarker -MVC
MongoJava Driver ->TCP Connection to MongoD
Port - 80, 8082
MongoShell
start mongo shell
mongo
>use test
switch to db test
>db.things.save({a:1, b:2, c:3})
saved in collection things
>db.things.find()
will return 1 document
>db.things.save({a:3, b:4, c:6, d:200})
>db.things.find()
will return two documents
>db.things.find({a:1})
>db.things.save({a:3, b:4, c:6, d:{k:200}})
>db.things.find.preety()
Mongo DB Operations comparison
Ops - Mongo - SQL
Create - Insert - Insert
Read - Find - Select
Update - Update - Update
Delete - Remove - Delete
$mongo - open mongo shell, connects with db and display version of mongodb
->mongo shell is interactive javascript interpretor
-mongoshell contains doskey, up arrow, down arrow key, left arrow and right arrow key for editing
use tab to autocomplete the token in mongoshell
z={a:1}
z.a will return 1
z["a"] will return 1
difference in above is in z.a, a is not considered literal, i.e.
if i say w="a"
then z[w] will return 1 but not in the case of using dot (.) notation. reason is dot(.) notation look for reference or member variable in an object, but the square [] notation treats object more as a pirce of data or dictionary
BSON - binary JSON - Contains all datatypes of JSON
NumberInt(1)
NumberLong(1)
new Date() -> ISODate("2012-10-21T17:41:51.398Z")
use above constructor syntaxes to create objects of number, date etc.
Inserting documents in MongoDB
doc={"name":"smith", "Age":30}
db.people.insert(doc)
db.people.find()
above row will be returned.
All documents insterted in mongodb will have an id, "_id" primary key is unique. This value is immutable, it cannot be changed.
findOne()
db.people.findOne() - selects a random document from the collection people.
db.people.findOne({"name":"Jones"})
selects a document having value of name field as "Jones"
second argument can be used to specify which field will be returned from database.
db.people.findOne({"name":"Jones"}, {"name":true, "_id":false})
->{"name":"Jones"}
if we don't say "_id":false, it will be returned from DB as default behavior.
find()
inserting records using a loop
for(i=0; i<1000 db.scores.insert="" essay="" exam="" for="" i="" j="" names="" quiz="" score="Math.round(Math.random()*100});}}</p" student="" type="">
3000 rows will be inserted.
db.scores.find() - will return 3000 records, but page wise, 20 records per page. type "it" for iterating to next page.
getting formatted output - use pretty() function
db.scores.find().pretty()
Querying using selection
using AND operation
db.scores.find({student:19, type:"essay"})
will select the rows having student id 19 and type essay
$gt and $lt opearator
db.scores.find({score:{$gt:95}})
will return all records having score value greater than 95
db.scores.find({score:{$gt:95}, type:"essay"})
will return all records having score value greater than 95 and type is equal to "essay"
putting more constraints on score
1000>
db.scores.find({score:{$gt:95, $lte:98})
$lte means less than or equal to
$gt means greater than
inequality comparison
db.people.find({name:{$lt:"D"}});
will return all the names starting from A, B or C.
db.people.find({name:{$lt:"D", $gt:"B"}});
will return all the names starting from B, or C.
db.people.insert({name:42});
db.people.find({name:{$lt:"D", $gt:"B"}});
will not select the record having name=42.
Mogodb allows to query based on structure of document and type of values in document
For exmaple
{"name":"Smith", "age":30, "profession":"hacker"}
{"name":"Jones", "age":35, "profession":"baker"}
{"name":"Alice"}
{"name":"Bob"}
{"name":42}
find all the records having field profession
db.people.find({profession:{$exists:true}});
below records will be selected
{"name":"Smith", "age":30, "profession":"hacker"}
{"name":"Jones", "age":35, "profession":"baker"}
find all the records having field profession
db.people.find({profession:{$exists:false}});
will select all records not have profession field value
type based selection
for selecting records having value of name field as string
db.people.find({name:{$type:2}})
type:2 is for String as per BSON Specs.
$regex
Find all rows field name having value containing "a"
db.people.find({name:{$regex:"a"}});
Find all rows field name having value containing "e" as last letter
db.people.find({name:{$regex:"e$"}});
Find all rows field name field start with "A"
db.people.find({name:{$regex:"^A"}});
$or
$or operator is used as key and value is a array of conditions
db..people.find({$or:[name:{$regex:"e$"}}, {age:{$exists:true}}]};
find all rows having name ending with "e" or all rows containing age attribute.
$and
db.people.find({$and:[name:{$regex:"e$"}}, {age:{$exists:true}}]};
Querying inside arrays
Arrays can be queried at the top level
db.account.insert({name:"Howard", favouriutes:["pretzels", "beer"]});
db.accounts.find({favourites:"pretzels"});
Which of the following documents would be returned by this query?
db.products.find( { tags : "shiny" } );
{ _id : 42 , name : "Whizzy Wiz-o-matic", tags : [ "awesome", "shiny" , "green" ] }
{ _id : 1040 , name : "Snappy Snap-o-lux", tags : "shiny" }
db.accounts.find().pretty(); -display in a format
{name:"Howard", favourites:["pretzels", "beer"]}
{name:"Irving", favourites:["pretzels", "beer", "cheese"]}
$all - Finding all rows which contain all elements of the given array in filtr, for ex
db.accounts.find({favourites:{$all:[""pretzels", "beer"]}});
will display both above records because both records contain "pretzels" and "beer"
$in - Finding all rows which contain any of the elements of the given array in filter, for ex
db.accounts.find({favourites:{$in:[""pretzels", "beer"]}});
Querying nested docs with dot notation
{name:"richard", email:{work:"richard@10gen.com", personal:"kreuter@example.com"}}
db.users.find({email:{work:"richard@10gen.com", personal:"kreuter@example.com"}})
this will return above record, by byte by byte comparison. but if you change the order of elements, query will not find the document
for example:
db.users.find({email:{personal:"kreuter@example.com", work:"richard@10gen.com"}})
or below will also not work
db.users.find({email:{work:"richard@10gen.com"}})
how to query embeded fields
db.users.find({"email.work":"richard@10gen.com"})
this will return by looking the contents of embeded field email
Cursors--
cur=db.people.find();null;
cur.hasNext() -> Return true
cur.next() -> Return next row
while(cur.hasNext())printJson(cur.next());
impose limit
cur.limit(5);null;
cur.sort({name:-1}); null;->sort in reverse order
cur.sort({name:-1}).limit(3); null; -> will not print top 3
counting results:
db.scores.count({type:"exam"})
return count of rews requrned from aboive query.
replacing data in DB
db.people.update({name:"Smith"}, {name:"Thompson", salary:50000});
First argument {namne:"Smith"} is where clause
Second argument {name:"Thompson", salary:50000} is the new values updating the existing values of fields. It will discard the previous vlaues of the fields . for example
> db.foo.insert({ "_id" : "Texas", "population" : 2500000, "land_locked" : 1 });
WriteResult({ "nInserted" : 1 })
> db.foo.update({_id:"Texas"},{population:30000000})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.foo.find();
{ "_id" : "Texas", "population" : 30000000 }
updating specific field of a collection using $set
> db.foo.find({"_id" : "Poland"});
{ "_id" : "Poland", "population" : 2500000, "land_locked" : 2 }
> db.foo.update({"_id" : "Poland"}, {$set:{"population" : 200000}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.foo.find({"_id" : "Poland"});
{ "_id" : "Poland", "population" : 200000, "land_locked" : 2 }
If the field does not exist, new field with set value is created, e.g.
> db.foo.update({"_id" : "Poland"}, {$set:{"language" : "Polish"}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.foo.find({"_id" : "Poland"});
{ "_id" : "Poland", "population" : 200000, "land_locked" : 2, "language" : "Polish" }
$inc - increasing value of a field
> db.foo.update({"_id" : "Poland"}, {$inc:{"population" : 1}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.foo.find({"_id" : "Poland"});
{ "_id" : "Poland", "population" : 200001, "land_locked" : 2, "language" : "Polish" }
update will not create any new row if it does not exist
> db.foo.update({"_id" : "Englad"}, {$inc:{"population" : 1}});
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
> db.food.find({"_id" : "Englad"});
>
But update will add a new field if it does not exist
> db.foo.insert({ "_id" : "England", "land_locked" : 2 });
WriteResult({ "nInserted" : 1 })
> db.foo.update({"_id" : "England"}, {$inc:{"population" : 1}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.foo.find({"_id" : "England"});
{ "_id" : "England", "land_locked" : 2, "population" : 1 }
$inc operator can only be applied to numeric value. $inc operator can add new field but $set operator cannot add new field.
$unset - remove a field from document
> db.users.find({ "_id" : "myrnarackham"});
{ "_id" : "myrnarackham", "phone" : "301-512-7434", "country" : "RU" }
> db.users.update({ "_id" : "myrnarackham"}, {$unset:{"country":"RU"}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find({ "_id" : "myrnarackham"});
{ "_id" : "myrnarackham", "phone" : "301-512-7434" }
> db.users.update({ "_id" : "myrnarackham"}, {$unset:{"phone":"1"}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find({ "_id" : "myrnarackham"});
{ "_id" : "myrnarackham" }
Using $push, $pop, $pull, $pushAll, $pullAll, $addToSet
> db.friends.insert({_id : "Mike", interests : [ "chess", "botany" ] });
WriteResult({ "nInserted" : 1 })
> db.friends.update( { _id : "Mike" }, { $push : { interests : "skydiving" } } );
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.friends.find()
{ "_id" : "Mike", "interests" : [ "chess", "botany", "skydiving" ] }
> db.friends.update( { _id : "Mike" }, { $pop : { interests : -1 } } );
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.friends.find()
{ "_id" : "Mike", "interests" : [ "botany", "skydiving" ] }
> db.friends.update( { _id : "Mike" }, { $addToSet : { interests : "skydiving" } } );
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
> db.friends.find()
{ "_id" : "Mike", "interests" : [ "botany", "skydiving" ] }
> db.friends.update( { _id : "Mike" }, { $pushAll: { interests : [ "skydiving" , "skiing" ] } } );
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.friends.find()
{ "_id" : "Mike", "interests" : [ "botany", "skydiving", "skydiving", "skiing" ] }
$upsert- insert a record if it does not exist, or update the existing one. example
After performing the following update on an empty collection
db.foo.update( { username : 'bar' }, { '$set' : { 'interests': [ 'cat' , 'dog' ] } } , { upsert : true } );
{ "_id" : ObjectId("507b78232e8dfde94c149949"), "interests" : [ "cat", "dog" ], "username" : "bar" }
Removing Documents - Deleting documents from Database.
> db.people.insert({"name":"Alice", "age":20, sex:"f"})
WriteResult({ "nInserted" : 1 })
> db.people.insert({"name":"John", "age":20, sex:"m"})
WriteResult({ "nInserted" : 1 })
> db.people.insert({"name":"Ran", "age":20, sex:"f"})
WriteResult({ "nInserted" : 1 })
> db.people.insert({"name":"Mony", "age":25, sex:"f"})
WriteResult({ "nInserted" : 1 })
> db.people.insert({"name":"Ricky", "age":30, sex:"m"})
WriteResult({ "nInserted" : 1 })
> db.people.insert({"name":"Aster Krtor", "age":24, sex:"m"})
WriteResult({ "nInserted" : 1 })
Works like find() command. Receives argument to filter the rows to remove
> db.people.remove({name:"Alice"})
WriteResult({ "nRemoved" : 1 })
If you want to remove all documents of the collection "people"
> db.people.remove({})
WriteResult({ "nRemoved" : 5 })
> db.people.find()
If you want to remove more efficiently, use drop
db.people.drop()
drop() function is different from remove(). Remove updates collection one by one, but drop removes whole collection datafile at ones.
Document removal is an atomic operation and no document is half removed.