MongoDB Israel June Meetup

41
MongoDB 2.6 Features in NodeJS Web Apps Valeri Karpov Software Engineer, MongoDB www.thecodebarbarian.com www.slideshare.net/vkarpov15 github.com/vkarpov15 @code_barbarian

description

An overview of using new features in MongoDB 2.6 in the context of NodeJS web apps

Transcript of MongoDB Israel June Meetup

Page 1: MongoDB Israel June Meetup

MongoDB 2.6 Features in NodeJS Web Apps

Valeri KarpovSoftware Engineer, MongoDBwww.thecodebarbarian.com

www.slideshare.net/vkarpov15github.com/vkarpov15

@code_barbarian

Page 2: MongoDB Israel June Meetup

*

Who Am I?

•CI/NodeJS Engineer at MongoDB

•Maintainer of mongoose ODM

•Blogs at thecodebarbarian.com

Page 3: MongoDB Israel June Meetup

*

Talk Overview

•MongoDB 2.6 released in April (currently 2.6.2)

•Exciting new features including:• Text search

• $min and $max operators for updates

• $out operator for aggregation

•Examples of use cases in NodeJS Single Page App

Page 4: MongoDB Israel June Meetup

*

Additional Tools

•MongoDB NodeJS Driver

•Mongoose: ODM for NodeJS, convenience wrapper around mongodb driver

•Express: lightweight server MVC for NodeJS

Page 5: MongoDB Israel June Meetup

*

More Minor Tools

•Moment: elegant wrapper around clunky JS Date

•Omni: dependency injector for NodeJS

•AngularJS: client-side MVC framework

• Don’t worry if you don’t know AngularJS, won’t be used much in this presentation

Page 6: MongoDB Israel June Meetup

*

The App We’ll Be Using

•Open source food journal, LeanMEAN

•Counts calories, computes ratios, etc.

•MEAN = MongoDB, ExpressJS, AngularJS, NodeJS

Page 7: MongoDB Israel June Meetup

*

The App We’ll Be Using - Demo

Page 8: MongoDB Israel June Meetup

*

App Overview

•3 models: FoodItem, User, Day

•Day = list of FoodItems a User ate on a given date

Page 9: MongoDB Israel June Meetup

*

What a FoodItem looks like

•From USDA SR-25 data set

•FoodItem: description, list of nutrients and weights

Page 10: MongoDB Israel June Meetup

*

Food Item Nutrients

Page 11: MongoDB Israel June Meetup

*

Food Item Weights

Page 12: MongoDB Israel June Meetup

*

Simple SR-25 Query

•How many carbs in 1 serving of raw kale?

Page 13: MongoDB Israel June Meetup

*

Part I: Text Search

•Problem: searching for FoodItems

•Don’t want user to have to type exactly “Kale, raw”

•Would be ideal if “raw kale” matched “Kale, raw”

Page 14: MongoDB Israel June Meetup

*

Example of Text Search in Shell

•Top 3 results for “grass-fed beef”

Page 15: MongoDB Israel June Meetup

*

Text Search Details

•Need to create a text index:

• db.nutrition.ensureIndex({ description : "text" });

•Need MongoDB server >= 2.6.0

•Can specify language (15 supported languages)

• db.nutrition.ensureIndex({ description : "text" }, {default_language:"ru"});

• Supports English and Russian, but no Hebrew yet

•Limitation: 1 text search index per collection

Page 16: MongoDB Israel June Meetup

*

Text Search In NodeJS

•Recommend using:• node-mongodb-native >= 1.4.0 (1.2 and 1.3 seem to work)

• mongoose >= 3.8.9

•Since JS, very similar to shell

Page 17: MongoDB Israel June Meetup

*

Use Case For Text Search

•Autocomplete/typeahead for entering food items

Page 18: MongoDB Israel June Meetup

*

The API Endpoint in Express

•All our API methods:

Page 19: MongoDB Israel June Meetup

*

Search API Implementation

Note: text search API is atypical, docs here

Page 20: MongoDB Israel June Meetup

*

A Note on $meta and Text Score

Page 21: MongoDB Israel June Meetup

*

Part II: $min and $max

•Mongoose users often update docs in memory

•Not necessarily good practice!

•Just use update() where possible

•$min and $max enable new use case for update()

•Not to be confused with aggregation $min/$max

•Not to be confused with query modifier $min/$max

Page 22: MongoDB Israel June Meetup

*

Using $min and $max in the Shell

•Conditional update:• $min: only update if new value < old value

• $max: only update if new value > old value

Page 23: MongoDB Israel June Meetup

*

More Interesting Use Case for $min

•$min and $max also work on ISODate

•Common use case: oldest piece of data for user

•In LeanMEAN, user can enter data for past days

•Inexpensive query, but 0 queries better than 1

•Save an HTTP request and a query = win

•Tradeoff: extra load when saving

Page 24: MongoDB Israel June Meetup

*

Using $min and $max in NodeJS

•No known restrictions

•Still recommend• node-mongodb-native >= 1.4.0

• mongoose >= 3.8.0

Page 25: MongoDB Israel June Meetup

*

Taking a Look at the User Schema

Page 26: MongoDB Israel June Meetup

*

$min in Action with Mongoose

Page 27: MongoDB Israel June Meetup

*

Notes about $min and $max

•$min and $max use BSON comparison order

•Can have unexpected results!

•Example: null < 4

Page 28: MongoDB Israel June Meetup

*

Notes about $min and $max, cont

•$min and $max use BSON comparison order

•Example: ISODate > 4

Careful to use $min/$max with right type!

Page 29: MongoDB Israel June Meetup

*

Part III: Aggregation $out

•Before MongoDB 2.6, aggregation limited to 16MB

•Also no good way to output to collection

•2.6.0 solves both!

•Aggregation returns a cursor, no fixed limit on size

•$out stage outputs agg. results to collection

Page 30: MongoDB Israel June Meetup

*

Using $out from the Shell

•$out is pipeline stage, like $group, $match, etc.

•Takes string input: name of collection

Page 31: MongoDB Israel June Meetup

*

Using $out from the Shell: Data

Page 32: MongoDB Israel June Meetup

*

Running $out from the Shell

Page 33: MongoDB Israel June Meetup

*

Using $out in NodeJS

•node-mongodb-native >= 1.4.0 recommended

•mongoose >= 3.8.0 recommended

•But .out() aggregation helper requires >= 3.8.9

Page 34: MongoDB Israel June Meetup

*

Use Case: All I Need is One Document

•Ideal MEAN stack world: 1 document ⇔ 1 page

•NodeJS makes scheduling aggregations easy

•Use $out to build complex data sets with ease

Page 35: MongoDB Israel June Meetup

*

Average Calories Per Week Per User

•Show week by week average calories per day

•Bulky, complex aggregation

•Don’t want to do this on-demand

•Use node-cron to run aggregation once per day

Page 36: MongoDB Israel June Meetup

*

The Actual Aggregation, 1-3

•6 stages + $out

Page 37: MongoDB Israel June Meetup

*

The Actual Aggregation, 4-5

Page 38: MongoDB Israel June Meetup

*

The Actual Aggregation, 6-7

Page 39: MongoDB Israel June Meetup

*

Accessing via API Endpoint

Page 40: MongoDB Israel June Meetup

*

Notes on $out

•Always creates a new collection

•Overwrites existing collection, no append mode yet

•Under the hood:• Puts aggregation output into temp collection

• Atomic rename of collection after complete

•Old data still available during aggregation

•Temp collection inserts go in oplog and replicate

•Can’t $out to a sharded or capped collection