Practical MongoDB
-
Upload
will-button -
Category
Software
-
view
368 -
download
1
description
Transcript of Practical MongoDB
Will Button - @wfbutton
Practical MongoDB
From template to production
Many resources exist for individual components.Getting them to work together is a different story.
{name: ‘Will Button’,contact: [twitter: ‘@wfbutton’, email: ‘[email protected]’, web: ‘www.two4seven.me’],role: [‘dev’, ‘ops’, ‘it’],company: ‘myList.com’
}
mean stackfacebook
passport.jsd3.js
The problem.Participants competing in a challenge log meals, workouts and health data into a private Facebook group
Facebook newsfeed algorithmNo reportingDon’t want to lose demographics
Can we use existing frameworks to make it better without losing the parts that work well?
The solution.Tools and
TechnologiesPractical
Application
Step 1: MEAN Stack Template
git clone http://github.com/linnovate/mean.git
Connecting Facebook…
https://developers.facebook.com/apps
Configure passport
Facebook PermissionsDefault: profile, friends list, email
Can’t read newsfeed by default
Reading newsfeed requires valid accessToken
Facebook Permissions
https://developers.facebook.com/docs/facebook-login/permissions/
What about this accessToken thing?
> db.users.findOne({ provider: "facebook" }){
"__v" : 0,"_id" : ObjectId("52f6fc252ae38687577cc688"),"currentchallenge" : ObjectId("5308d9756d7d30a94b681b2d"),"email" : "[email protected]","facebook" : {
"username" : "will.button.56","updated_time" : "2014-01-06T22:33:03+0000","verified" : true,"locale" : "en_US","timezone" : -7,"email" : "[email protected]","gender" : "male","education" : [
{ "type" : "High School", "school" : { "name" : "Sidney High School", "id" : "110094965686846" } }],"favorite_athletes" : [
{ "name" : "CrossFit Endurance", "id" : "182015510972" },{ "name" : "Lucas Parker", "id" : "346667935460586" }
],"favorite_teams" : [
{ "name" : "Dallas Cowboys", "id" : "99559607813" }],"work" : [
{ "start_date" : "0000-00", "employer" : { "name" : "myList", "id" : "105017792957809" } },{ "end_date" : "0000-00", "start_date" : "2004-07-01", "employer" : { "name" : "NightHawk Radiology Services", "id" :
"115173631830635" } }],"bio" : "CrossFit Level 1 (CF-L1) Trainer","location" : { "name" : "Jost Van Dyke, British Virgin Islands", "id" : "327610993996350" },"hometown" : { "name" : "Sidney, Texas", "id" : "108011082555210" },"link" : "https://www.facebook.com/will.button.56","last_name" : "Button","first_name" : "Will","name" : "Will Button","id" : "100001902024344"
},"name" : "Will Button","provider" : "facebook","username" : "will.button.56"
}}
All of this for FREE$$$$
But no accessToken
Passport.js
Refreshes oauth accessToken on login
YIKES!
Functional, but not scalable.
User.js Model
Updated user.js model to store accessToken
Using Facebook OpenGraph
Displaying Entries
Stored Documents{
"user" : ObjectId("52f6fc252ae38687577cc688"),
"message" : "I ate my stuff","challenge" :
ObjectId("5302e4e445bae1611e2e60d9"),"_id" :
ObjectId("53125a106184fe00006e46d6"),"likes" : {
"data" : [ ]},"comments" : {
"data" : [ ]},"updated_time" : ISODate("2014-03-
01T22:07:12.442Z"),"created_time" : ISODate("2014-03-
01T22:07:12.442Z"),"__v" : 0
}
Journal Data Model
var JournalSchema = new Schema({created_time: {
type: Date,default: Date.now
},updated_time: {
type: Date,default: Date.now
},message: {
type: String},comments: {
data: [CommentSchema]},likes: {
data: [LikesSchema]},user: {
type: Schema.ObjectId,ref: 'User'
},challenge: {
type: Schema.ObjectId,ref: 'Challenge'
}});
var LikesSchema = new Schema({id: {
type: String},name: {
type: String}
});
Controller (part of it anyway)
All accessible via Routes
Recap: Where are we now?
Reporting
Aggregation Framework
Aggregation : Quick ReviewPipeline for multiple stages of document transformations for producing aggregated results
Name Description$project Reshapes a document stream. $project can rename, add, or remove fields as well as create computed values and sub-documents.$match Filters the document stream, and only allows matching documents to pass into the next pipeline stage. $match uses standard MongoDB queries.$limit Restricts the number of documents in an aggregation pipeline.$skip Skips over a specified number of documents from the pipeline and returns the rest.$unwind Takes an array of documents and returns them as a stream of documents.$group Groups documents together for the purpose of calculating aggregate values based on a collection of documents.$sort Takes all input documents and returns them in a stream of sorted documents.$geoNear Returns an ordered stream of documents based on proximity to a geospatial point.
db.journals.aggregate( { $group: { _id: "$from.name", numposts: { $sum: 1 } } }, { $project: { who: "$from.name", numposts: 1 } }, { $sort: {_id: 1 } } )
{"result" : [
{"_id" : "Andrew","numposts" : 83
},{
"_id" : "Ben","numposts" : 108
},########### results truncated for brevity ##########
{"_id" : "Tara","numposts" : 20
},{
"_id" : "Will","numposts" : 26
}],"ok" : 1
}
Accessible via:
http://localhost:3000/journals/ppu
Page is rendered By a
controller
With a directive
Using D3 injected as a
service
The Controllerangular.module('mean.reports').controller('ReportsController', ['$scope', '$http', function($scope, $http){ $http({ method: 'GET', url: '/journals/ppu' }).then(function(data, status) { $scope.d3Data = data.data; });}]);
d3Bars Directive
this
thisgets normalized to
d3Bars Directive
D3 library injected as a service
The d3 service is accessible because we add the service to our
footer
And inject it as a dependency
The service itself simply downloads d3.js
Directives are just reusable pieces of code
Restrict where the directive can be used
A/E/C
Scope refers to the type of isolated scope:= two way data binding with the parent DOM object@ one way data binding with the parent DOM object
& expression binding with the parent DOM object
link is basically a controller
variables either specified on declaration or use
defaults
Where do we go from here?
Where do we go from here?
Add new aggregation queries to journals controller
Build new reports/d3 visualizations in
directives.js
Add directives to any page:<d3-bars data="d3Data”></d3-bars>
The mistakes people I make.
Request the right Facebook
permissions
Setup your Facebook
Developers Account
Make your Facebook app public (at least for a few
minutes)
Facebook Graph Explorer
Hardcode dummy data first.
Don’t assume .success(),
wait for it .then()
Do this now:
• Clone the MEAN stack• Stub out dummy data• Build a d3 graph• Stick around
www.two4seven.me/dcc@wfbutton