45
Aggregation Framework Senior Solutions Architect, MongoDB Norberto Leite #mongodbdays @nleite #aggfwk

Aggregation Framework MongoDB Days Munich

Embed Size (px)

DESCRIPTION

MongoDB's Aggregation Framework presentation on the internal aspects, usage and application implications.

Citation preview

Page 1: Aggregation Framework MongoDB Days Munich

Aggregation Framework

Senior Solutions Architect, MongoDB

Norberto Leite

#mongodbdays @nleite #aggfwk

Page 2: Aggregation Framework MongoDB Days Munich

Agenda

•  What is the Aggregation Framework?

•  The Aggregation Pipeline

•  Usage and Limitations

•  Aggregation and Sharding

•  Summary

Page 3: Aggregation Framework MongoDB Days Munich

What is the Aggregation Framework?

Page 4: Aggregation Framework MongoDB Days Munich

Aggregation Framework

Page 5: Aggregation Framework MongoDB Days Munich

Aggregation in Nutshell

•  We're storing our data in MongoDB

•  Our applications need to run ad-hoc queries for grouping, summarizations, reporting, etc.

•  We must have a way to reshape data easily to support these access patterns

•  You can use Aggregation Framework for this!

Page 6: Aggregation Framework MongoDB Days Munich

•  Extremely versatile, powerful

•  Overkill for simple aggregation tasks •  Averages •  Summation •  Grouping •  Reshaping

MapReduce is great, but…

•  High level of complexity

•  Difficult to program and debug

Page 7: Aggregation Framework MongoDB Days Munich

Aggregation Framework

•  Plays nice with sharding

•  Executes in native code –  Written in C++ –  JSON parameters

•  Flexible, functional, and simple –  Operation pipeline –  Computational expressions

Page 8: Aggregation Framework MongoDB Days Munich

Aggregation Pipeline

Page 9: Aggregation Framework MongoDB Days Munich

Pipeline

Page 10: Aggregation Framework MongoDB Days Munich

What is an Aggregation Pipeline?

•  A Series of Document Transformations –  Executed in stages –  Original input is a collection –  Output as a cursor or a collection

•  Rich Library of Functions –  Filter, compute, group, and summarize data –  Output of one stage sent to input of next –  Operations executed in sequential order

$match $project $group $sort

Page 11: Aggregation Framework MongoDB Days Munich

Pipeline Operators

•  $sort •  Order documents

•  $limit / $skip •  Paginate documents

•  $redact •  Restrict documents

•  $geoNear •  Proximity sort documents

•  $let, $map •  Define variables

•  $match •  Filter documents

•  $project •  Reshape documents

•  $group •  Summarize documents

•  $unwind •  Expand documents

Page 12: Aggregation Framework MongoDB Days Munich

{

"_id" : ObjectId("54523d2d25784427c6fabce1"),

"From" : "[email protected]",

"To" : "[email protected]",

"Date" : ISODate("2012-08-15T22:32:34Z"),

"body" : {

"text/plain" : ”Hello Munich, nice to see yalll!"

},

"Subject" : ”Live From MongoDB World"

}

Our Example Data

Page 13: Aggregation Framework MongoDB Days Munich

$match

•  Filter documents –  Uses existing query syntax –  No $where (server side Javascript)

Page 14: Aggregation Framework MongoDB Days Munich

Matching Field Values

{ subject: "Hello There", words: 218, from: "[email protected]" }

{ $match: { from: "[email protected]" }}

{ subject: "I love Hofbrauhaus", words: 90, from: "[email protected]" } { subject: "MongoDB Rules!", words: 100, from: "[email protected]" }

{ subject: "MongoDB Rules!", words: 100, from: "[email protected]" }

Page 15: Aggregation Framework MongoDB Days Munich

Matching with Query Operators

{ subject: "Hello There", words: 218, from: "[email protected]" }

{ $match: { words: {$gt: 100} }}

{ subject: "I love Hofbrauhaus", words: 90, from: "[email protected]" } { subject: "MongoDB Rules!", words: 100, from: "[email protected]" }

{ subject: "MongoDB Rules!", words: 100, from: "[email protected]" }

{ subject: "Hello There", words: 218, from: "[email protected]" }

Page 16: Aggregation Framework MongoDB Days Munich

$project

•  Reshape Documents –  Include, exclude or rename fields –  Inject computed fields –  Create sub-document fields

Page 17: Aggregation Framework MongoDB Days Munich

Including and Excluding Fields

{ _id: 12345, subject: "Hello There", words: 218, from:"[email protected]" to: [ "[email protected]", "[email protected]" ], account: "mongodb mail", date: ISODate("2012-08-05"), replies: 3, folder: "Inbox", ... }

{ $project: { _id: 0, subject: 1, from: 1 }}

{ subject: "Hello There", from:"[email protected]" }

Page 18: Aggregation Framework MongoDB Days Munich

Including and Excluding Fields

