MongoDB CSC309 TA: Sukwon Oh
MongoDBCSC309 TA: Sukwon Oh
Review● SQL
○ “declarative” language for querying data○ tells what to find and not how to find
Review● RDBMS Characteristics
○ Easy to use○ Complicated to use it right○ Fixed schema○ Difficult to handle large amount of data
● Why?○ How the system works is hidden!
Review● NoSQL Philosophy (Not-Only SQL)
○ Simpler DB operations○ Complex query logic is moved to application code○ Relaxes ACID guarantees for better performance
Review● Types of NoSQL DB
○ Key-Value Store
○ Key-Data Structure Store
○ Key-Document Store
Why MongoDB?● To handle big amount of data● Better performance● Handle failures easily● Dynamic schema● Don’t need complex query operations● Your app is already using JSON● ...
Basics
Basics
Basics● Each DB has a set of collections● Each collection has a set of documents
○ Document looks like JSON format○ All documents have _id field with unique values
(primary key)● Each document contains a set of key-value
pairs
Sample Document{
“address”: {“building”: “1007”,“coord”: [-73.856077, 40.848447],“street”: “Morris Park Ave”,
...
How to use MongoDB?● First install MongoDB by following
instructions at https://www.mongodb.org/downloads
● Install node.js MongoDB driver (or any other language you want to use)○ npm install mongodb
Node.js Driver● MongoDB API that you can use from
express.js
● Supports CRUD operations○ CRUD - create, read, update, delete
Connecting to DBvar client = require(‘mongodb’).MongoClient;client.connect(url, function(err, db) {
console.log(‘connected!’);db.close(); // closes connection
});
MongoDB URI● Address of MongoDB instance you want to
connectmongodb://[username:password@]host[:port][/database][?options]● Example
○ ‘mongodb://localhost:27017/test’
Create● insertOne(), insertMany()
○ inserts 1 or multiple documents to a collection specified.
○ _id field is automatically generatedinsertOne Syntax:db.collection(‘collection’).insertOne(
{//document}, function(err, result){..});
CreateinsertMany Syntax:db.collection(‘collection’).insertMany(
[{//doc1}, {//doc2},...], function(err, result){..});
Read● Use find() to query DB
○ All queries are performed on a single collection○ Use filters to select only interesting documents
■ Similar to WHERE clause in SQL○ Returns cursor object, which you can use to iterate
over query results■ Use cursor.each() to look at individual document
Filter● Filters are in following format{<field1>: <value1>, <field2>: <value2>..}● Examples
○ {“borough”: “Manhattan”}○ {“addresses.zipcode”: “10075”}○ {“ratings”: [5,8,9]}○ {“ratings.0”: 5}
Examplevar cursor = db.collection(‘restaurants’).find({“borough”: “Manhattan”});cursor.each(function(err, doc) {
console.log(doc);});
Query Operators● Filter can be complex by using following
operators○ $or○ $gt○ $lt○ $elemMatch○ $eq○ ...
Query Operators{<field1>: {<operator1>: <value1>}}
● Examples○ {“grades.score”: {$gt: 30}}○ {ratings: {$elemMatch: {$gt: 5, $lt: 9}}}
Query Operators● Logical AND
○ Write multiple filters separated by commas
● Example○ {“cuisine”: “Italian”, “address.zipcode”: “10075”}
Query Operators● Logical OR
○ Use $or
● Examples○ {$or: [ {“cuisine”: “Italian”}, {“address.zipcode”:
“10075”} ] }
Sorting● Use .sort() method after .find()
○ Similar to ORDER BY in SQL● Accepts a document with keys to sort by and
values as 1 for ascending order and -1 or descending order
● Example○ {“borough”: 1, “address.zipcode”: -1}
Cursor methods● We have used each() but other methods are
available○ skip(# doc to skip)○ sort()○ next()○ toArray()○ map()
Update● updateOne(), updateMany(), replaceOne()● Accepts 3 paramters
○ a filter○ update value○ options
● Cannot update _id field!
Update Operators● $set to change a field value● $currentDate to update a field value to
current date● ...
UpdateupdateOne/updateMany Syntax:db.collection(‘collection’).updateOne/Many(
{//filter},{//update value},function(err, result) {..}
);
Exampledb.collection(‘restaurants’).updateMany(
{“address.zipcode”: “10016”, cuisine: “Other”},{
$set: {cuisine: “Category to be determined”},$currentDate: {“lastModified”: true}
},function(err, results) {
console.log(results);}
);
replaceOne● replaceOne() will only preserve field values
that are updated and throw away existing fields that are untouched!
● Same syntax as insertOne()
More on Update● By default, MongoDB does nothing when
none of documents are matched. However when upsert option is set to true, it will insert a new document if no matching documents are found.
Delete● deleteOne(), deleteMany()● Accepts a filter to choose which documents
to delete● Does not delete indexes or collections
○ Indexes are explained in next tutorial
DeleteSyntax:db.collection(‘collection’).deleteMany(
{//filter}, function(err, result) {..});
Exampledb.collection(‘restaurants’).deleteOne(
{“borough”: “Queens”},function(err, results) {
console.log(results);}
);
Drop● To completely remove a collection, consider
using drop()● Many be more efficient than deleteMany({})Syntax:db.collection(‘collection’).drop(function(err, results) {..});
Aggregation● Operates on multiple documents● Similar to the popular MapReduce paradigm● Perform stage-based aggregation
○ Example■ Stage 1: Filter out uninteresting documents■ Stage 2: Group documents by some key■ Stage 3: Count # of documents with same key
AggregationSyntax:db.collection.aggregate([<stage1>, <stage2>, ..])
Group Stage● Use $group to specify a stage{$group: {“_id”: “$key”, “field1”: {//accumulator}}
● Example○ {$group:{“_id”:”$borough”, “count”: {$sum: 1}}}
Accumulators● Only available in group stage and computes
values by combining documents with same key○ $sum○ $avg○ $max○ $min
Match Stage● Filters documents● Uses query syntax from before{$match: {//filter}}
Exampledb.collection(‘restaurants’).aggregate(
[{$match: {“borough”: “Queens”, “cuisine”: “Brazilian”}},{$group: {“_id”: “$address.zipcode”, “count”: {$sum: 1}}}
]).toArray(function(err, result) {
console.log(result);});