From 129d2d1b43d2d847ac89388a23b927cdeae274ce Mon Sep 17 00:00:00 2001 From: Matt Huntington Date: Fri, 19 Feb 2016 20:01:20 -0500 Subject: [PATCH] Added files via upload --- 1.MONGO.md | 136 +++++++++++++++++++++++++++++++ 10.MONITOR.md | 18 +++++ 11.GEO_SPACIAL.md | 171 +++++++++++++++++++++++++++++++++++++++ 2.MONGO_UPDATE.md | 46 +++++++++++ 3.MONGOOSE.md | 114 ++++++++++++++++++++++++++ 4.MAP_REDUCE.md | 71 ++++++++++++++++ 4.MONGO_ADVANCED_FIND.md | 27 +++++++ 5.BACKUP_RESTORE.md | 13 +++ 6.ADVANCED_MONGOOSE.md | 170 ++++++++++++++++++++++++++++++++++++++ 7.MONGO_AGGREGATION.md | 37 +++++++++ 8.MONGO_STRUCTURE.md | 43 ++++++++++ 9.PERFORMANCE.md | 43 ++++++++++ 12 files changed, 889 insertions(+) create mode 100644 1.MONGO.md create mode 100644 10.MONITOR.md create mode 100644 11.GEO_SPACIAL.md create mode 100644 2.MONGO_UPDATE.md create mode 100644 3.MONGOOSE.md create mode 100644 4.MAP_REDUCE.md create mode 100644 4.MONGO_ADVANCED_FIND.md create mode 100644 5.BACKUP_RESTORE.md create mode 100644 6.ADVANCED_MONGOOSE.md create mode 100644 7.MONGO_AGGREGATION.md create mode 100644 8.MONGO_STRUCTURE.md create mode 100644 9.PERFORMANCE.md diff --git a/1.MONGO.md b/1.MONGO.md new file mode 100644 index 0000000..4607152 --- /dev/null +++ b/1.MONGO.md @@ -0,0 +1,136 @@ +# Databases - Mongo + +## Lesson Objectives +1. show +1. use +1. create collection +1. insert +1. dropping +1. find +1. remove +1. count + +## Show +1. `show dbs` + +## Use +1. `use learn` +1. `db` + - show current database being used + +## create collection +1. `db.createCollection('testCollection')` + +## Insert +1. `db.testCollection.insert({foo:'true'})` +1. multi-lines +1. `show collections` +1. can use regular javascript with variables and functions + - watch out for cursors from find() +1. can insert array of objects + +## Dropping +1. `db.dropDatabase();` +1. `db.collection.drop();` + +## Find +``` +db.employees.insert([{ + name: 'Daisy', + dob: new Date(1992,2,13,7,47), + loves: ['carrot','papaya'], + weight: 600, + gender: 'm', + salary: 63 +},{ + name: 'Aurora', + dob: new Date(1991, 0, 24, 13, 0), + loves: ['carrot', 'grape'], + weight: 450, + gender: 'f', + salary: 43 +},{ + name: 'Unicrom', + dob: new Date(1973, 1, 9, 22, 10), + loves: ['energon', 'redbull'], + weight: 984, + gender: 'm', + salary: 182 +},{ + name: 'Roooooodles', + dob: new Date(1979, 7, 18, 18, 44), + loves: ['apple'], + weight: 575, + gender: 'm', + salary: 99 +},{ + name: 'Solnara', + dob: new Date(1985, 6, 4, 2, 1), + loves:['apple', 'carrot','chocolate'], + weight:550, + gender:'f', + salary:80 +},{ + name:'Ayna', + dob: new Date(1998, 2, 7, 8, 30), + loves: ['strawberry', 'lemon'], + weight: 733, + gender: 'f', + salary: 40 +},{ + name:'Kenny', + dob: new Date(1997, 6, 1, 10, 42), + loves: ['grape', 'lemon'], + weight: 690, + gender: 'm', + salary: 39 +},{ + name: 'Raleigh', + dob: new Date(2005, 4, 3, 0, 57), + loves: ['apple', 'sugar'], + weight: 421, + gender: 'm', + salary: 2 +},{ + name: 'Leia', + dob: new Date(2001, 9, 8, 14, 53), + loves: ['apple', 'watermelon'], + weight: 601, + gender: 'f', + salary: 33 +},{ + name: 'Pilot', + dob: new Date(1997, 2, 1, 5, 3), + loves: ['apple', 'watermelon'], + weight: 650, + gender: 'm', + salary: 54 +},{ + name: 'Nimue', + dob: new Date(1999, 11, 20, 16, 15), + loves: ['grape', 'carrot'], + weight: 540, + gender: 'f' +},{ + name: 'Dunx', + dob: new Date(1976, 6, 18, 18, 18), + loves: ['grape', 'watermelon'], + weight: 704, + gender: 'm', + salary: 165}]); +``` + +1. `db.employees.find({gender:'m'})` +1. `db.employees.find({weight : { $gt : 700 }})` + - $lt, $lte, $gt, $gte, $ne, $exists: false, $in: ['orange', 'apple'] +1. `db.employees.find({loves:'energon'})` + - if field is array, will return search within that array +1. AND + - `db.employees.find({gender: 'm', weight: {$gt: 700}})` +1. OR + - `db.employees.find({gender: 'f', $or: [{loves: 'apple'},{weight: {$lt: 500}}]})` +1. value between + - `db.employees.find( { salary: { $gte : 80, $lte : 165} } );` + +## Remove +## Count diff --git a/10.MONITOR.md b/10.MONITOR.md new file mode 100644 index 0000000..f65c0d2 --- /dev/null +++ b/10.MONITOR.md @@ -0,0 +1,18 @@ +# Mongo - Monitoring + +## Lesson Objectives +1. Explain explain +1. Explain stats +1. Explain profile + +## Explain Explain +1. `db.employees.find().explain()` + +## Explain stats +1. `db.stats()` +1. `db.collectionName.stats()` + +## Explain profile +1. `db.setProfilingLevel(2);` +1. `db.employees.find();` +1. `db.system.profile.find()` diff --git a/11.GEO_SPACIAL.md b/11.GEO_SPACIAL.md new file mode 100644 index 0000000..b92971c --- /dev/null +++ b/11.GEO_SPACIAL.md @@ -0,0 +1,171 @@ +# Mongo - GeoSpacial + +## Lesson Objectives +1. Explain GeoSpacial +1. Explain GeoJSON +1. Explain containers +1. Explain How To Create an Index +1. Explain $near +1. Explain $geoWithin +1. Explain $geoIntersects + +## Explain GeoSpacial + +## Explain GeoJSON +1. `{ type: "" , coordinates: }` +1. Always list coordinates in `longitude`, `latitude` order. +1. point + - `{ type: "Point", coordinates: [ 40, 5 ] }` +1. line + - `{ type: "LineString", coordinates: [ [ 40, 5 ], [ 41, 6 ] ] }` +1. polygons + - array of coordinate arrays (rings) + - at least four points and have same start/end position + - one outer ring and 0+ inner rings + - cannot self intersect + - single ring + - `{ type: "Polygon", coordinates: [ [ [ 0 , 0 ] , [ 3 , 6 ] , [ 6 , 1 ] , [ 0 , 0 ] ] ] }` + - multiple rings + - 1st ring is outer ring + - Any interior ring must be entirely contained by the outer ring + - Interior rings cannot intersect or overlap each other + - Interior rings cannot share an edge. + - http://docs.mongodb.org/manual/_images/index-2dsphere-polygon-with-ring.png + ``` + { + type : "Polygon", + coordinates : [ + [ [ 0 , 0 ] , [ 3 , 6 ] , [ 6 , 1 ] , [ 0 , 0 ] ], + [ [ 2 , 2 ] , [ 3 , 3 ] , [ 4 , 2 ] , [ 2 , 2 ] ] + ] + } + ``` + +## Explain containers +1. MultiPoint +``` +{ + type: "MultiPoint", + coordinates: [ + [ -73.9580, 40.8003 ], + [ -73.9498, 40.7968 ], + [ -73.9737, 40.7648 ], + [ -73.9814, 40.7681 ] + ] +} +``` +1. MultiLineString +``` +{ + type: "MultiLineString", + coordinates: [ + [ [ -73.96943, 40.78519 ], [ -73.96082, 40.78095 ] ], + [ [ -73.96415, 40.79229 ], [ -73.95544, 40.78854 ] ], + [ [ -73.97162, 40.78205 ], [ -73.96374, 40.77715 ] ], + [ [ -73.97880, 40.77247 ], [ -73.97036, 40.76811 ] ] + ] +} +``` +1. MultiPolygon +``` +{ + type: "MultiPolygon", + coordinates: [ + [ [ [ -73.958, 40.8003 ], [ -73.9498, 40.7968 ], [ -73.9737, 40.7648 ], [ -73.9814, 40.7681 ], [ -73.958, 40.8003 ] ] ], + [ [ [ -73.958, 40.8003 ], [ -73.9498, 40.7968 ], [ -73.9737, 40.7648 ], [ -73.958, 40.8003 ] ] ] + ] +} +``` +1. GeometryCollection +``` +{ + type: "GeometryCollection", + geometries: [ + { + type: "MultiPoint", + coordinates: [ + [ -73.9580, 40.8003 ], + [ -73.9498, 40.7968 ], + [ -73.9737, 40.7648 ], + [ -73.9814, 40.7681 ] + ] + }, + { + type: "MultiLineString", + coordinates: [ + [ [ -73.96943, 40.78519 ], [ -73.96082, 40.78095 ] ], + [ [ -73.96415, 40.79229 ], [ -73.95544, 40.78854 ] ], + [ [ -73.97162, 40.78205 ], [ -73.96374, 40.77715 ] ], + [ [ -73.97880, 40.77247 ], [ -73.97036, 40.76811 ] ] + ] + } + ] +} +``` + +## Explain How To Create an Index +1. `db.collection.createIndex( { : "2dsphere" } )` + +## Explain $near +``` +db.test_data.insert({name: 'north', position : { type: "Point", coordinates: [0,1] } }); +db.test_data.insert({name: 'east', position : { type: "Point", coordinates: [1,0] } }); +db.test_data.insert({name: 'south', position : { type: "Point", coordinates: [0,-1] } }); +db.test_data.insert({name: 'west', position : { type: "Point", coordinates: [-1,0] } }); +db.test_data.createIndex({position: "2dsphere"}); + +db.test_data.find({ + position: { + $near : { + $geometry: { + type: "Point", + coordinates: [ 2, 0 ] + }, + $minDistance: 0, + $maxDistance: 200000 + } + } +}); +``` + +## Explain $geoWithin +``` +db.test_data.find({ + position: { + $geoWithin: { + $geometry: { + type : "Polygon" , + coordinates: [[ + [ 0.5, 0.5 ], + [ 1.5, 0.5 ], + [ 1.5, -0.5 ], + [ 0.5, -0.5 ], + [ 0.5, 0.5 ], // VERY IMPORTANT + ]] + } + } + } +}); +``` +## Explain $geoIntersects +``` +db.test_data.insert({ name : 'line' , "position" : { "type" : "LineString", "coordinates" : [ [1,0], [2,0] ] } } ); +WriteResult({ "nInserted" : 1 }); + +db.test_data.find({ + position: { + $geoIntersects: { + $geometry: { + type : "Polygon" , + coordinates: [[ + [ 0.5, 0.5 ], + [ 1.5, 0.5 ], + [ 1.5, -0.5 ], + [ 0.5, -0.5 ], + [ 0.5, 0.5 ], // VERY IMPORTANT + ]] + } + } + } +}); +``` \ No newline at end of file diff --git a/2.MONGO_UPDATE.md b/2.MONGO_UPDATE.md new file mode 100644 index 0000000..5a6eaea --- /dev/null +++ b/2.MONGO_UPDATE.md @@ -0,0 +1,46 @@ +# Mongo - Update + +## Lesson Objectives +1. Explain how to replace a record +1. Explain how to update certain values for a record +1. Explain update operators +1. Explain upserts +1. Explain multiple updates + +## Explain how to replace a record +1.`db.employees.update({name:'Roooooodles'}, {weight: 590})` + +## Explain how to update certain values for a record +``` +db.employees.update( + {weight: 590}, + {$set: { + name: 'Roooooodles', + dob: new Date(1979, 7, 18, 18, 44), + loves: ['apple'], + gender: 'm', + salary: 99}}) +``` + +## Explain update operators +1. `db.employees.update({name: 'Pilot'}, {$inc: {salary: -2}})` +1. `db.employees.update({name: 'Pilot'}, {$mul: {salary: (1/2)}})` +1. `db.employees.update({name: 'Aurora'}, {$push: {loves: 'sugar'}})` +1. `db.employees.update({name: 'Aurora'}, {$pop: 1})` +1. `db.employees.update({name: 'Aurora'}, {$unset: {loves: ''}})` +1. `db.employees.update({name: 'Aurora'}, {$rename: {wrong_field_name : 'correct_field_name'}})` +1. http://docs.mongodb.org/manual/reference/operator/update/#update-operators + +## Explain multiple updates +1. update() updates first entry +``` +db.employees.update( + {}, + {$set: {vaccinated: true}}, + {multi:true}); +db.employees.find({vaccinated: true}); +``` + +## Explain upserts +1. `db.hits.update({page: 'employees'}, {$inc: {hits: 1}}); db.hits.find();` +1. `db.hits.update({page: 'employees'}, {$inc: {hits: 1}}, {upsert:true}); db.hits.find();` diff --git a/3.MONGOOSE.md b/3.MONGOOSE.md new file mode 100644 index 0000000..06fc87a --- /dev/null +++ b/3.MONGOOSE.md @@ -0,0 +1,114 @@ +# Mongo - Mongoose + +## Lesson Objectives +1. Explain ODM +1. Explain Schema +1. Explain Create/Save +1. Explain Find +1. Explain Update +1. Explain Remove +1. Explain Helper Functions + +## Explain ODM + +## Explain Schema + +article.js + +```javascript +var mongoose = require('mongoose'); +mongoose.set('debug', true); +var Schema = mongoose.Schema; + +var articleSchema = new Schema({ + title: { type: String, required: true, unique: true }, + author: { type: String, required: true }, + body: String, + comments: [{ body: String, date: Date }], + date: { type: Date, default: Date.now }, + hidden: Boolean, + meta: { + votes: Number, + favs: Number + } +}); + +//Creating an Article class -- will be stored in 'articles' collection +var Article = mongoose.model('Article', articleSchema); + +module.exports = Article; +``` +1. String +1. Number +1. Date +1. Boolean +1. Mixed +1. ObjectId +1. Array + +## Explain Create/Save +```javascript +var mongoose = require('mongoose'); +var db = mongoose.connection; +var Article = require('./article.js'); + +//Setting up a new article +var newArticle = new Article({ + title: 'Awesome Title', + author: 'Matt' +}); + +newArticle.hidden = false; + +//connect to mongo +mongoose.connect('mongodb://localhost:27017/example'); + +//if the connection fails +db.on('error', function(){ + console.log('error'); +}); + +db.once('open', function() { + //we're connected! + //save article to the database + newArticle.save(function(err, article) { + if(err) { + console.log(err); + } else { + console.log(article); + } + mongoose.connection.close(); + }); +}); +``` + +## Explain Find +```javascript +Article.find({author:'Matt'}, 'name -_id',function(err, articles){ + console.log(articles); + mongoose.connection.close(); +}) +``` + +## Explain Update +```javascript +Article.update({ author: 'Matt' }, { $set : { author: 'Matthew' } }, { multi: true }, function (err, response) {...}); +``` + +## Explain Remove +```javascript +Article.remove({author:'Matt'}, function(err){...}); +``` +```javascript +Article.findOne({title:'Harry Potter'}, function(err, article){ + article.remove(); +}); +``` + +## Explain Helper Functions +1. findById +1. findOne +1. findByIdAndUpdate +1. findByIdAndRemove +1. findOneAndUpdate +1. findOneAndRemove diff --git a/4.MAP_REDUCE.md b/4.MAP_REDUCE.md new file mode 100644 index 0000000..06defd1 --- /dev/null +++ b/4.MAP_REDUCE.md @@ -0,0 +1,71 @@ +# Mongo - MapReduce + +## Lesson Objectives +1. Explain what MapReduce is and why we have it +1. Explain structure of Map Reduce +1. Explain map function +1. Explain reduce function +1. Explain aggregating multiple values +1. Explain Multiple group by + +## Explain what MapReduce is and why we have it + +## Explain structure of Map Reduce +1. db.collectionName.mapReduce(mapFunction, reduceFunction, { query: {}, out:{} }) +1. out + - collection name + - { [ replace | inline | merge | reduce ]: 1 } + +## Explain map function +1. return key=>value pair +``` +var emitter = function (){ + if(this.gender === 'm'){ + emit(this.name, { yum : this.loves[0], weight:this.weight }); + } +} +db.employees.mapReduce(emitter, function(){}, {out:'mapTest'}); +``` + +## Explain reduce function +1. if multiple values for a key, how to reduce +``` +var emitter = function (){ + emit(this.gender, this.weight); +} +var reducer = function (key, values){ + return Array.sum(values); +} +db.employees.mapReduce(emitter, reducer, {out:'mapTest'}); +``` + +## Multiple values +```javascript +var emitter = function (){ + emit(this.gender, { weights: this.weight, money: this.salary }); +} +var reducer = function(key, values){ + var total_weight = 0; + var total_salary = 0; + for(var i=0; i, ]);` +1. http://docs.mongodb.org/manual/_images/aggregation-pipeline.png + +## Explain some basic aggregation functions +1. `{ $match : { weight : { $lt : 600 } } }` +1. `{ $sort : { salary : -1 } }` +1. `{ $limit : 1 }` +1. `{ $skip : 1 }` +1. `{ $out : 'collectionName'}` +1. $group + - `{ $group : { _id : '$gender' } }` + - `{ $group : { _id : { 'weight' : '$weight', 'gender' : '$gender' } } } ] );` + - `{ $group : { _id : '$gender', numOfEachGender : { $sum : 1 } } }` + - `{ $group : { _id : '$gender', avgSalary : { $avg : '$salary' } } }` + - `{ $group : { _id : '$weight', namesArray : { $addToSet : '$name' } } }` +1. `{ $unwind : '$loves' }` + - `db.employees.aggregate([{$unwind : '$loves'}, {$group : { _id : '$loves', num : {$sum : 1}, names : {$addToSet : '$name'}}}])` +1. $project + - `{ $project : { name : 1, _id : 0 } }` + - `{ $project : { namezz :'$name' } }` + - expressions + - `{ $project : { awesomeName : { $concat : ['$name', ' is awesome', '!']}} }` + - http://docs.mongodb.org/manual/meta/aggregation-quick-reference/#aggregation-expressions + - `{ $project : { embedded_atrribute : '$embedded_object.foo' } }` + - `{ $project : { embedded_object.attribute : 1 } }` + - arrays? diff --git a/8.MONGO_STRUCTURE.md b/8.MONGO_STRUCTURE.md new file mode 100644 index 0000000..d129ae3 --- /dev/null +++ b/8.MONGO_STRUCTURE.md @@ -0,0 +1,43 @@ +# Mongo - Data Modeling + +## Lesson Objectives +1. Explain how to relate documents using foreign keys +1. Explain how to use Arrays +1. Explain how to use Embedded Documents +1. Explain what denormalization is and when to use it + +## Explain how to relate documents using foreign keys +``` +db.employees.insert({_id: ObjectId( "4d85c7039ab0fd70a117d730"), name: 'Leto'}); +db.employees.insert({_id: ObjectId( "4d85c7039ab0fd70a117d731"), name: 'Duncan', manager: ObjectId( "4d85c7039ab0fd70a117d730")}); +db.employees.insert({_id: ObjectId( "4d85c7039ab0fd70a117d732"), name: 'Moneo', manager: ObjectId( "4d85c7039ab0fd70a117d730")}); +``` +1. to find: `db.employees.find({manager: ObjectId( "4d85c7039ab0fd70a117d730")})` + +## Explain how to use Arrays +``` +db.employees.insert({ + _id: ObjectId( "4d85c7039ab0fd70a117d733"), + name: 'Siona', + manager: [ + ObjectId( "4d85c7039ab0fd70a117d730"), + ObjectId( "4d85c7039ab0fd70a117d732")] }) +``` +1. to find: `db.employees.find({manager: ObjectId( "4d85c7039ab0fd70a117d730")})` +1. index uses dot notation + - `db.employees.find({ 'manager.0': ObjectId("4d85c7039ab0fd70a117d730")})` + +## Explain how to use Embedded Documents +``` +db.employees.insert({ + _id: ObjectId( "4d85c7039ab0fd70a117d734"), + name: 'Ghanima', + family: { + mother: 'Chani', + father: 'Paul', + brother: ObjectId( "4d85c7039ab0fd70a117d730")}}) +``` +1. can be queried using dot notation + - `db.employees.find({ 'family.mother': 'Chani'})` + +## Explain what denormalization is and when to use it \ No newline at end of file diff --git a/9.PERFORMANCE.md b/9.PERFORMANCE.md new file mode 100644 index 0000000..7c42d2c --- /dev/null +++ b/9.PERFORMANCE.md @@ -0,0 +1,43 @@ +# Mongo - Performance + +## Lesson Objectives +1. Explain indexes +1. Explain text indexes +1. Explain replication +1. Explain sharding + +## Explain indexes +1. `db.employees.ensureIndex({name: 1});` +1. `db.employees.dropIndex({name: 1});` +1. `db.employees.ensureIndex({name: 1}, {unique: true});` +1. indexes on embedded fields +1. indexes on arrays +1. `db.employees.ensureIndex({name: 1, salary: -1});` + +## Explain text indexes +1. `db.articles.createIndex({ subject : "text", content : "text" })` +1. drop text index + - `db.articles.getIndexes()` + - `db.articles.dropIndex('index_name')` +1. `db.articles.find( { $text: { $search: "coffee" } } )` +1. `db.articles.find( { $text: { $search: "leche", $language: "es" } } )` + - stop words (a, the, and, etc) +1. `db.articles.find( { $text: { $search: "bake coffee cake" } } )` +1. `db.articles.find( { $text: { $search: "\"coffee cake\"" } } )` +1. `db.articles.find( { $text: { $search: "bake coffee -cake" } } )` +1. `db.articles.find( { $text: { $search: "cake" } }, { score: { $meta: "textScore" } } )` +``` +db.articles.find( + { $text: { $search: "cake" } }, + { score: { $meta: "textScore" } } +).sort( { score: { $meta: "textScore" } } ) +``` + +## Explain replication +1. Writes sent to secondary DBs asynchonously +1. Reads can happen on secondaries + - although data may be stale +1. If primary goes down, a secondary is chosen to be new primary + +## Explain sharding +1. split data across multiple servers