SlideShare a Scribd company logo
#MDBlocal
PIPELINE POWER
DOING MORE WITH MONGODB AGGREGATION
Ankur Raina MongoDB Inc @rainaankur92
#MDBlocal
STORE
RETRIEVE
APPLICATIONS & DATA
#MDBlocal
STORE
RETRIEVE
QUERY & ANALYTICS
APPLICATIONS & DATA
#MDBlocal
STORE
RETRIEVE
find() & aggregate()
APPLICATIONS & DATA
#MDBlocal
#MDBlocal
OPTIONS FOR ANALYTICS
pre-aggregate
analyze
in MongoDB
analyze elsewhere
#MDBlocal
pre-aggregate
analyze
in MongoDB
analyze
elsewhere
OPTIONS FOR ANALYTICS
#MDBlocal
pre-aggregate
analyze
in MongoDB
analyze
elsewhere
OPTIONS FOR ANALYTICS
#MDBlocal
#MDBlocal
#MDBlocal
#MDBlocal
#MDBlocal
pre-aggregate
analyze
in MongoDB
analyze elsewhere
OPTIONS FOR ANALYTICS
#MDBlocal
ANALYTICS = AGGREGATION
pre-aggregate
analyze
in MongoDB
analyze elsewhere
#MDBlocal
PIPELINE
#MDBlocal
ps ax | grep mongod | head 1
*nix command line pipe
PIPELINE
#MDBlocal
$match $group | $sort|
Input stream {} {} {}{} Result {} {}...
PIPELINE
MongoDB document pipeline
#MDBlocal
Stage 1 Stage 2 Stage 3 Stage 4
{}{}{}{}
{}{}{}{}
DATA PIPELINE
{}{}{}{}
{"$stage":{ ... }}
START
Collection
View
Special stage
STAGES
{title: "The Great Gatsby",
language: "English",
subjects: "Long Island"}
{title: "The Great Gatsby",
language: "English",
subjects: "New York"}
{title: "The Great Gatsby",
language: "English",
subjects: "1920s"}
{title: "The Great Gatsby",
language: "English",
subjects: [
"Long Island",
"New York",
"1920s"] },
{"$match":{"language":"English"}}
$match
{ _id:"Long Island",
count: 1 },
$group
{ _id: "New York",
count: 2 },
$unwind
{ _id: "1920s",
count: 1 },
$sort $skip$limit $project
{"$unwind":"$subjects"}
{"$group":{"_id":"$subjects", "count":{"$sum:1}}
{ _id: "Harlem",
count: 1 },
{ _id: "Long Island",
count: 1 },
{ _id: "New York",
count: 2 },
{ _id: "1920s",
count: 1 },
{title: "Open City",
language: "English",
subjects: [
"New York"
"Harlem" ] }
{ title: "The Great Gatsby",
language: "English",
subjects: [
"Long Island",
"New York",
"1920s"] },
{ title: "War and Peace",
language: "Russian",
subjects: [
"Russia",
"War of 1812",
"Napoleon"] },
{ title: "Open City",
language: "English",
subjects: [
"New York",
"Harlem" ] },
{title: "Open City",
language: "English",
subjects: "New York"}
{title: "Open City",
language: "English",
subjects: "Harlem"}
{ _id: "Harlem",
count: 1 },
{"$sort:{"count":-1}
{"$limit":3}
{"$project":...}
STAGES
[MongoDB.local Bengaluru 2018] Tutorial: Pipeline Power - Doing More with MongoDB Aggregation
Group
and
Transform
Aliases
Special
• Input
• Output
Reorder
Transform
Decrease
Increase
{title: "The Great Gatsby",
language: "English",
subjects: "Long Island"}
{title: "The Great Gatsby",
language: "English",
subjects: "New York"}
{title: "The Great Gatsby",
language: "English",
subjects: "1920s"}
{title: "The Great Gatsby",
language: "English",
subjects: [
"Long Island",
"New York",
"1920s"] },
$match
{ _id:"Long Island",
count: 1 },
$group
{ _id: "New York",
count: 2 },
$unwind
{ _id: "1920s",
count: 1 },
$sort $skip$limit $project
{ _id: "Harlem",
count: 1 },
{ _id: "Long Island",
count: 1 },
{ _id: "New York",
count: 2 },
{ _id: "1920s",
count: 1 },
{title: "Open City",
language: "English",
subjects: [
"New York"
"Harlem" ] }
{ title: "The Great Gatsby",
language: "English",
subjects: [
"Long Island",
"New York",
"1920s"] },
{ title: "War and Peace",
language: "Russian",
subjects: [
"Russia",
"War of 1812",
"Napoleon"] },
{ title: "Open City",
language: "English",
subjects: [
"New York",
"Harlem" ] },
{title: "Open City",
language: "English",
subjects: "New York"}
{title: "Open City",
language: "English",
subjects: "Harlem"}
{ _id: "Harlem",
count: 1 },
{"$match":{"language":"English"}}
{"$unwind":"$subjects"}
{"$group":{"_id":"$subjects", "count":{"$sum:1}}
{"$sort:{"count":-1}
{"$limit":3}
{"$project":...}
#MDBlocal
STREAMING VS BLOCKING
{title: "The Great Gatsby",
language: "English".
subjects: "Long Island"}
{title: "The Great Gatsby",
language: "English",
subjects: "New York"}
{title: "The Great Gatsby",
language: "English",
subjects: "1920s"}
{title: "The Great Gatsby",
language: "English",
subjects: [
"Long Island",
"New York",
"1920s"] },
$match
{ _id:"Long Island",
count: 1 },
$group
{ _id: "New York",
count: 2 },
$unwind
{ _id: "1920s",
count: 1 },
$sort $skip$limit $project
{ _id: "Harlem",
count: 1 },
{ _id:"LongIsland",
count: 1 },
{ _id: "New York",
count: 2 },
{ _id: "1920s",
count: 1 },
{title: "Open City",
language: "English",
subjects: [
"New York"
"Harlem" ] }
{ title: "The Great Gatsby",
language: "English",
subjects: [
"Long Island",
"New York",
"1920s"] },
{ title: "War and Peace",
language: "Russian",
subjects: [
"Russia",
"War of 1812",
"Napoleon"] },
{ title: "Open City",
language: "English",
subjects: [
"New York",
"Harlem" ] },
{title: "Open City",
language: "English",
subjects: "New York"}
{title: "Open City",
language: "English",
subjects: "Harlem"}
{ _id: "Harlem",
count: 1 },
$group $sort
1
{"$match":{"language":"English"}}
{"$unwind":"$subjects"}
{"$group":{"_id":"$subjects", "count":{"$sum:1}}
{"$sort:{"count":-1}
{"$limit":3}
{"$project":...}
Group
and
Transform
Aliases
Special
• Input
• Output
Reorder
Transform
Decrease
Increase
#MDBlocal
INPUT STAGE RESULTSSTAGE
STREAMING RESOURCE USE
#MDBlocal
Each document is streamed through RAM
STREAMING RESOURCE USE
#MDBlocal
INPUT STAGE RESULTSSTAGE
BLOCKING RESOURCE USE
#MDBlocal
Sort with Limit:
sizeOfAvgDoc * Limit + sizeOfAvgDoc
Sort without Limit:
sizeOfAllDocs
Group:
sizeOfAvgDoc * numberOfGroups + sizeOfAvgDoc
BLOCKING RESOURCE USE
# M D B l o c a l
EXPRESSIONS
[MongoDB.local Bengaluru 2018] Tutorial: Pipeline Power - Doing More with MongoDB Aggregation
[MongoDB.local Bengaluru 2018] Tutorial: Pipeline Power - Doing More with MongoDB Aggregation
#MDBlocal
# M D B l o c a l
ARRAY EXPRESSIONS
#MDBlocal
$arrayElemAt
$concatArrays
$indexOfArray
$isArray
$size
$range
$reverseArray
$map
$reduce
$filter
$slice
$zip
$in
... plus all the set expressions
ARRAY EXPRESSIONS
#MDBlocal
$arrayElemAt
$concatArrays
$indexOfArray
$isArray
$size
$range
$reverseArray
$map
$reduce
$filter
$slice
$zip
$in
... plus all the set expressions
ARRAY EXPRESSIONS
#MDBlocal
$map
input: array
output: array
$filter
input: array
output: subset of array
$reduce
input: array
output: anything
you
want
ARRAY EXPRESSIONS
#MDBlocal
"arr":[{"a":1},{"a":99},{"a":5},{"a":3}]
{"$map":{
"input":"$arr",
"in":"$$this"
}}
{"$map":{
"input":"$arr",
"as":"eachElem",
"in":{"b":"$$eachElem.a"}
}}
{"$map":{
"input":{"$range":[0,{"$size":"$arr"}]},
"as":"index",
"in":{"c":{"$arrayElemAt":["$arr.a","$$index"]}}
}}
"a" 1
"a" 99
"a" 5
"a" 3
"b" 1
"b" 99
"b" 5
"b" 3
"c" 1
"c" 99
"c" 5
"c" 3
"a" 1
"a" 99
"a" 5
"a" 3
"a" 1
"a" 99
"a" 5
"a" 3
0
1
2
3
{"$map":{
"input":"$arr",
"as":"var",
"in":"$$var" }}
$map
{"$map":{
"input":"$arr.a",
"as":"eachElem",
"in":{"b":"$$eachElem"}}}
ARRAY EXPRESSIONS
1
99
5
3
#MDBlocal
"arr":[{"a":1},{"a":99},{"a":5},{"a":3}]
{"$filter": {
"input":"$arr",
"cond":{"$lt":["$$this.a",10]}
}}
{"$filter":{
"input":"$arr.a",
"as":"elem",
"cond":{"$lt":["$$elem",10]}
}}
ARRAY EXPRESSIONS
"a" 1
"a" 99
"a" 5
"a" 3
$filter
"a" 1
"a" 5
"a" 3
#MDBlocal
"arr":[{"a":1},{"a":99},{"a":5},{"a":3}]
{"$reduce":{
"input":"$arr",
"initialValue": 0,
"in":{$add:["$$value","$$this.a"]}
}}
ARRAY EXPRESSIONS $reduce
01100105108
"a" 1
"a" 99
"a" 5
"a" 3
#MDBlocal
"arr":[{"a":1},{"a":99},{"a":5},{"a":3}]
{"$reduce":{
"input":"$arr",
"initialValue":0,
"in":{$add:["$$value","$$this.a"]}
}}
{"$reduce":{
"input":"$arr",
"intialValue":[],
"in":{"$concatArrays":[
["$$this"],
"$$value"
]}
}}
ARRAY EXPRESSIONS $reduce
"a" 1
"a" 99
"a" 5
"a" 3
108
"a" 1
"a" 99
"a" 5
"a" 3
[]
#MDBlocal
"arr":[{"a":1},{"a":99},{"a":5},{"a":3}]
{"$reduce":{
"input":"$arr",
"initialValue":0,
"in":{$add:["$$value","$$this.a"]}
}}
{"$reduce":{
"input":"$arr",
"initialValue":[],
"in":{"$concatArrays":[
["$$this"],
"$$value"
]}
}}
[]
ARRAY EXPRESSIONS $reduce
"a" 1
"a" 99
"a" 5
"a" 3
108
"a" 1
"a" 99
"a" 5
"a" 3
"a" 1"a" 99
"a" 1
"a" 5
"a" 99
"a" 1
"a" 3
"a" 5
"a" 99
"a" 1
# M D B l o c a l
READABILITY TIP
#MDBlocal
Functions for expressions
reverseArray=function(input){
return{"$reduce":{
"input":input,
"intialValue":[],
"in":{"$concatArrays":[
["$$this"],
"$$value"
]}
}};
};
db.c.aggregate([{"$addFields":{
"revArray":reverseArray("$origArray")
}}])
ENCAPSULATE COMPLEXITY
#MDBlocal
Functions for expressions
sortArray=function(inputArray,sortField="",asc=false)
{
varsuffix="";
varmaxF=MaxKey;
varminF=MinKey;
if(sortField!=""){
suffix="."+sortField;
db.c.aggregate([{"$addFields":{
"sortedArray":sortArray("$origArray")
}}])
ENCAPSULATE COMPLEXITY
# M D B l o c a l
EXAMPLES
# M D B l o c a l
SCHEMA DISCOVERY
New Expressions (3.4.4, 3.6):
{"$objectToArray": <object>}
=> array of k/v pairs
{"$arrayToObject": <array of k/v pairs>}
=> object
$ObjectToArray:"$vid"
[
{ "k": "messageId",
"v": "bcd1d991"
},
{ "k": "date",
"v": 1486546629585
},
{ "k": "status",
"v": "accept"
},
{ "k": "comment",
"v": "hi"
}
]
$ObjectToArray:"$$ROOT"
[ {
"k":"vid",
"v": {
"messageId": "bcd1d991",
"date": 1486546629585,
"status": "accept",
"comment": "hi"
}
]
Object:
{
"vid": {
"messageId": "bcd1d9",
"date": 1486546629585,
"status": "accept",
"comment": "hi"
}
}
$project
{
"vid": "072ade7d42d8",
"msgId": "bcd1d9",
"date": 1486546629585,
"status": "accept",
"comment": "hi"
},
{
"vid": "595d0a56cff2",
"msgId": "595d0a",
"date": 1486566646197,
"status": "reject",
"comment": "no good"
},
...
{"$project": {
"fields": {
"$objectToArray": "$$ROOT"
}
}
{"fields": [
{ "k":"vid","v":"072ade7d42d8",
{ "k":"msgId", "v": "bcd1d991"},
{ "k":"date","v": 1486546629585 },
{ "k":"status", "v": "accept"},
{ "k":"comment", "v": "hi"}
] },
{"fields": [
{ "k":"vid","v":"595d0a56cff2",
{ "k":"msgId", "v": "595d0a"},
{ "k":"date","v": 1486566646197},
{ "k":"status", "v": "reject"},
{ "k":"comment", "v": "no good"}
] },
...
$project
{
"vid": "072ade7d42d8",
"msgId": "bcd1d9",
"date": 1486546629585,
"status": "accept",
"comment": "hi"
},
{
"vid": "595d0a56cff2",
"msgId": "595d0a",
"date": 1486566646197,
"status": "reject",
"comment": "no good"
},
...
{"$project": {
"fields": {
"$objectToArray": "$$ROOT"
}
} },
{"$project": {
"fields": {
"$map": {
"input":"$fields",
"in": {
"k":"$$this.k",
"t":{"$type":"$$this.v"}
}
}
}
}},
{"fields": [
{ "k":"vid","t":"string",
{ "k":"msgId", "t": "string"},
{ "k":"date","t": double},
{ "k":"status", "t": "string"},
{ "k":"comment", "t": "string"}
] },
{"fields": [
{ "k":"vid","t":"string",
{ "k":"msgId", "t": "string"},
{ "k":"date","t": "double"},
{ "k":"status", "t": "string"},
{ "k":"comment", "t": "string"}
] },
...
{"fields": [
{ "k":"vid","v":"072ade7d42d8",
{ "k":"msgId", "v": "bcd1d991"},
{ "k":"date","v": 1486546629585 },
{ "k":"status", "v": "accept"},
{ "k":"comment", "v": "hi"}
] },
{"fields": [
{ "k":"vid","v":"595d0a56cff2",
{ "k":"msgId", "v": "595d0a"},
{ "k":"date","v": 1486566646197},
{ "k":"status", "v": "reject"},
{ "k":"comment", "v": "no good"}
] },
...
$project
$project
{
"vid": "072ade7d42d8",
"msgId": "bcd1d9",
"date": 1486546629585,
"status": "accept",
"comment": "hi"
},
{
"vid": "595d0a56cff2",
"msgId": "595d0a",
"date": 1486566646197,
"status": "reject",
"comment": "no good"
},
...
{"$project": {
"fields": {
"$map": {
"input":{
"$objectToArray":"$$ROOT"},
"in": {
"k":"$$this.k",
"t":{"$type":"$$this.v"}
}
}
}
}},
{"fields": [
{ "k":"vid","t":"string",
{ "k":"msgId", "t": "string"},
{ "k":"date","t": double},
{ "k":"status", "t": "string"},
{ "k":"comment", "t": "string"}
] },
{"fields": [
{ "k":"vid","t":"string",
{ "k":"msgId", "t": "string"},
{ "k":"date","t": "double"},
{ "k":"status", "t": "string"},
{ "k":"comment", "t": "string"}
] },
...
$project
$project
{
"vid": "072ade7d42d8",
"msgId": "bcd1d9",
"date": 1486546629585,
"status": "accept",
"comment": "hi"
},
{
"vid": "595d0a56cff2",
"msgId": "595d0a",
"date": 1486566646197,
"status": "reject",
"comment": "no good"
},
...
{"$project": {
"fields": {
"$map": {
"input":{
"$objectToArray":"$$ROOT"},
"in": {
"k":"$$this.k",
"t":{"$type":"$$this.v"}
}
}
}
}},
{"$unwind" : "$fields"}
{"fields": [
{ "k":"vid","t":"string",
{ "k":"msgId", "t": "string"},
{ "k":"date","t": double},
{ "k":"status", "t": "string"},
{ "k":"comment", "t": "string"}
] },
{"fields": [
{ "k":"vid","t":"string",
{ "k":"msgId", "t": "string"},
{ "k":"date","t": "double"},
{ "k":"status", "t": "string"},
{ "k":"comment", "t": "string"}
] },
...
{"fields":{"k":"vid","t":"string",
{"fields":{"k":"msgId", "t": "string"},
{"fields":{"k":"date","t": double},
{"fields":{"k":"status", "t": "string"},
{"fields":{"k":"comment", "t": "string"},
{"fields":{"k":"vid","t":"string",
{"fields":{"k":"msgId", "t": "string"},
{"fields":{"k":"date","t": double},
{"fields":{"k":"status", "t": "string"},
{"fields":{"k":"comment", "t": "string"}
...
$unwind
$project
{
"vid": "072ade7d42d8",
"msgId": "bcd1d9",
"date": 1486546629585,
"status": "accept",
"comment": "hi"
},
{
"vid": "595d0a56cff2",
"msgId": "595d0a",
"date": 1486566646197,
"status": "reject",
"comment": "no good"
},
...
{"$project": {
"fields": {
"$map": {
"input":{
"$objectToArray":"$$ROOT"},
"in": {
"k":"$$this.k",
"t":{"$type":"$$this.v"}
}
}
}
}},
{"$unwind" : "$fields"},
{"$group" : {
"_id" : "$fields.k",
"types" : {
"$addToSet":"$fields.t"
}
}
}
{"fields":{"k":"vid","t":"string",
{"fields":{"k":"msgId", "t": "string"},
{"fields":{"k":"date","t": double},
{"fields":{"k":"status", "t": "string"},
{"fields":{"k":"comment", "t": "string"},
{"fields":{"k":"vid","t":"string",
{"fields":{"k":"msgId", "t": "string"},
{"fields":{"k":"date","t": double},
{"fields":{"k":"status", "t": "string"},
{"fields":{"k":"comment", "t": "string"}
...
$unwind $group
{ "_id": "comment", "types": ["string"]},
{ "_id": "status", "types": ["string"]},
{ "_id": "date", "types": ["double"]},
{ "_id": "msgId", "types": ["string"]},
{ "_id": "vid", "types": ["string"]},
...
$project
{
"vid": "072ade7d42d8",
"msgId": "bcd1d9",
"date": 1486546629585,
"status": "accept",
"comment": "hi"
},
{
"vid": "595d0a56cff2",
"msgId": "595d0a",
"date": 1486566646197,
"status": "reject",
"comment": "no good"
},
...
{"$project": {
"fields": {
"$map": {
"input":{
"$objectToArray":"$$ROOT"},
"in": {
"k":"$$this.k",
"t":{"$type":"$$this.v"}
}
}
}
}},
{"$unwind" : "$fields"},
{"$group" : {
"_id" : {
"k":"$fields.k",
"t":"$fields.t"
},
"c":{"$sum":1}
} }
{"fields": [
{ "k":"vid","t":"string",
{ "k":"msgId", "t": "string"},
{ "k":"date","t": double},
{ "k":"status", "t": "string"},
{ "k":"comment", "t": "string"}
] },
{"fields": [
{ "k":"vid","t":"string",
{ "k":"msgId", "t": "string"},
{ "k":"date","t": "double"},
{ "k":"status", "t": "string"},
{ "k":"comment", "t": "string"}
] },
...
{"fields":{"k":"vid","t":"string",
{"fields":{"k":"msgId", "t": "string"},
{"fields":{"k":"date","t": double},
{"fields":{"k":"status", "t": "string"},
{"fields":{"k":"comment", "t": "string"},
{"fields":{"k":"vid","t":"string",
{"fields":{"k":"msgId", "t": "string"},
{"fields":{"k":"date","t": double},
{"fields":{"k":"status", "t": "string"},
{"fields":{"k":"comment", "t": "string"}
...
$unwind
{"_id":{"k":"status","t":"string"},
"c":100
},
{"_id":{"k":"comment","t":"string" },
"c":100
},
{"_id":{"k":"date","t":"double" },
"c":100
},
{"_id":{"k":"msgId","t":"string"},
"c":100
},
{"_id":{"k":"vid","t":"string"},
"c":100
}
...
$group
# M D B l o c a l
SCHEMA TRANSFORMATION
{"body": {
"VMESSAGE": {
"072ade7d42d8": {
"msgId": "bcd1d9",
"date":1486546629585,
"status": "accept",
"comment": "hi"
} } } },
{"body": {
"VMESSAGE": {
"595d0a56cff2": {
"msgId": "595d0a",
"date":1486566646197,
"status": "reject",
"comment": "no good"
} } } },
{ "body": {
"VMESSAGE": {
"52ffd09bf5b5": {
"msgId": "1dadce",
"date":1486568943752,
"status": "accept"
} } } }
{"message": {
"vid": "072ade7d42d8",
"msgId": "bcd1d9",
"date": 1486546629585,
"status": "accept",
"comment": "hi"
} },
{"message": {
"vid": "595d0a56cff2",
"msgId": "595d0a",
"date": 1486566646197,
"status": "reject",
"comment": "no good"
} },
{"message": {
"vid": "52ffd09bf5b5",
"msgId": "1dadce",
"date": 1486568943752,
"status": "accept"
} }
{"$addFields":{
"message":{
"$let":{
"vars":{
"elem": {"$arrayElemAt:[
{"$objectToArray":"$body.VMESSAGE"},
0
]}
},
"in":{"$mergeObjects":[
{"vid": "$$elem.k" },
"$$elem.v"
]}
}
}
}}
{"body": {
"VMESSAGE": {
"072ade7d42d8": {
"msgId": "bcd1d9",
"date":1486546629585,
"status": "accept",
"comment": "hi"
} } } },
{"body": {
"VMESSAGE": {
"595d0a56cff2": {
"msgId": "595d0a",
"date":1486566646197,
"status": "reject",
"comment": "no good"
} } } },
{ "body": {
"VMESSAGE": {
"52ffd09bf5b5": {
"msgId": "1dadce",
"date":1486568943752,
"status": "accept"
} } } }
{"message": {
"vid": "072ade7d42d8",
"msgId": "bcd1d9",
"date": 1486546629585,
"status": "accept",
"comment": "hi"
} },
{"message": {
"vid": "595d0a56cff2",
"msgId": "595d0a",
"date": 1486566646197,
"status": "reject",
"comment": "no good"
} },
{"message": {
"vid": "52ffd09bf5b5",
"msgId": "1dadce",
"date": 1486568943752,
"status": "accept"
} }
# M D B l o c a l
AGGREGATION
FIND QUERY
UPDATE QUERY
DOCUMENT VALIDATION
EXPRESSIONS
{children:[
{name:"Max",dob:"1994-12-01",dep:true},
{name:"Sam",dob:"1997-09-28",dep:true},
{name:"Kim",dob:"2000-02-29",dep:true}
]}
# M D B l o c a l
AGGREGATION
FIND QUERY
UPDATE QUERY
DOCUMENT VALIDATION
{children:[
{name:"Max",dob:"1994-12-01",dep:false},
{name:"Sam",dob:"1997-09-28",dep:true},
{name:"Kim",dob:"2000-02-29",dep:true}
]}
db.c.aggregate([
{$addFields:{
numChildren:{$size:"$children"},
numDependents:{$size:{
$filter:{
input:"$children.dep",
cond:"$$this"
}
}}
}},
...
])
EXPRESSIONS
# M D B l o c a l
AGGREGATION
FIND QUERY
UPDATE QUERY
DOCUMENT VALIDATION
{children:[
{name:"Max",dob:"1994-12-01",dep:false},
{name:"Sam",dob:"1997-09-28",dep:true},
{name:"Kim",dob:"2000-02-29",dep:true}
]}
db.c.find({$expr:{$gt:["$a","$b"]}})
NEW IN 3.6
EXPRESSIONS
# M D B l o c a l
AGGREGATION
FIND QUERY
UPDATE QUERY
DOCUMENT VALIDATION
EXPRESSIONS
{children:[
{name:"Max",dob:"1994-12-01",dep:false},
{name:"Sam",dob:"1997-09-28",dep:true},
{name:"Kim",dob:"2000-02-29",dep:true}
]}
db.c.find({$expr:{
$lt:[{$size:{$filter:{
input:"$children.dep",
cond:"$$this"
}}},
2
]
}})
NEW IN 3.6
# M D B l o c a l
AGGREGATION
FIND QUERY
UPDATE QUERY
DOCUMENT VALIDATION
EXPRESSIONS
{children:[
{name:"Max",dob:"1994-12-01",dep:false},
{name:"Sam",dob:"1997-09-28",dep:true},
{name:"Kim",dob:"2000-02-29",dep:true}
]}
db.c.find({$expr:{$gt:[
{$let:{
vars:{dobs:{$map:{
input:"$children.dob"
in:{$year:{$dateFromString:{
dateString:"$$this"
}}}}}},
in:{$subtract:[
{$max:"$$dobs"},
{$min:"$$dobs"}
]}}},
10
]}})
NEW IN 3.6
# M D B l o c a l
AGGREGATION
FIND QUERY
UPDATE QUERY
DOCUMENT VALIDATION
EXPRESSIONS
{children:[
{name:"Max",dob:"1994-12-01",dep:false},
{name:"Sam",dob:"1997-09-28",dep:true},
{name:"Kim",dob:"2000-02-29",dep:true}
]}
db.c.update({$expr:{$anyElementTrue:{$map:{
input:"$children",
in:{$and:[
{$lt:["$$this.dob","1997-04-24"]},
"$$this.dep"
]}
}}}},
{$set:{audit:true}}
)
NEW IN 3.6
# M D B l o c a l
AGGREGATION
FIND QUERY
UPDATE QUERY
DOCUMENT VALIDATION
EXPRESSIONS
{children:[
{name:"Max",dob:"1994-12-01",dep:false},
{name:"Sam",dob:"1997-09-28",dep:true},
{name:"Kim",dob:"2000-02-29",dep:true}
]}
db.createCollection("c",validator:
{$expr:{
<anythingyoucanexpress>
}})
NEW IN 3.6
# M D B l o c a l
See you again after the break!
Coming Up Next:
Aggregation Performance
Aggregation in Sharding
and A use case
#MDBlocal
PIPELINE POWER
DOING MORE WITH MONGODB AGGREGATION
Ankur Raina MongoDB Inc @rainaankur92
# M D B l o c a l
Can you EXPLAIN ?
db.books.aggregate([
{$match:{"language":"English"}},
{$unwind:"$subjects"},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3}
],{explain:true})
{"stages" : [
{"$cursor" : {"query" : { "language" : "English"},
"fields" : { "subjects" : 1,"_id" : 0} ...
}},
{"$unwind" : {"path" : "$subjects"}},
{"$group" : {"_id" : "$subjects","count" : {"$sum" : {"$const" : 1}} }},
{"$sort" : {
"sortKey" : {"count" : -1},
"limit" : NumberLong(3)
}}
] }
db.books.aggregate([
{$match:{"language":"English"}},
{$unwind:"$subjects"},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3}
],{explain:true})
{"stages" : [
{"$cursor" : {"query" : { "language" : "English"},
"fields" : { "subjects" : 1,"_id" : 0} ...
}},
{"$unwind" : {"path" : "$subjects"}},
{"$group" : {"_id" : "$subjects","count" : {"$sum" : {"$const" : 1}} }},
{"$sort" : {
"sortKey" : {"count" : -1},
"limit" : NumberLong(3)
}}
] }
db.books.aggregate([
{$match:{"language":"English"}},
{$unwind:"$subjects"},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3}
],{explain:true})
{"stages" : [
{"$cursor" : {"query" : { },
"fields" : { "subjects" : 1,"_id" : 0} ...
}},
{"$unwind" : {"path" : "$subjects"}},
{"$group" : {"_id" : "$subjects","count" : {"$sum" : {"$const" : 1}} }},
{"$sort" : {
"sortKey" : {"count" : -1},
"limit" : NumberLong(3)
}}
] }
db.books.aggregate([
{$unwind:"$subjects"},
{$match:{"language":"English"}},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3}
],{explain:true})
db.books.aggregate([
{$unwind:"$subjects"},
{$match:{"language":"English"}},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3}
],{explain:true})
{"stages" : [
{"$cursor" : {"query" : { "language" : "English"},
"fields" : { "subjects" : 1,"_id" : 0} ...
}},
{"$unwind" : {"path" : "$subjects"}},
{"$group" : {"_id" : "$subjects","count" : {"$sum" : {"$const" : 1}} }},
{"$sort" : {
"sortKey" : {"count" : -1},
"limit" : NumberLong(3)
}}
] }
db.books.aggregate([
{$unwind:"$subjects"},
{$match:{"language":"English","subjects":/^[ABC]/}},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3}
],{explain:true})
{"stages" : [
{"$cursor" : {"query" : { "language" : "English"},
"fields" : { "subjects" : 1,"_id" : 0} ...
}},
{"$unwind" : {"path" : "$subjects"}},
{"$match" : {"subjects" : {"$regex" : "^[ABC]"}}},
{"$group" : {"_id" : "$subjects","count" : {"$sum" : {"$const" : 1}}}},
{"$sort" : {
"sortKey" : {"count" : -1},
"limit" : NumberLong(3)
}}
] }
db.books.aggregate([
{$unwind:"$subjects"},
{$match:{"language":"English","subjects":/^[ABC]/}},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3}
],{explain:true})
{"stages" : [
{"$cursor" : {"query" : { "language" : "English"},
"fields" : { "subjects" : 1,"_id" : 0} ...
}},
{"$unwind" : {"path" : "$subjects"}},
{"$match" : {"subjects" : {"$regex" : "^[ABC]"}}},
{"$group" : {"_id" : "$subjects","count" : {"$sum" : {"$const" : 1}}}},
{"$sort" : {
"sortKey" : {"count" : -1},
"limit" : NumberLong(3)
}}
] }
# M D B l o c a l
NETWORK SUSPECT
ACTIVITY DETECTION
start=ISODate("...")
end=ISODate("...")
{
user: "303900",
ipaddr: "71.56.112.56",
ts:ISODate("2017-05-08T05:28:13Z")
}
{$match:{ts:{$gte:start,$lt:end}}},
{$sort:{ts:1}},
{$group:{_id:"$user",ips:{$push:{ip:"$ipaddr", ts:"$ts"}}}},
$sort$match $group
start=ISODate("...")
end=ISODate("...")
{
user: "303900",
ipaddr: "71.56.112.56",
ts:ISODate("2017-05-08T...")
}
{ _id: "303900",
ips: [
{ip:"71.56.112.56",
ts:ISODate("2017-05-08T08:54:04Z")
},
{ip:"71.56.112.56",
ts:ISODate("2017-05-09T09:01:11Z")
},
{ip:"12.130.117.87",
ts:ISODate("2017-05-09T09:04:59Z")
}
]}
$sort$match $group $addFields $match
start=ISODate("...")
end=ISODate("...")
{
user: "303900",
ipaddr: "71.56.112.56",
ts:ISODate("2017-05-08T...")
}
$project
{_id:"303900",
ips:[
{ip:"71.56.112.56",
ts:ISODate("2017-05-08T...")
},
{ip:"71.56.112.56",
ts:ISODate("2017-05-09T...")
},
{ip:"12.130.117.87",
ts:ISODate("2017-05-09T...")
}
]}
{$match:{ts:{$gte:start,$lt:end}}},
{$sort:{ts:1}},
{$group:{_id:"$user",ips:{$push:{ip:"$ipaddr", ts:"$ts"}}}},
{$addFields:{diffs: {$filter:{
input:{$map:{
input: {$range:[0,{$subtract:[{$size:"$ips"},1]}]}, as:"i",
in:{$let:{vars:{ip1:{$arrayElemAt:["$ips","$$i"]},
ip2:{$arrayElemAt:["$ips",{$add:["$$i",1]}]}},
in:{
diff:{$divide:[{$subtract:["$$ip2.ts","$$ip1.ts"]},60000]},
ip1:"$$ip1.ip", t1:"$$ip1.ts",
ip2:"$$ip2.ip", t2:"$$ip2.ts"
}}}}},
cond:{$and:[{$lt:["$$this.diff",10]},{$ne:["$$this.ip1","$$this.ip2"]}]}
}}}},
$sort$match $group $addFields $match
start=ISODate("...")
end=ISODate("...")
{
user: "303900",
ipaddr: "71.56.112.56",
ts:ISODate("2017-05-08T...")
}
$project
{_id:"303900",
ips:[
{ip:"71.56.112.56",
ts:ISODate("2017-05-08T...")
},
{ip:"71.56.112.56",
ts:ISODate("2017-05-09T...")
},
{ip:"12.130.117.87",
ts:ISODate("2017-05-09T...")
}
]}
{$match:{ts:{$gte:start,$lt:end}}},
{$sort:{ts:1}},
{$group:{_id:"$user",ips:{$push:{ip:"$ipaddr", ts:"$ts"}}}},
{$addFields:{diffs: {$filter:{
input:{$map:{
input: {$range:[0,{$subtract:[{$size:"$ips"},1]}]}, as:"i",
in:{$let:{vars:{ip1:{$arrayElemAt:["$ips","$$i"]},
ip2:{$arrayElemAt:["$ips",{$add:["$$i",1]}]}},
in:{
diff:{$divide:[{$subtract:["$$ip2.ts","$$ip1.ts"]},60000]},
ip1:"$$ip1.ip", t1:"$$ip1.ts",
ip2:"$$ip2.ip", t2:"$$ip2.ts"
}}}}},
cond:{$and:[{$lt:["$$this.diff",10]},{$ne:["$$this.ip1","$$this.ip2"]}]}
}}}},
{$match:{"diffs":{$ne:[]}}},
{$project:{_id:0, user:"$_id", suspectLogins:"$diffs"}}
$sort$match $group $addFields $match
start=ISODate("...")
end=ISODate("...")
{
user: "303900",
ipaddr: "71.56.112.56",
ts:ISODate("2017-05-08T...")
}
$project
{$match:{ts:{$gte:start,$lt:end}}},
{$sort:{ts:1}},
{$group:{_id:"$user",ips:{$push:{ip:"$ipaddr", ts:"$ts"}}}},
{$addFields:{diffs: {$filter:{
input:{$map:{
input: {$range:[0,{$subtract:[{$size:"$ips"},1]}]}, as:"i",
in:{$let:{vars:{ip1:{$arrayElemAt:["$ips","$$i"]},
ip2:{$arrayElemAt:["$ips",{$add:["$$i",1]}]}},
in:{
diff:{$divide:[{$subtract:["$$ip2.ts","$$ip1.ts"]},60000]},
ip1:"$$ip1.ip", t1:"$$ip1.ts",
ip2:"$$ip2.ip", t2:"$$ip2.ts"
}}}}},
cond:{$and:[{$lt:["$$this.diff",10]},{$ne:["$$this.ip1","$$this.ip2"]}]}
}}}},
{$match:{"diffs":{$ne:[]}}},
{$project:{_id:0, user:"$_id", suspectLogins:"$diffs"}}
{"user":"35237073",
"suspectLogins":[
{"diff":4.8333333333,
"ip1":"106.220.151.16",
"t1":"2017-05-08T06:58",
"ip2":"223.182.113.15"
"t2":"2017-05-08T07:03"
},
{"diff":8.3,
"ip1":"223.182.113.15",
"t1":"2017-05-08T07:03",
"ip2":"49.206.217.26",
"t2":"2017-05-08T07:11"
}
]
}
$sort$match $group $addFields $match $project
{$match:{ts:{$gte:start,$lt:end}}},
{$sort:{ts:1}},
{$group:{_id:"$user",ips:{$push:{ip:"$ipaddr", ts:"$ts"}}}},
{$addFields:{diffs: {$filter:{
input:{$map:{
input: {$range:[0,{$subtract:[{$size:"$ips"},1]}]}, as:"i",
in:{$let:{vars:{ip1:{$arrayElemAt:["$ips","$$i"]},
ip2:{$arrayElemAt:["$ips",{$add:["$$i",1]}]}},
in:{
diff:{$divide:[{$subtract:["$$ip2.ts","$$ip1.ts"]},60000]},
ip1:"$$ip1.ip", t1:"$$ip1.ts",
ip2:"$$ip2.ip", t2:"$$ip2.ts"
}}}}},
cond:{$and:[{$lt:["$$this.diff",10]},{$ne:["$$this.ip1","$$this.ip2"]}]}
}}}},
{$match:{"diffs":{$ne:[]}}},
{$project:{_id:0, user:"$_id", suspectLogins:"$diffs"}}
start=ISODate("...")
end=ISODate("...")
{
user: "303900",
ipaddr: "71.56.112.56",
ts:ISODate("2017-05-08T...")
}
{_id:"303900",
ips:[
{ip:"71.56.112.56",
ts:ISODate("2017-05-08T...")
},
{ip:"71.56.112.56",
ts:ISODate("2017-05-09T...")
},
{ip:"12.130.117.87",
ts:ISODate("2017-05-09T...")
}
]}
$sort$match $group $addFields $match
start=ISODate("...")
end=ISODate("...")
{
user: "303900",
ipaddr: "71.56.112.56",
ts:ISODate("2017-05-08T...")
}
$addFields $match $proj
{$match:{ts:{$gte:start,$lt:end}}},
{$sort:{ts:1}},
{$group:{_id:"$user",ips:{$push:{ip:"$ipaddr", ts:"$ts"}}}},
{$addFields:{diffIpNum:{$size:{$setUnion:"$ips.ip"}}}},
{$match:{diffIpNum:{$gt:1}}},
{$addFields:{diffs: {$filter:{
input:{$map:{
input: {$range:[0,{$subtract:[{$size:"$ips"},1]}]}, as:"i",
in:{$let:{vars:{ip1:{$arrayElemAt:["$ips","$$i"]},
ip2:{$arrayElemAt:["$ips",{$add:["$$i",1]}]}},
in:{
diff:{$divide:[{$subtract:["$$ip2.ts","$$ip1.ts"]},60000]},
ip1:"$$ip1.ip", t1:"$$ip1.ts",
ip2:"$$ip2.ip", t2:"$$ip2.ts"
}}}}},
cond:{$and:[{$lt:["$$this.diff",10]},{$ne:["$$this.ip1","$$this.ip2"]}]}
}}}},
{$match:{"diffs":{$ne:[]}}},
{$project:{_id:0, user:"$_id", suspectLogins:"$diffs"}}
{_id:"303900",
ips:[
{ip:"71.56.112.56",
ts:ISODate("2017-05-08T...")
},
{ip:"71.56.112.56",
ts:ISODate("2017-05-09T...")
},
{ip:"12.130.117.87",
ts:ISODate("2017-05-09T...")
}
]}
$sort$match $group $match
start=ISODate("...")
end=ISODate("...")
{
user: "303900",
ipaddr: "71.56.112.56",
ts:ISODate("2017-05-08T...")
}
$addFields $match $project
{$match:{ts:{$gte:start,$lt:end}}},
{$sort:{ts:1}},
{$group:{_id:"$user",ips:{$push:{ip:"$ipaddr", ts:"$ts"}},
diffIps:{$addToSet:"$ipaddr"}}},
{$match:{$expr:{$gt:[{$size:"$diffIps"},1]}}},
{$addFields:{diffs: {$filter:{
input:{$map:{
input: {$range:[0,{$subtract:[{$size:"$ips"},1]}]}, as:"i",
in:{$let:{vars:{ip1:{$arrayElemAt:["$ips","$$i"]},
ip2:{$arrayElemAt:["$ips",{$add:["$$i",1]}]}},
in:{
diff:{$divide:[{$subtract:["$$ip2.ts","$$ip1.ts"]},60000]},
ip1:"$$ip1.ip", t1:"$$ip1.ts",
ip2:"$$ip2.ip", t2:"$$ip2.ts"
}}}}},
cond:{$and:[{$lt:["$$this.diff",10]},{$ne:["$$this.ip1","$$this.ip2"]}]}
}}}},
{$match:{"diffs":{$ne:[]}}},
{$project:{_id:0, user:"$_id", suspectLogins:"$diffs"}}
{_id:"303900",
ips:[
{ip:"71.56.112.56",
ts:ISODate("2017-05-08T...")
},
{ip:"71.56.112.56",
ts:ISODate("2017-05-09T...")
},
{ip:"12.130.117.87",
ts:ISODate("2017-05-09T...")
},
diffIps:[
"71.56.112.56",
"12.130.117.87"
]
]}
$sort$match $group $match
start=ISODate("...")
end=ISODate("...")
{
user: "303900",
ipaddr: "71.56.112.56",
ts:ISODate("2017-05-08T...")
}
$addFields $match $project
{$match:{ts:{$gte:start,$lt:end}}},
{$sort:{ts:1}},
{$group:{_id:"$user",ips:{$push:{ip:"$ipaddr", ts:"$ts"}},
diffIps:{$addToSet:"$ipaddr"}}},
{$match:{"diffIps.1":{$exists:true}}},
{$addFields:{diffs: {$filter:{
input:{$map:{
input: {$range:[0,{$subtract:[{$size:"$ips"},1]}]}, as:"i",
in:{$let:{vars:{ip1:{$arrayElemAt:["$ips","$$i"]},
ip2:{$arrayElemAt:["$ips",{$add:["$$i",1]}]}},
in:{
diff:{$divide:[{$subtract:["$$ip2.ts","$$ip1.ts"]},60000]},
ip1:"$$ip1.ip", t1:"$$ip1.ts",
ip2:"$$ip2.ip", t2:"$$ip2.ts"
}}}}},
cond:{$and:[{$lt:["$$this.diff",10]},{$ne:["$$this.ip1","$$this.ip2"]}]}
}}}},
{$match:{"diffs":{$ne:[]}}},
{$project:{_id:0, user:"$_id", suspectLogins:"$diffs"}}
{_id:"303900",
ips:[
{ip:"71.56.112.56",
ts:ISODate("2017-05-08T...")
},
{ip:"71.56.112.56",
ts:ISODate("2017-05-09T...")
},
{ip:"12.130.117.87",
ts:ISODate("2017-05-09T...")
},
diffIps:[
"71.56.112.56",
"12.130.117.87"
]
]}
$sort$match $group
start=ISODate("...")
end=ISODate("...")
{
user: "303900",
ipaddr: "71.56.112.56",
ts:ISODate("2017-05-08T...")
}
{$match:{ts:{$gte:start,$lt:end}}},
{$sort:{ts:1}},
{$group:{_id:"$user",ips:{$push:{ip:"$ipaddr", ts:"$ts"}},
diffIps:{$addToSet:"$ipaddr"}}},
{$match:{"diffIps.1":{$exists:true}}},
{$addFields:{diffs: {$filter:{
input:{$map:{
input: {$range:[0,{$subtract:[{$size:"$ips"},1]}]}, as:"i",
in:{$let:{vars:{ip1:{$arrayElemAt:["$ips","$$i"]},
ip2:{$arrayElemAt:["$ips",{$add:["$$i",1]}]}},
in:{
diff:{$divide:[{$subtract:["$$ip2.ts","$$ip1.ts"]},60000]},
ip1:"$$ip1.ip", t1:"$$ip1.ts",
ip2:"$$ip2.ip", t2:"$$ip2.ts"
}}}}},
cond:{$and:[{$lt:["$$this.diff",10]},{$ne:["$$this.ip1","$$this.ip2"]}]}
}}}},
{$match:{"diffs":{$ne:[]}}},
{$project:{_id:0, user:"$_id", suspectLogins:"$diffs"}}
$match $addFields $match $project
{_id:"303900",
ips:[
{ip:"71.56.112.56",
ts:ISODate("2017-05-08T...")
},
{ip:"71.56.112.56",
ts:ISODate("2017-05-09T...")
},
{ip:"12.130.117.87",
ts:ISODate("2017-05-09T...")
},
diffIps:[
"71.56.112.56",
"12.130.117.87"
]
]}
$sort$match $group
start=ISODate("...")
end=ISODate("...")
{
user: "303900",
ipaddr: "71.56.112.56",
ts:ISODate("2017-05-08T...")
}
{$match:{ts:{$gte:start,$lt:end}}},
{$sort:{ts:1}},
{$group:{_id:"$user",ips:{$push:{ip:"$ipaddr", ts:"$ts"}},
diffIps:{$addToSet:"$ipaddr"}}},
{$match:{"diffIps.1":{$exists:true}}},
{$addFields:{diffs: {$filter:{
input:{$map:{
input: {$range:[0,{$subtract:[{$size:"$ips"},1]}]}, as:"i",
in:{$let:{vars:{ip1:{$arrayElemAt:["$ips","$$i"]},
ip2:{$arrayElemAt:["$ips",{$add:["$$i",1]}]}},
in:{
diff:{$cond:{
}},
ip1:"$$ip1.ip", t1:"$$ip1.ts",
ip2:"$$ip2.ip", t2:"$$ip2.ts"
}}}}},
cond:{$and:[{$lt:["$$this.diff",10]},{$ne:["$$this.ip1","$$this.ip2"]}]}
}}}},
{$match:{"diffs":{$ne:[]}}},
{$project:{_id:0, user:"$_id", suspectLogins:"$diffs"}}
$match $addFields $match $project
{_id:"303900",
ips:[
{ip:"71.56.112.56",
ts:ISODate("2017-05-08T...")
},
{ip:"71.56.112.56",
ts:ISODate("2017-05-09T...")
},
{ip:"12.130.117.87",
ts:ISODate("2017-05-09T...")
},
diffIps:[
"71.56.112.56",
"12.130.117.87"
]
]}
$sort$match $group
start=ISODate("...")
end=ISODate("...")
{
user: "303900",
ipaddr: "71.56.112.56",
ts:ISODate("2017-05-08T...")
}
{$match:{ts:{$gte:start,$lt:end}}},
{$sort:{ts:1}},
{$group:{_id:"$user",ips:{$push:{ip:"$ipaddr", ts:"$ts"}},
diffIps:{$addToSet:"$ipaddr"}}},
{$match:{"diffIps.1":{$exists:true}}},
{$addFields:{diffs: {$filter:{
input:{$map:{
input: {$range:[0,{$subtract:[{$size:"$ips"},1]}]}, as:"i",
in:{$let:{vars:{ip1:{$arrayElemAt:["$ips","$$i"]},
ip2:{$arrayElemAt:["$ips",{$add:["$$i",1]}]}},
in:{
diff:{$cond:{
if:{$ne:["$$ip1.ip","$$ip2.ip"]},
then:{$divide:[{$subtract:["$$ip2.ts","$$ip1.ts"]},60000]},
else: 9999 }},
ip1:"$$ip1.ip", t1:"$$ip1.ts",
ip2:"$$ip2.ip", t2:"$$ip2.ts"
}}}}},
cond:{$and:[{$lt:["$$this.diff",10]},{$ne:["$$this.ip1","$$this.ip2"]}]}
}}}},
{$match:{"diffs":{$ne:[]}}},
{$project:{_id:0, user:"$_id", suspectLogins:"$diffs"}}
$match $addFields $match $project
{_id:"303900",
ips:[
{ip:"71.56.112.56",
ts:ISODate("2017-05-08T...")
},
{ip:"71.56.112.56",
ts:ISODate("2017-05-09T...")
},
{ip:"12.130.117.87",
ts:ISODate("2017-05-09T...")
},
diffIps:[
"71.56.112.56",
"12.130.117.87"
]
]}
$sort$match $group
start=ISODate("...")
end=ISODate("...")
{
user: "303900",
ipaddr: "71.56.112.56",
ts:ISODate("2017-05-08T...")
}
{$match:{ts:{$gte:start,$lt:end}}},
{$sort:{ts:1}},
{$group:{_id:"$user",ips:{$push:{ip:"$ipaddr", ts:"$ts"}},
diffIps:{$addToSet:"$ipaddr"}}},
{$match:{"diffIps.1":{$exists:true}}},
{$addFields:{diffs: {$filter:{
input:{$map:{
input: {$range:[0,{$subtract:[{$size:"$ips"},1]}]}, as:"i",
in:{$let:{vars:{ip1:{$arrayElemAt:["$ips","$$i"]},
ip2:{$arrayElemAt:["$ips",{$add:["$$i",1]}]}},
in:{
diff:{$cond:{
if:{$ne:["$$ip1.ip","$$ip2.ip"]},
then:{$divide:[{$subtract:["$$ip2.ts","$$ip1.ts"]},60000]},
else: 9999 }},
ip1:"$$ip1.ip", t1:"$$ip1.ts",
ip2:"$$ip2.ip", t2:"$$ip2.ts"
}}}}},
cond:{$and:[{$lt:["$$this.diff",10]},{$ne:["$$this.ip1","$$this.ip2"]}]}
}}}},
{$match:{"diffs":{$ne:[]}}},
{$project:{_id:0, user:"$_id", suspectLogins:"$diffs"}}
$match $addFields $match $project
{_id:"303900",
ips:[
{ip:"71.56.112.56",
ts:ISODate("2017-05-08T...")
},
{ip:"71.56.112.56",
ts:ISODate("2017-05-09T...")
},
{ip:"12.130.117.87",
ts:ISODate("2017-05-09T...")
},
diffIps:[
"71.56.112.56",
"12.130.117.87"
]
]}
$sort$match $group
start=ISODate("...")
end=ISODate("...")
{
user: "303900",
ipaddr: "71.56.112.56",
ts:ISODate("2017-05-08T...")
}
{$match:{ts:{$gte:start,$lt:end}}},
{$sort:{ts:1}},
{$group:{_id:"$user",ips:{$push:{ip:"$ipaddr", ts:"$ts"}},
diffIps:{$addToSet:"$ipaddr"}}},
{$match:{"diffIps.1":{$exists:true}}},
{$addFields:{diffs: {$filter:{
input:{$map:{
input: {$range:[0,{$subtract:[{$size:"$ips"},1]}]}, as:"i",
in:{$let:{vars:{ip1:{$arrayElemAt:["$ips","$$i"]},
ip2:{$arrayElemAt:["$ips",{$add:["$$i",1]}]}},
in:{
diff:{$cond:{
if:{$ne:["$$ip1.ip","$$ip2.ip"]},
then:{$divide:[{$subtract:["$$ip2.ts","$$ip1.ts"]},60000]},
else: 9999 }},
ip1:"$$ip1.ip", t1:"$$ip1.ts",
ip2:"$$ip2.ip", t2:"$$ip2.ts"
}}}}},
cond:{$lt:["$$this.diff",10]}
}}}},
{$match:{"diffs":{$ne:[]}}},
{$project:{_id:0, user:"$_id", suspectLogins:"$diffs"}}
{"user":"35237073",
"suspectLogins":[
{"diff":4.8333333333,
"ip1":"106.220.151.16",
"t1":"2017-05-08T06:58",
"ip2":"223.182.113.15"
"t2":"2017-05-08T07:03"
},
{"diff":8.3,
"ip1":"223.182.113.15",
"t1":"2017-05-08T07:03",
"ip2":"49.206.217.26",
"t2":"2017-05-08T07:11"
}
]
} $match $addFields $match $project
$sort$match $group
start=ISODate("...")
end=ISODate("...")
{
user: "303900",
ipaddr: "71.56.112.56",
ts:ISODate("2017-05-08T...")
}
{$match:{ts:{$gte:start,$lt:end}}},
{$sort:{ts:1}},
{$group:{_id:"$user",ips:{$push:{ip:"$ipaddr", ts:"$ts"}},
diffIps:{$addToSet:"$ipaddr"}}},
{$match:{"diffIps.1":{$exists:true}}},
{$addFields:{diffs: {$filter:{
input:{$map:{
input: {$range:[0,{$subtract:[{$size:"$ips"},1]}]}, as:"i",
in:{$let:{vars:{ip1:{$arrayElemAt:["$ips","$$i"]},
ip2:{$arrayElemAt:["$ips",{$add:["$$i",1]}]}},
in:{
diff:{$cond:{
if:{$ne:["$$ip1.ip","$$ip2.ip"]},
then:{$divide:[{$subtract:["$$ip2.ts","$$ip1.ts"]},60000]},
else: 9999 }},
ip1:"$$ip1.ip", t1:"$$ip1.ts",
ip2:"$$ip2.ip", t2:"$$ip2.ts"
}}}}},
cond:{$lt:["$$this.diff",10]}
}}}},
{$match:{"diffs":{$ne:[]}}},
{$project:{_id:0, user:"$_id", suspectLogins:"$diffs"}}
{"user":"35237073",
"suspectLogins":[
{"diff":4.8333333333,
"ip1":"106.220.151.16",
"t1":"2017-05-08T06:58",
"ip2":"223.182.113.15"
"t2":"2017-05-08T07:03"
},
{"diff":8.3,
"ip1":"223.182.113.15",
"t1":"2017-05-08T07:03",
"ip2":"49.206.217.26",
"t2":"2017-05-08T07:11"
}
]
} $match $addFields $match $project
$sort$match $group
start=ISODate("...")
end=ISODate("...")
{
user: "303900",
ipaddr: "71.56.112.56",
ts:ISODate("2017-05-08T...")
}
{$match:{ts:{$gte:start,$lt:end}}},
{$sort:{ts:1}},
{$group:{_id:"$user",ips:{$push:{ip:"$ipaddr", ts:"$ts"}},
diffIps:{$addToSet:"$ipaddr"}}},
{$match:{"diffIps.1":{$exists:true}}},
{$addFields:{diffs: {$filter:{
input:{$map:{
input: {$range:[0,{$subtract:[{$size:"$ips"},1]}]}, as:"i",
in:{$let:{vars:{ip1:{$arrayElemAt:["$ips","$$i"]},
ip2:{$arrayElemAt:["$ips",{$add:["$$i",1]}]}},
in:{
diff:{$cond:{
if:{$ne:["$$ip1.ip","$$ip2.ip"]},
then:{$divide:[{$subtract:["$$ip2.ts","$$ip1.ts"]},60000]},
else: 9999 }},
ip1:"$$ip1.ip", t1:"$$ip1.ts",
ip2:"$$ip2.ip", t2:"$$ip2.ts"
}}}}},
cond:{$lt:["$$this.diff",10]}
}}}},
{$match:{"diffs":{$ne:[]}}},
{$project:{_id:0, user:"$_id", suspectLogins:"$diffs"}}
{"user":"35237073",
"suspectLogins":[
{"diff":4.8333333333,
"ip1":"106.220.151.16",
"t1":"2017-05-08T06:58",
"ip2":"223.182.113.15"
"t2":"2017-05-08T07:03"
},
{"diff":8.3,
"ip1":"223.182.113.15",
"t1":"2017-05-08T07:03",
"ip2":"49.206.217.26",
"t2":"2017-05-08T07:11"
}
]
} $match $addFields $match $project
$sort$match $group
start=ISODate("...")
end=ISODate("...")
{
user: "303900",
ipaddr: "71.56.112.56",
ts:ISODate("2017-05-08T...")
}
{$match:{ts:{$gte:start,$lt:end}}},
{$sort:{ts:1}},
{$group:{_id:"$user",ips:{$push:{ip:"$ipaddr", ts:"$ts"}},
diffIps:{$addToSet:"$ipaddr"}}},
{$match:{"diffIps.1":{$exists:true}}},
{$addFields:{diffs: {$filter:{
input:{$map:{
input: {$range:[0,{$subtract:[{$size:"$ips"},1]}]}, as:"i",
in:{$let:{vars:{ip1:{$arrayElemAt:["$ips","$$i"]},
ip2:{$arrayElemAt:["$ips",{$add:["$$i",1]}]}},
in:{
diff:{$cond:{
if:{$ne:["$$ip1.ip","$$ip2.ip"]},
then:{$divide:[{$subtract:["$$ip2.ts","$$ip1.ts"]},60000]},
else: 9999 }},
ip1:"$$ip1.ip", t1:"$$ip1.ts",
ip2:"$$ip2.ip", t2:"$$ip2.ts"
}}}}},
cond:{$lt:["$$this.diff",10]}
}}}},
{$match:{"diffs":{$ne:[]}}},
{$project:{_id:0, user:"$_id", suspectLogins:"$diffs"}}
{"user":"35237073",
"suspectLogins":[
{"diff":4.8333333333,
"ip1":"106.220.151.16",
"t1":"2017-05-08T06:58",
"ip2":"223.182.113.15"
"t2":"2017-05-08T07:03"
},
{"diff":8.3,
"ip1":"223.182.113.15",
"t1":"2017-05-08T07:03",
"ip2":"49.206.217.26",
"t2":"2017-05-08T07:11"
}
]
} $match $addFields $match $project
# M D B l o c a l
streaming vs blocking
SHARDING & MERGING
SHARDING
SHARDING
SHARDING
SHARDING
SHARDING
SHARDING
SHARDING AGGREGATION
SHARDING AGGREGATION
SHARDING AGGREGATION
SHARDING AGGREGATION
SHARDING AGGREGATION
#MDBlocal
SHARDING AGGREGATION
Work starts on individual shards
only "targeted" shards
"Merging" for first "blocking" stage is split into two parts
shards part (each shard starts the merging work)
merge part (merging finishes at "merge" location)
Final merge can happen on primary shard, any shard or mongos
on mongos (starting in 3.6 only)
Merging with only streaming stages happens on 'mongos' same as "find"
# M D B l o c a l
I CAN EXPLAIN!
I CAN EXPLAIN
db.books.aggregate([
{$unwind:"$subjects"},
{$match:{"language":"English","subjects":/^[ABC]/}},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3} ], {explain:true})
db.books.aggregate([
{$unwind:"$subjects"},
{$match:{"language":"English","subjects":/^[ABC]/}},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3} ], {explain:true})
{
mergeType:
splitPipeline:
shards:
}
db.books.aggregate([
{$unwind:"$subjects"},
{$match:{"language":"English","subjects":/^[ABC]/}},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3} ], {explain:true})
{
mergeType:
splitPipeline:
shards:
}
"primaryShard"
"anyShard"
"mongos"
db.books.aggregate([
{$unwind:"$subjects"},
{$match:{"language":"English","subjects":/^[ABC]/}},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3} ], {explain:true})
{
mergeType: "mongos",
splitPipeline:
shards:
}
db.books.aggregate([
{$unwind:"$subjects"},
{$match:{"language":"English","subjects":/^[ABC]/}},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3} ], {explain:true, allowDiskUse: true })
{
mergeType: "anyShard",
splitPipeline:
shards:
}
db.books.aggregate([
{$unwind:"$subjects"},
{$match:{"language":"English","subjects":/^[ABC]/}},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3}, {$out: "output"} ], {explain:true})
{
mergeType: "primaryShard",
splitPipeline:
shards:
}
db.books.aggregate([
{$unwind:"$subjects"},
{$match:{"language":"English","subjects":/^[ABC]/}},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3} ], {explain:true})
{
mergeType:
splitPipeline:
shards:
}
{ "shardsPart" : [
],
"mergerPart" : [
] },
db.books.aggregate([
{$unwind:"$subjects"},
{$match:{"language":"English","subjects":/^[ABC]/}},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3} ], {explain:true})
{
mergeType:
splitPipeline:
shards:
}
{ "shardsPart" : [
{"$match" :{"language": {"$eq":"English"}}},
{"$unwind":{"path": "$subjects"}},
{"$match" :{"subjects": {"$regex":"^[ABC]"}}},
{"$group" :{"_id":"$subjects","count":{"$sum":1}}}
],
"mergerPart" : [
] },
db.books.aggregate([
{$unwind:"$subjects"},
{$match:{"language":"English","subjects":/^[ABC]/}},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3} ], {explain:true})
{
mergeType:
splitPipeline:
shards:
}
{ "shardsPart" : [
{"$match" :{"language": {"$eq":"English"}}},
{"$unwind":{"path": "$subjects"}},
{"$match" :{"subjects": {"$regex":"^[ABC]"}}},
{"$group" :{"_id":"$subjects","count":{"$sum":1}}}
],
"mergerPart" : [
{"$group":{
"_id":"$$ROOT._id",
"count":{"$sum":"$$ROOT.count"},
"$doingMerge" : true}},
{"$sort":{
"sortKey":{"count" : -1},
"limit":NumberLong(3)}}
] },
db.books.aggregate([
{$unwind:"$subjects"},
{$match:{"language":"English","subjects":/^[ABC]/}},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3} ], {explain:true})
{
mergeType:
splitPipeline:
shards:
}
{ "shardsPart" : [
{"$match" :{"language": {"$eq":"English"}}},
{"$unwind":{"path": "$subjects"}},
{"$match" :{"subjects": {"$regex":"^[ABC]"}}},
{"$group" :{"_id":"$subjects","count":{"$sum":1}}}
],
"mergerPart" : [
{"$group":{
"_id":"$$ROOT._id",
"count":{"$sum":"$$ROOT.count"},
"$doingMerge" : true}},
{"$sort":{
"sortKey":{"count" : -1},
"limit":NumberLong(3)}}
] },
db.books.aggregate([
{$unwind:"$subjects"},
{$match:{"language":"English","subjects":/^[ABC]/}},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3} ], {explain:true})
{
mergeType:
splitPipeline:
shards:
}
{ "shard0000" : {
},
"shard0001" : {
}
}
db.books.aggregate([
{$unwind:"$subjects"},
{$match:{"language":"English","subjects":/^[ABC]/}},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3} ], {explain:true})
{
mergeType:
splitPipeline:
shards: { "shard0000" : {
"host": <hostname>,
"stages": [ ]
},
"shard0001" : {
"host": <hostname>,
"stages": [ ]
}
}
db.books.aggregate([
{$unwind:"$subjects"},
{$match:{"language":"English","subjects":/^[ABC]/}},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3} ], {explain:true})
{
mergeType:
splitPipeline:
shards: { "shard0000" : {
"host": <hostname>,
"stages": [
{"$cursor": {
"query":{"language":{"$eq":"English"}},
"fields":{"subjects":1,"_id":0},
"queryPlanner":{"plannerVersion":1,"namespace":"test.books", ...
},
{"$unwind":{"path":"$subjects"}},
{"$match":{"subjects":{"$regex":"^[ABC]"}}},
{"$group":{"_id":"$subjects","count":{"$sum":1}}}
]
db.books.aggregate([
{$unwind:"$subjects"},
{$match:{"language":"English","subjects":/^[ABC]/}},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3} ], {explain:true})
{
mergeType:
splitPipeline:
shards: { "shard0000" : {
"host": <hostname>,
"stages": [
{"$cursor": {
"query":{"language":{"$eq":"English"}},
"fields":{"subjects":1,"_id":0},
"queryPlanner":{"plannerVersion":1,"namespace":"test.books",
"winningPlan":{
"stage":"SHARDING_FILTER",
"inputStage":{ "stage":"FETCH",
"inputStage":{"stage":"IXSCAN",
"keyPattern":{"language":1,"subjects":1},
"indexName":"language_1_subjects_1","isMultiKey":false, ...
} } } }
} },
{"$unwind":{"path":"$subjects"}},
db.books.aggregate([
{$unwind:"$subjects"},
{$match:{"language":"English","subjects":/^[ABC]/}},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3} ], {explain:true})
{
mergeType:
splitPipeline:
shards:
}
db.books.aggregate([
{$unwind:"$subjects"},
{$match:{"language":"English","subjects":/^[ABC]/}},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3} ], {explain:true})
{
mergeType:
splitPipeline:
shards: {
"shard0000" : {
...
}
}
}
db.books.aggregate([
{$unwind:"$subjects"},
{$match:{"language":"English","subjects":/^[ABC]/}},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3} ], {explain:true})
{
mergeType:
splitPipeline: null,
shards: {
"shard0000" : {
...
}
}
}
db.books.aggregate([
{$unwind:"$subjects"},
{$match:{"language":"English","subjects":/^[ABC]/}},
{$group:{_id:"$subjects",count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:3} ], {explain:true})
{
splitPipeline: null,
shards: {
"shard0000" : {
...
}
}
}
db.orders.explain().aggregate( [
{$match:{status:"F"}},
{$sort:{totalprice:-1}},
{$limit:40},
{$group:{_id:1,avgprice:{$avg:"$totalprice"}}}])
db.orders.explain().aggregate( [
{$match:{status:"F"}},
{$sort:{totalprice:-1}},
{$limit:40},
{$group:{_id:1,avgprice:{$avg:"$totalprice"}}}])
{"stages" : [
{"$cursor" : { "query" : { "status" : "F"},
"sort" : {"totalprice" : -1},
"limit" : NumberLong(40),
"fields" : { "totalprice" : 1, "_id" : 0},
"queryPlanner" : {
"winningPlan" : {
"stage" : "PROJECTION",
"transformBy" : {"totalprice" : 1, "_id" : 0},
"inputStage" : {
"stage" : "IXSCAN",
"indexName" : "status_1_totalprice_1",
"direction" : "backward",
"indexBounds" : {
"status" : [ "["F", "F"]"],
"totalprice" : ["[MaxKey, MinKey]"]
} } } },
} },
{"$group" : {"_id" : 1, "avgprice" : {"$avg" : "$totalprice"} } }
] }
db.orders.explain("executionStats").aggregate( [
{$match:{status:"F"}},
{$sort:{totalprice:-1}},
{$limit:40},
{$group:{_id:1,avgprice:{$avg:"$totalprice"}}}])
{"stages" : [
{"$cursor" : { "query" : { "status" : "F"},
"sort" : {"totalprice" : -1},
"limit" : NumberLong(40),
"fields" : { "totalprice" : 1, "_id" : 0},
"queryPlanner" : {
"winningPlan" : {
"stage" : "PROJECTION",
"transformBy" : {"totalprice" : 1, "_id" : 0},
"inputStage" : {
"stage" : "IXSCAN",
"indexName" : "status_1_totalprice_1",
"direction" : "backward",
"indexBounds" : {
"status" : [ "["F", "F"]"],
"totalprice" : ["[MaxKey, MinKey]"]
} } } },
} },
{"$group" : {"_id" : 1, "avgprice" : {"$avg" : "$totalprice"} } }
] }
db.orders.explain("executionStats").aggregate( [
{$match:{status:"F"}},
{$sort:{totalprice:-1}},
{$limit:40},
{$group:{_id:1,avgprice:{$avg:"$totalprice"}}}])
{"stages" : [
{"$cursor" : { "query" : { "status" : "F"},
"sort" : {"totalprice" : -1},
"limit" : NumberLong(40),
"fields" : { "totalprice" : 1, "_id" : 0},
"queryPlanner" : {
"winningPlan" : {
"stage" : "PROJECTION",
"transformBy" : {"totalprice" : 1, "_id" : 0},
"inputStage" : {
"stage" : "IXSCAN",
"indexName" : "status_1_totalprice_1",
"direction" : "backward",
"indexBounds" : {
"status" : [ "["F", "F"]"],
"totalprice" : ["[MaxKey, MinKey]"]
} } } },
} },
{"$group" : {"_id" : 1, "avgprice" : {"$avg" : "$totalprice"} } }
db.orders.explain("executionStats").aggregate( [
{$match:{status:"F"}},
{$sort:{totalprice:-1}},
{$limit:40},
{$group:{_id:1,avgprice:{$avg:"$totalprice"}}}])
{"stages" : [
{"$cursor" : { "query" : { "status" : "F"},
"sort" : {"totalprice" : -1},
"limit" : NumberLong(40),
"fields" : { "totalprice" : 1, "_id" : 0},
"queryPlanner" : {
"winningPlan" : {
"stage" : "PROJECTION",
"transformBy" : {"totalprice" : 1, "_id" : 0},
"inputStage" : {
"stage" : "IXSCAN",
"indexName" : "status_1_totalprice_1",
"direction" : "backward",
"indexBounds" : {
"status" : [ "["F", "F"]"],
"totalprice" : ["[MaxKey, MinKey]"]
} } } },
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 85,
"executionTimeMillis" : 3,
"totalKeysExamined" : 30295,
"totalDocsExamined" : 0,
"executionStages" : { ... }
} } },
{"$group" : {"_id" : 1, "avgprice" : {"$avg" : "$totalprice"} } }
#MDBlocal
NEW IN 3.6
executionStats option to explain
"hint" for aggregation
db.orders.explain().aggregate( [
{$match:{status:"F"}},
{$sort:{totalprice:-1}},
{$limit:40},
{$group:{_id:1,avgprice:{$avg:"$totalprice"}}}
], {"hint":{"status":1, "totalprice":1}})
#MDBlocal# M D B l o c a l
understand stages
• Best order for performance
• Avoid unnecessary "blocking"
• keep "streaming"
• Maximize use of indexes
• early stages get the index!
• Liberally check explain() output
understand expressions
• Schema manipulation
• Array transformation
• Use in find query filter, ...
use functions
• Readable, debug-able, reusable
POWERFUL AGGREGATIONS
#MDBlocal# M D B l o c a l
Better performance & optimizations
More stages & expressions
More options for output
Compass helper for aggregate
Unify different languages
THE FUTURE OF AGGREGATION
[MongoDB.local Bengaluru 2018] Tutorial: Pipeline Power - Doing More with MongoDB Aggregation

More Related Content

What's hot (20)

PDF
Template Haskell Tutorial
kizzx2
 
PPT
Functional Pe(a)rls version 2
osfameron
 
PPTX
Using R for Building a Simple and Effective Dashboard
Andrea Gigli
 
PPTX
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
takeoutweight
 
PDF
Wx::Perl::Smart
lichtkind
 
PDF
CSS for developers
Anji Beeravalli
 
KEY
Elastic tire demo
Scott Hamilton
 
PPTX
CSS for Developers
Nascenia IT
 
PDF
Functional pe(a)rls: Huey's zipper
osfameron
 
PDF
Functional Pe(a)rls - the Purely Functional Datastructures edition
osfameron
 
KEY
FCIP SASS Talk
Chris Schneider
 
PPTX
Coding Horrors
Mark Baker
 
PDF
The Perl6 Type System
abrummett
 
PPT
Perl training-in-navi mumbai
vibrantuser
 
PDF
CLI, the other SAPI phpnw11
Combell NV
 
PDF
What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27
Ruby Meditation
 
PDF
The Ring programming language version 1.7 book - Part 49 of 196
Mahmoud Samir Fayed
 
PDF
Using a mobile phone as a therapist - Superweek 2018
Peter Meyer
 
PDF
Avro, la puissance du binaire, la souplesse du JSON
Alexandre Victoor
 
Template Haskell Tutorial
kizzx2
 
Functional Pe(a)rls version 2
osfameron
 
Using R for Building a Simple and Effective Dashboard
Andrea Gigli
 
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
takeoutweight
 
Wx::Perl::Smart
lichtkind
 
CSS for developers
Anji Beeravalli
 
Elastic tire demo
Scott Hamilton
 
CSS for Developers
Nascenia IT
 
Functional pe(a)rls: Huey's zipper
osfameron
 
Functional Pe(a)rls - the Purely Functional Datastructures edition
osfameron
 
FCIP SASS Talk
Chris Schneider
 
Coding Horrors
Mark Baker
 
The Perl6 Type System
abrummett
 
Perl training-in-navi mumbai
vibrantuser
 
CLI, the other SAPI phpnw11
Combell NV
 
What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27
Ruby Meditation
 
The Ring programming language version 1.7 book - Part 49 of 196
Mahmoud Samir Fayed
 
Using a mobile phone as a therapist - Superweek 2018
Peter Meyer
 
Avro, la puissance du binaire, la souplesse du JSON
Alexandre Victoor
 

Similar to [MongoDB.local Bengaluru 2018] Tutorial: Pipeline Power - Doing More with MongoDB Aggregation (20)

PPTX
"Powerful Analysis with the Aggregation Pipeline (Tutorial)"
MongoDB
 
PPTX
Powerful Analysis with the Aggregation Pipeline
MongoDB
 
PDF
Doing More with MongoDB Aggregation
MongoDB
 
PDF
MongoDB .local Toronto 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pi...
MongoDB
 
PDF
MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...
MongoDB
 
PDF
MongoDB .local Chicago 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pi...
MongoDB
 
PDF
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
MongoDB
 
PDF
MongoDB World 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pipeline Em...
MongoDB
 
PDF
MongoDB .local Bengaluru 2019: Aggregation Pipeline Power++: How MongoDB 4.2 ...
MongoDB
 
PPTX
Aggregation Framework
MongoDB
 
PPTX
The Aggregation Framework
MongoDB
 
PDF
Webinar: Data Processing and Aggregation Options
MongoDB
 
PDF
Max Neunhöffer – Joins and aggregations in a distributed NoSQL DB - NoSQL mat...
NoSQLmatters
 
PPTX
Introduction to MongoDB for C# developers
Taras Romanyk
 
PDF
MongoDB .local Paris 2020: La puissance du Pipeline d'Agrégation de MongoDB
MongoDB
 
PDF
Barcelona.pm Curs1211 sess01
Javier Arturo Rodríguez
 
PDF
MongoDB Aggregation Framework
Caserta
 
PPTX
MongoDB Aggregations Indexing and Profiling
Manish Kapoor
 
PDF
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Workhorse Computing
 
PDF
Perl6 grammars
Andrew Shitov
 
"Powerful Analysis with the Aggregation Pipeline (Tutorial)"
MongoDB
 
Powerful Analysis with the Aggregation Pipeline
MongoDB
 
Doing More with MongoDB Aggregation
MongoDB
 
MongoDB .local Toronto 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pi...
MongoDB
 
MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...
MongoDB
 
MongoDB .local Chicago 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pi...
MongoDB
 
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
MongoDB
 
MongoDB World 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pipeline Em...
MongoDB
 
MongoDB .local Bengaluru 2019: Aggregation Pipeline Power++: How MongoDB 4.2 ...
MongoDB
 
Aggregation Framework
MongoDB
 
The Aggregation Framework
MongoDB
 
Webinar: Data Processing and Aggregation Options
MongoDB
 
Max Neunhöffer – Joins and aggregations in a distributed NoSQL DB - NoSQL mat...
NoSQLmatters
 
Introduction to MongoDB for C# developers
Taras Romanyk
 
MongoDB .local Paris 2020: La puissance du Pipeline d'Agrégation de MongoDB
MongoDB
 
Barcelona.pm Curs1211 sess01
Javier Arturo Rodríguez
 
MongoDB Aggregation Framework
Caserta
 
MongoDB Aggregations Indexing and Profiling
Manish Kapoor
 
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Workhorse Computing
 
Perl6 grammars
Andrew Shitov
 
Ad

More from MongoDB (20)

PDF
MongoDB SoCal 2020: Migrate Anything* to MongoDB Atlas
MongoDB
 
PDF
MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!
MongoDB
 
PDF
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...
MongoDB
 
PDF
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDB
MongoDB
 
PDF
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...
MongoDB
 
PDF
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
MongoDB
 
PDF
MongoDB SoCal 2020: MongoDB Atlas Jump Start
MongoDB
 
PDF
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]
MongoDB
 
PDF
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2
MongoDB
 
PDF
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...
MongoDB
 
PDF
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!
MongoDB
 
PDF
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your Mindset
MongoDB
 
PDF
MongoDB .local San Francisco 2020: MongoDB Atlas Jumpstart
MongoDB
 
PDF
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
MongoDB
 
PDF
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...
MongoDB
 
PDF
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep Dive
MongoDB
 
PDF
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & Golang
MongoDB
 
PDF
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...
MongoDB
 
PDF
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...
MongoDB
 
PDF
MongoDB .local Paris 2020: Les bonnes pratiques pour sécuriser MongoDB
MongoDB
 
MongoDB SoCal 2020: Migrate Anything* to MongoDB Atlas
MongoDB
 
MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!
MongoDB
 
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...
MongoDB
 
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDB
MongoDB
 
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...
MongoDB
 
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
MongoDB
 
MongoDB SoCal 2020: MongoDB Atlas Jump Start
MongoDB
 
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]
MongoDB
 
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2
MongoDB
 
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...
MongoDB
 
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!
MongoDB
 
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your Mindset
MongoDB
 
MongoDB .local San Francisco 2020: MongoDB Atlas Jumpstart
MongoDB
 
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
MongoDB
 
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...
MongoDB
 
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep Dive
MongoDB
 
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & Golang
MongoDB
 
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...
MongoDB
 
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...
MongoDB
 
MongoDB .local Paris 2020: Les bonnes pratiques pour sécuriser MongoDB
MongoDB
 
Ad

Recently uploaded (20)

PDF
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
PDF
Mastering Financial Management in Direct Selling
Epixel MLM Software
 
PDF
“Voice Interfaces on a Budget: Building Real-time Speech Recognition on Low-c...
Edge AI and Vision Alliance
 
PDF
“Squinting Vision Pipelines: Detecting and Correcting Errors in Vision Models...
Edge AI and Vision Alliance
 
PDF
AI Agents in the Cloud: The Rise of Agentic Cloud Architecture
Lilly Gracia
 
PPTX
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
PDF
Peak of Data & AI Encore AI-Enhanced Workflows for the Real World
Safe Software
 
PPT
Ericsson LTE presentation SEMINAR 2010.ppt
npat3
 
PDF
UPDF - AI PDF Editor & Converter Key Features
DealFuel
 
PDF
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
PDF
“NPU IP Hardware Shaped Through Software and Use-case Analysis,” a Presentati...
Edge AI and Vision Alliance
 
PDF
The 2025 InfraRed Report - Redpoint Ventures
Razin Mustafiz
 
PDF
SIZING YOUR AIR CONDITIONER---A PRACTICAL GUIDE.pdf
Muhammad Rizwan Akram
 
PDF
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
PDF
Go Concurrency Real-World Patterns, Pitfalls, and Playground Battles.pdf
Emily Achieng
 
PDF
Kit-Works Team Study_20250627_한달만에만든사내서비스키링(양다윗).pdf
Wonjun Hwang
 
PPTX
MuleSoft MCP Support (Model Context Protocol) and Use Case Demo
shyamraj55
 
PDF
NLJUG Speaker academy 2025 - first session
Bert Jan Schrijver
 
PPTX
New ThousandEyes Product Innovations: Cisco Live June 2025
ThousandEyes
 
PPTX
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
Mastering Financial Management in Direct Selling
Epixel MLM Software
 
“Voice Interfaces on a Budget: Building Real-time Speech Recognition on Low-c...
Edge AI and Vision Alliance
 
“Squinting Vision Pipelines: Detecting and Correcting Errors in Vision Models...
Edge AI and Vision Alliance
 
AI Agents in the Cloud: The Rise of Agentic Cloud Architecture
Lilly Gracia
 
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
Peak of Data & AI Encore AI-Enhanced Workflows for the Real World
Safe Software
 
Ericsson LTE presentation SEMINAR 2010.ppt
npat3
 
UPDF - AI PDF Editor & Converter Key Features
DealFuel
 
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
“NPU IP Hardware Shaped Through Software and Use-case Analysis,” a Presentati...
Edge AI and Vision Alliance
 
The 2025 InfraRed Report - Redpoint Ventures
Razin Mustafiz
 
SIZING YOUR AIR CONDITIONER---A PRACTICAL GUIDE.pdf
Muhammad Rizwan Akram
 
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
Go Concurrency Real-World Patterns, Pitfalls, and Playground Battles.pdf
Emily Achieng
 
Kit-Works Team Study_20250627_한달만에만든사내서비스키링(양다윗).pdf
Wonjun Hwang
 
MuleSoft MCP Support (Model Context Protocol) and Use Case Demo
shyamraj55
 
NLJUG Speaker academy 2025 - first session
Bert Jan Schrijver
 
New ThousandEyes Product Innovations: Cisco Live June 2025
ThousandEyes
 
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 

[MongoDB.local Bengaluru 2018] Tutorial: Pipeline Power - Doing More with MongoDB Aggregation