{ _id: 12345, subject: "Hello There", words: 218, from:"[email protected]" to: [ "[email protected]", "[email protected]" ], account: "mongodb mail", date: ISODate("2012-08-05"), replies: 3, folder: "Inbox", ... }

{ $project: { _id: 0, subject: 1, from: 1 }}

{ subject: "Hello There", from:"[email protected]" }

Page 19: Aggregation Framework MongoDB Days Munich

Renaming and Computing Fields

{ $project: { spamIndex: { $mul: ["$words", "$replies"] }, user: "$from" }}

{ _id: 12345, spamIndex: 72.6666 , user: "[email protected]" }

{ _id: 12345, subject: "Hello There", words: 218, from:"[email protected]" to: [ "[email protected]", "[email protected]" ], account: "mongodb mail", date: ISODate("2012-08-05"), replies: 3, folder: "Inbox", ... }

Page 20: Aggregation Framework MongoDB Days Munich

Creating Sub-Document Fields

{ $project: { subject: 1, stats: { replies: "$replies", from: "$from", date: "$date" }}}

{ _id: 375, subject: "Hello There", stats: { replies: 3, from: "[email protected]", date: ISODate("2012-08-05") }}

{ _id: 12345, subject: "Hello There", words: 218, from:"[email protected]" to: [ "[email protected]", "[email protected]" ], account: "mongodb mail", date: ISODate("2012-08-05"), replies: 3, folder: "Inbox", ... }

Page 21: Aggregation Framework MongoDB Days Munich

$group •  Group documents by value

–  Field reference, object, constant –  Other output fields are computed

•  $max, $min, $avg, $sum •  $addToSet, $push •  $first, $last

–  Processes all data in memory by default

Page 22: Aggregation Framework MongoDB Days Munich

Calculating An Average

{ $group: { _id: "$from", avgWords: { $avg: "$words" } }}

{ _id: "[email protected]", avgPages: 154 }

{ _id: "[email protected]", avgPages: 100 }

{ subject: "Hello There", words: 218, from: "[email protected]" }

{ subject: "I love Hofbrauhaus", words: 90, from: "[email protected]" }

{ subject: "MongoDB Rules!", words: 100, from: "[email protected]" }

Page 23: Aggregation Framework MongoDB Days Munich

Summing Fields and Counting

{ $group: { _id: "$from", words: { $sum: "$words" }, mails: { $sum: 1 } }}

{ _id: "[email protected]", words: 308, mails: 2 } { _id: "[email protected]", words: 100, mails: 1 }

{ subject: "Hello There", words: 218, from: "[email protected]" }

{ subject: "I love Hofbrauhaus", words: 90, from: "[email protected]" }

{ subject: "MongoDB Rules!", words: 100, from: "[email protected]" }

Page 24: Aggregation Framework MongoDB Days Munich

$unwind

•  Operate on an array field –  Create documents from array elements

•  Array replaced by element value •  Missing/empty fields → no output •  Non-array fields → error

–  Pipe to $group to aggregate

Page 25: Aggregation Framework MongoDB Days Munich

Collecting Distinct Values

