Practical MongoDB

  • 261 views
Uploaded on

Slide notes from Desert Code Camp 2014. This talk focuses on using the MEAN Stack to build an app that uses Facebook authentication for access, demonstrates advanced permissions for reading an …

Slide notes from Desert Code Camp 2014. This talk focuses on using the MEAN Stack to build an app that uses Facebook authentication for access, demonstrates advanced permissions for reading an authenticated user's Facebook data, and generating a data visualization using the D3.js library and custom Angular directives.

More in: Software , Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
261
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
11
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Will Button - @wfbutton Practical MongoDB
  • 2. From template to production Many resources exist for individual components. Getting them to work together is a different story.
  • 3. { name: ‘Will Button’, contact: [twitter: ‘@wfbutton’, email: ‘willb@mylist.com’, web: ‘www.two4seven.me’], role: [‘dev’, ‘ops’, ‘it’], company: ‘myList.com’ }
  • 4. mean stack facebook passport.js d3.js
  • 5. The problem. Participants competing in a challenge log meals, workouts and health data into a private Facebook group Facebook newsfeed algorithm No reporting Don’t want to lose demographics Can we use existing frameworks to make it better without losing the parts that work well?
  • 6. The solution. Tools and Technologies Practical Application
  • 7. Step 1: MEAN Stack Template git clone http://github.com/linnovate/mean.git
  • 8. Connecting Facebook… https://developers.facebook.com/apps
  • 9. Configure passport
  • 10. Facebook Permissions Default: profile, friends list, email Can’t read newsfeed by default Reading newsfeed requires valid accessToken
  • 11. Facebook Permissions https://developers.facebook.com/docs/faceboo k-login/permissions/
  • 12. What about this accessToken thing? > db.users.findOne({ provider: "facebook" }) { "__v" : 0, "_id" : ObjectId("52f6fc252ae38687577cc688"), "currentchallenge" : ObjectId("5308d9756d7d30a94b681b2d"), "email" : "will@paleotracking.com", "facebook" : { "username" : "will.button.56", "updated_time" : "2014-01-06T22:33:03+0000", "verified" : true, "locale" : "en_US", "timezone" : -7, "email" : "wfbutton@gmail.com", "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 
  • 13. Passport.js Refreshes oauth accessToken on login YIKES! Functional, but not scalable.
  • 14. User.js Model Updated user.js model to store accessToken
  • 15. Using Facebook OpenGraph
  • 16. Displaying Entries
  • 17. 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
  • 18. 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 } });
  • 19. Controller (part of it anyway)
  • 20. All accessible via Routes
  • 21. Recap: Where are we now?
  • 22. Reporting
  • 23. Aggregation Framework
  • 24. Aggregation : Quick Review Pipeline 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.
  • 25. 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 }
  • 26. Accessible via: http://localhost:3000/journals/ppu
  • 27. Page is rendered By a controller With a directive Using D3 injected as a service
  • 28. The Controller angular.module('mean.reports').controller('ReportsController', ['$scope', '$http', function($scope, $http){ $http({ method: 'GET', url: '/journals/ppu' }).then(function(data, status) { $scope.d3Data = data.data; }); }]);
  • 29. d3Bars Directive this gets normalized to
  • 30. d3Bars Directive D3 library injected as a service
  • 31. The d3 service is accessible because we add the service to our footer And inject it as a dependency
  • 32. The service itself simply downloads d3.js
  • 33. 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
  • 34. link is basically a controller variables either specified on declaration or use defaults
  • 35. Where do we go from here?
  • 36. 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>
  • 37. 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()
  • 38. Do this now: • Clone the MEAN stack • Stub out dummy data • Build a d3 graph • Stick around
  • 39. www.two4seven.me/dcc @wfbutton