{ subject: "2.8 will be great!", to: "[email protected]", account : "mongodb mail” }

{ $unwind: "$to" } { _id: 2222, subject: "2.8 will be great!", to: [ "[email protected]",

"[email protected]", "[email protected]", ], account: "mongodb mail" }

{ subject: "2.8 will be great!", to: "[email protected]", account : "mongodb mail” }

{ subject: "2.8 will be great!", to: "[email protected]", account : "mongodb mail” }

Page 26: Aggregation Framework MongoDB Days Munich

$sort, $limit, $skip

•  Sort documents by one or more fields –  Same order syntax as cursors –  Waits for earlier pipeline operator to return –  In-memory unless early and indexed

•  Limit and skip follow cursor behavior

Page 27: Aggregation Framework MongoDB Days Munich

$redact

•  Restrict access to Documents –  Use document fields to define privileges –  Apply conditional queries to validate users

•  Field Level Access Control –  $$DESCEND, $$PRUNE, $$KEEP –  Applies to root and subdocument fields

Page 28: Aggregation Framework MongoDB Days Munich

{ _id: 375, item: "Sony XBR55X900A 55Inch 4K Ultra High Definition TV", Manufacturer: "Sony", security: 0, quantity: 12, list: 4999, pricing: { security: 1, sale: 2698, wholesale: { security: 2, amount: 2300 } } }

$redact Example Data

Page 29: Aggregation Framework MongoDB Days Munich

Query by Security Level

security = 0

db.catalog.aggregate([ { $match: {item: /^.*XBR55X900A*/} }, { $redact: { $cond: { if: { $lte: [ "$security", ?? ] }, then: "$$DESCEND", else: "$$PRUNE" } } }])

{ "_id" : 375, "item" : "Sony XBR55X900A 55Inch 4K Ultra High Definition TV", "Manufacturer" : "Sony”, "security" : 0, "quantity" : 12, "list" : 4999 }

{ "_id" : 375, "item" : "Sony XBR55X900A 55Inch 4K Ultra High Definition TV", "Manufacturer" : "Sony", "security" : 0, "quantity" : 12, "list" : 4999, "pricing" : { "security" : 1, "sale" : 2698, "wholesale" : { "security" : 2, "amount" : 2300 } }

}

security = 2

Page 30: Aggregation Framework MongoDB Days Munich

$geoNear

•  Order/Filter Documents by Location –  Requires a geospatial index –  Output includes physical distance –  Must be first aggregation stage

Page 31: Aggregation Framework MongoDB Days Munich

{ "_id" : 35089, "city" : “Sony”, "loc" : [ -86.048397, 32.979068 ], "pop" : 1584, "state" : "AL”

}

$geonear Example Data

Page 32: Aggregation Framework MongoDB Days Munich

Query by Proximity

db.catalog.aggregate([ { $geoNear : { near: [ -86.000, 33.000 ], distanceField: "dist", maxDistance: .050, spherical: true, num: 3 } }])

{ "_id" : "35089", "city" : "KELLYTON", "loc" : [ -86.048397, 32.979068 ], "pop" : 1584, "state" : "AL", "dist" : 0.0007971432165364155

}, {

"_id" : "35010", "city" : "NEW SITE", "loc" : [ -85.951086, 32.941445 ], "pop" : 19942, "state" : "AL", "dist" : 0.0012479615347306806

}, {

"_id" : "35072", "city" : "GOODWATER", "loc" : [ -86.078149, 33.074642 ], "pop" : 3813, "state" : "AL", "dist" : 0.0017333719627032555

}

Page 33: Aggregation Framework MongoDB Days Munich

Usage and Limitations

Page 34: Aggregation Framework MongoDB Days Munich

Usage

•  collection.aggregate([…], {<options>}) –  Returns a cursor –  Takes an optional document to specify aggregation options

•  allowDiskUse, explain –  Use $out to send results to a Collection

•  db.runCommand({aggregate:<collection>, pipeline:[…]}) –  Returns a document, limited to 16 MB

Page 35: Aggregation Framework MongoDB Days Munich

Collection

db.books.aggregate([

{ $project: { language: 1 }},

{ $group: { _id: "$language", numTitles: { $sum: 1 }}}

])

{ _id: "Russian", numTitles: 1 }, { _id: "English", numTitles: 2 }

Page 36: Aggregation Framework MongoDB Days Munich

Database Command

db.runCommand({ aggregate: "books", pipeline: [ { $project: { language: 1 }}, { $group: { _id: "$language", numTitles: { $sum: 1 }}} ] })

{ result : [ { _id: "Russian", numTitles: 1 }, { _id: "English", numTitles: 2 } ], “ok” : 1

}

Page 37: Aggregation Framework MongoDB Days Munich

Limitations

•  Pipeline operator memory limits –  Stages limited to 100 MB –  Use “allowDiskUse” option to use disk for larger data sets

•  Some BSON types unsupported –  Symbol, MinKey, MaxKey, DBRef, Code, and CodeWScope

Page 38: Aggregation Framework MongoDB Days Munich

Aggregation and Sharding

Page 39: Aggregation Framework MongoDB Days Munich

Sharding

Result

mongos

Shard 1 (Primary) $match, $project,

$group

Shard 2 $match, $project,

$group

Shard 3

excluded

Shard 4 $match, $project,

$group

•  Workload split between shards –  Shards execute pipeline up to a point –  Primary shard merges cursors and

continues processing* –  Use explain to analyze pipeline split –  Early $match may excuse shards –  Potential CPU and memory implications

for primary shard host

* Prior to v2.6 second stage pipeline processing was done by mongos

Page 40: Aggregation Framework MongoDB Days Munich

Summary

Page 41: Aggregation Framework MongoDB Days Munich

Framework Use Cases

•  Basic aggregation queries

•  Ad-hoc reporting

•  Real-time analytics

•  Visualizing and reshaping data

Page 42: Aggregation Framework MongoDB Days Munich

Extending the Framework

•  Adding new pipeline operators, expressions

•  $out and $tee for output control –  https://jira.mongodb.org/browse/SERVER-3253

Page 43: Aggregation Framework MongoDB Days Munich

Future Enhancements

•  Automatically move $match earlier if possible

•  Pipeline explain facility

•  Memory usage improvements –  Grouping input sorted by _id –  Sorting with limited output

Page 44: Aggregation Framework MongoDB Days Munich

Enabling Developers

•  Doing more within MongoDB, faster

•  Refactoring MapReduce and groupings –  Replace pages of JavaScript –  Longer aggregation pipelines

•  Quick aggregations from the shell

Page 45: Aggregation Framework MongoDB Days Munich

Obrigado!

SA | Eng – [email protected]

Norberto Leite

#mongodbdays #aggfwk #devs @mongodb