SlideShare a Scribd company logo
1 of 192
Download to read offline
Chris Harris
Tips and Tricks++ for Querying MongoDB
Chris Harris
Lead Technical Expert for Queries and Indexing
Introductions
Diego
Introductions
I identified slow queries.
What index do I make?
Roadmap
§ E-S-R
§ Overview
§ Predicate Type Check
§ Sequential Prefix
§ Exceptions?
§ Multikey Index
§ Definition
§ Semantics
§ Performance
Roadmap
§ E-S-R
§ Overview
§ Predicate Type Check
§ Sequential Prefix
§ Exceptions?
§ Multikey Index
§ Definition
§ Semantics
§ Performance
Equality Sort Range "Rule"
E – S - R
The ordering of index keys in a
compound index is critically
important. E-S-R provides
guidance that is useful in most
cases:
• Equality first
• Sort next
• Range last
E – S - R
The ordering of index keys in a
compound index is critically
important. E-S-R provides
guidance that is useful in most
cases:
• Equality first
• Sort next
• Range last
What is the difference between
Equality and Range?
Definitions
Equality Fields
An exact match on a single
value. For example:
• {x:123}
• {x:{$eq:123}}
• {x:"123"}
• {"x.y":123}
Definitions
Equality Fields
An exact match on a single
value. For example:
• {x:123}
• {x:{$eq:123}}
• {x:"123"}
• {"x.y":123}
Sort
The (entire) requested sort.
.sort({x:1, y:-1})
Definitions
Equality Fields
An exact match on a single
value. For example:
• {x:123}
• {x:{$eq:123}}
• {x:"123"}
• {"x.y":123}
Sort
The (entire) requested sort.
.sort({x:1, y:-1})
Range Predicates
Any predicates that are not
exact matches. Some
operators include:
• {x:{$gt:0}}
• {x:{$lte:1000}}
Equality
Equality keys are placed first in any order
If present in the query shape, equality fields should always form the
prefix for the index.
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
Equality
Equality keys are placed first in any order
If present in the query shape, equality fields should always form the
prefix for the index.
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
Equality
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{gamertag: "Ace", score: 100}
{gamertag: "Ace", score: 99,999}
{gamertag: "Bob", score: 15,000}
{gamertag: "Bob", score: 50,000}
Equality
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {}
{}{}
100 15,000 50,000 99,999
Ace Bob Bob Ace
{gamertag: "Ace", score: 100}
{gamertag: "Ace", score: 99,999}
{gamertag: "Bob", score: 15,000}
{gamertag: "Bob", score: 50,000}
Equality
100 15,000 50,000 99,999
Ace Bob Bob Ace
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
100 15,000 50,000 99,999
Ace Bob Bob Ace
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
100 15,000 50,000 99,999
Ace Bob Bob Ace
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
100 15,000 50,000 99,999
Ace Bob Bob Ace
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
100 15,000 50,000 99,999
Ace Bob Bob Ace
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
100 15,000 50,000 99,999
Ace Bob Bob Ace
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
100 15,000 50,000 99,999
Ace Bob Bob Ace
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
100 15,000 50,000 99,999
Ace Bob Bob Ace
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
Ace Bob Bob Ace
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
100 99,999 15,000 50,000
{} {} {} {}
Equality
100
Ace Bob
99,999 15,000 50,000
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
100
Ace Bob
99,999 15,000 50,000
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
100
Ace Bob
99,999 15,000 50,000
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality before Range
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
R
E R
E
Sort
Sort fields are placed next
Placing sort predicates after sequential equality keys allow for the
index to:
• Provide a non-blocking sort.
• Minimize the amount of scanning required.
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
Sort
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
100 15,000 50,000 99,999
Ace Bob Bob Ace
{} {}{} {}
Sort
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
100 15,000 50,000 99,999
Ace Bob Bob Ace
{} {}{} {}
Sort
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
{}
100 15,000 50,000 99,999
Ace Bob Bob Ace
{} {} {}
Sort
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
15,000 50,000 99,999
Ace Bob Bob Ace
{} {}{} {}
100
Sort
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
100 15,000 50,000 99,999
Ace Bob Bob Ace
{} {}{} {}
Sort
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
100 15,000 50,000 99,999
Ace Bob Bob Ace
{} {}{} {}
Sort
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
100 15,000 50,000 99,999
Ace Bob Bob Ace
{} {}{} {}
Sort
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
100 15,000 50,000 99,999
Ace Bob Bob Ace
{} {}{} {}
Sort
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
100 15,000 50,000 99,999
Ace Bob Bob Ace
{} {}{} {}
Sort
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
100 15,000 50,000 99,999
Ace Bob Bob Ace
{} {}{} {}
Sort
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
100 15,000 50,000 99,999
Ace Bob Bob Ace
{} {}{} {}
Sort
Ace Bob Bob Ace
100 99,999 15,000 50,000
{} {} {} {}
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
Sort
100
Ace Bob
{}
99,999 15,000 50,000
{} {}
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
{}
Sort
100
Ace Bob
{}
99,999 15,000 50,000
{} {}
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
{}
Sort
100
Ace Bob
{}
99,999 15,000 50,000
{} {}
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
{}
Sort
100
Ace Bob
{}
99,999 15,000 50,000
{} {}
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
{}
Sort after Equality
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
S
E S
E
Range
Range fields are usually last
Generally range predicates should be placed last.
This allows them to still participate in filtering the data, but does not
force a blocking sort.
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
Range after Equality
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
R
E R
E
Range
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
Should range come after sort
too?
R
E R
E
Range
db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
Should range come after sort
too?
R
E R
E
Range
db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
100 15,000 50,000 99,999
Ace Bob Cali Ace
{} {}{} {}
Range
db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
100 15,000 50,000 99,999
Ace Bob Cali Ace
{} {}{} {}{1}{3}{2}
{1}{3}{2}
Range
db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
100 15,000 50,000 99,999
Ace Bob Cali Ace
{}
{1}{3}{2}
Range
100 15,000 50,000 99,999
Ace Bob Cali Ace
{}
db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
{1}{3}{2}
Range
100 15,000 50,000 99,999
Ace Bob Cali Ace
{}
db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
{1}{3}{2}
Range
100 15,000 50,000 99,999
Ace Bob Cali Ace
{}
db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
{1}{3}{2}
Range
100 15,000 50,000 99,999
Ace Bob Cali Ace
{}
db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
{1}{3}{2}
Range
100 15,000 50,000 99,999
Ace Bob Cali Ace
{}
db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
{1}{3}{2}
Range
100 15,000 50,000 99,999
Ace Bob Cali Ace
{}
db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
{1}{3}{2}
Range
100 15,000 50,000 99,999
Ace Bob Cali Ace
{}
db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
{1}{3}{2}
Range
{}
db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
{1}{3}{2}
Range
db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
Blocking SortBlocking Sort
BS
{1}{3}{2}
Range
db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
BS
Range
100 15,000 50,000 99,999
Ace Bob Cali Ace
db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
Range
Ace Bob Cali Ace
100 15,000 50,00099,999
{1} {3}{2}{}
db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
Range
100 15,000 50,00099,999
Ace Bob Cali
{1} {3}{2}{}
db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
Range
100 15,000 50,00099,999
Ace Bob Cali
{1} {3}{2}{}
db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
Range
100 15,000 50,00099,999
Ace Bob Cali
{1} {3}{2}{}
db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
Range
100 15,000 50,00099,999
Ace Bob Cali
{1} {3}{2}{}
db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
Range
100 15,000 50,00099,999
Ace Bob Cali
{1} {3}{2}{}
db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
Range
100 15,000 50,00099,999
Ace Bob Cali
{1} {3}{2}{}
db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
Range
100 15,000 50,00099,999
Ace Bob Cali
{1} {3}{2}{}
db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
Range after Sort
db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
BS
R S
R
S
Roadmap
§ E-S-R
§ Overview
§ Predicate Type Check
§ Sequential Prefix
§ Exceptions?
§ Multikey Index
§ Definition
§ Semantics
§ Performance
Predicate Type Check
What are the types of the following operators?
Predicate Type Check - Inequality
Inequality operators, such as the
following, are E, S, or R?
§ $ne:123
§ $nin:[1,2]
Range!
Predicate Type Check - Inequality
Inequality operators, such as the
following, are E, S, or R?
§ $ne:123
§ $nin:[1,2]
Range!
How do you know?
Predicate Type Check - Inequality
Inequality operators, such as the
following, are E, S, or R?
§ $ne:123
§ $nin:[1,2]
Range!
"indexBounds" : {
"x" : [
"[MinKey, 123.0)",
"(123.0, MaxKey]"
]
}
Predicate Type Check - Inequality
Range!
"indexBounds" : {
"x" : [
"[MinKey, 123.0)",
"(123.0, MaxKey]"
]
}
50 123 999
Predicate Type Check - Inequality
Range!
"indexBounds" : {
"x" : [
"[MinKey, 123.0)",
"(123.0, MaxKey]"
]
}
50 123 999
Predicate Type Check - Regex
Regex operators, such as the
following, are E, S, or R?
§ {str:/car/}
§ {str:/^car/i}
Range!
Predicate Type Check - Regex
Regex operators, such as the
following, are E, S, or R?
§ {str:/car/}
§ {str:/^car/i}
Range!
Predicate Type Check - Regex
Regex operators, such as the
following, are E, S, or R?
§ {str:/car/}
§ {str:/^car/i}
Range!
planecar racecar
Predicate Type Check - Regex
Regex operators, such as the
following, are E, S, or R?
§ {str:/car/}
§ {str:/^car/i}
Range!
planecar racecar
Predicate Type Check - Regex
Regex operators, such as the
following, are E, S, or R?
§ {str:/car/}
§ {str:/^car/i}
Range!
planecar racecar
Predicate Type Check - Regex
Regex operators, such as the
following, are E, S, or R?
§ {str:/car/}
§ {str:/^car/i}
Range!
Predicate Type Check - Regex
Regex operators, such as the
following, are E, S, or R?
§ {str:/car/}
§ {str:/^car/i}
Range!
raincarry Carpool
Predicate Type Check - Regex
Regex operators, such as the
following, are E, S, or R?
§ {str:/car/}
§ {str:/^car/i}
Range!
raincarry Carpool
Predicate Type Check - Regex
Regex operators, such as the
following, are E, S, or R?
§ {str:/car/}
§ {str:/^car/i}
Range!
raincarry Carpool
Predicate Type Check - $in
$in filters, as demonstrated below,
are E, S, or R?
§ {field:{$in:[1,3]}}
… it depends! Can be Equality or
Range in terms of the key ordering
Predicate Type Check - $in
{field:{$in:[1,3]}}
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
"[3.0, 3.0]"
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
1 2 3
C G B F A D
Predicate Type Check - $in
{field:{$in:[1,3]}}
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
"[3.0, 3.0]"
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
1 2 3
C G B F A D
Predicate Type Check - $in
{field:{$in:[1,3]}}
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
"[3.0, 3.0]"
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
1 2 3
C G B F A D
Predicate Type Check - $in
{field:{$in:[1,3]}}
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
"[3.0, 3.0]"
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
1 2 3
C G B F A D
Predicate Type Check - $in
{field:{$in:[1,3]}}
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
"[3.0, 3.0]"
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
1 2 3
C G B F A D
Predicate Type Check - $in
{field:{$in:[1,3]}}
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
"[3.0, 3.0]"
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
1 2 3
C G B F A D
BS
Predicate Type Check - $in
{field:{$in:[1,3]}}
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
"[3.0, 3.0]"
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
Predicate Type Check - $in
{field:{$in:[1,3]}}
Predicate Type Check - $in
{field:{$in:[1,3]}}
"indexBounds" : {
"field" : [
"[1.0, 1.0]"
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
1 2 3
C G B F A D
{} {} {} {} {} {}
Predicate Type Check - $in
1 2 3
C G B F A D
1 2 3
C G B F A D
{} {} {} {} {} {} {} {} {} {} {} {}
{field:{$in:[1,3]}}
"indexBounds" : {
"field" : [
"[1.0, 1.0]"
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
"indexBounds" : {
"field" : [
"[3.0, 3.0]"
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
Predicate Type Check - $in
{field:{$in:[1,3]}}
"indexBounds" : {
"field" : [
"[1.0, 1.0]"
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
"indexBounds" : {
"field" : [
"[3.0, 3.0]"
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
1 2 3
C G B F A D
1 2 3
C G B F A D
Sort Merge
{} {} {} {} {} {} {} {} {} {} {} {}
Predicate Type Check - $in
BS
Depends on the length of the $in list
S M
Roadmap
§ E-S-R
§ Overview
§ Predicate Type Check
§ Sequential Prefix
§ Exceptions?
§ Multikey Index
§ Definition
§ Semantics
§ Performance
Sequential Equality Keys
Does it matter if there is missing predicate in the equality key list?
For example, given:
§ Query: {gamertag:"Ace", game: "Halo"}
§ Index: {gamertag:1, date:1, game:1}
Is that index as efficient as the following one?
{gamertag:1, game:1, date:1}
Sequential Equality Keys
Answer: It depends! … but probably not
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[MinKey, MaxKey]"
],
"game" : [
"["Halo", "Halo"]"
]
}
Sequential Equality Keys
Ace
Mario Halo
2016 2017
Mario Halo
2018 2019
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[MinKey, MaxKey]"
],
"game" : [
"["Halo", "Halo"]"
]
}
Sequential Equality Keys
Ace
Mario Halo
2016 2017
Mario Halo
2018 2019
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[MinKey, MaxKey]"
],
"game" : [
"["Halo", "Halo"]"
]
}
Sequential Equality Keys
Ace
Mario Halo
2016 2017
Mario Halo
2018 2019
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[MinKey, MaxKey]"
],
"game" : [
"["Halo", "Halo"]"
]
}
Sequential Equality Keys
Ace
Mario Halo
2016 2017
Mario Halo
2018 2019
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[MinKey, MaxKey]"
],
"game" : [
"["Halo", "Halo"]"
]
}
Sequential Equality Keys
Ace
Mario Halo
2016 2017
Mario Halo
2018 2019
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[MinKey, MaxKey]"
],
"game" : [
"["Halo", "Halo"]"
]
}
Sequential Equality Keys
Ace
Mario Halo
2016 2017
Mario Halo
2018 2019
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[MinKey, MaxKey]"
],
"game" : [
"["Halo", "Halo"]"
]
}
Sequential Equality Keys
Ace
Mario Halo
2016 2017
Mario Halo
2018 2019
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[MinKey, MaxKey]"
],
"game" : [
"["Halo", "Halo"]"
]
}
Sequential Equality Keys
Ace
Mario Halo
2016 2017
Mario Halo
2018 2019
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[MinKey, MaxKey]"
],
"game" : [
"["Halo", "Halo"]"
]
}
Sequential Equality Keys
Ace
Mario Halo
2016 2017
Mario Halo
2018 2019
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[MinKey, MaxKey]"
],
"game" : [
"["Halo", "Halo"]"
]
}
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"game" : [
"["Halo", "Halo"]"
]
}
Sequential Equality Keys
Ace
Mario Halo
2016 2017
Mario Halo
2018 2019
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[MinKey, MaxKey]"
],
"game" : [
"["Halo", "Halo"]"
]
}
Halo
Sequential Equality Keys
Ace
Mario Halo
2016 2017
Mario
2018 2019
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[MinKey, MaxKey]"
],
"game" : [
"["Halo", "Halo"]"
]
}
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"game" : [
"["Halo", "Halo"]"
]
}
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"game" : [
"["Halo", "Halo"]"
]
}
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"game" : [
"["Halo", "Halo"]"
]
}
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"game" : [
"["Halo", "Halo"]"
],
"date" : [
"[MinKey, MaxKey]"
]
}
Sequential Equality Keys
Ace
2016 2017Mario2018 2019Halo
Sequential Equality Keys
R
E
E E
E
E
E
Roadmap
§ E-S-R
§ Overview
§ Predicate Type Check
§ Sequential Prefix
§ Exceptions?
§ Multikey Index
§ Definition
§ Semantics
§ Performance
Exceptions
Is this "rule" always optimal?
Not always.
db.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Exceptions
db.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
Exceptions
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
db.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Exceptions
db.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
Exceptions
db.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
Exceptions
db.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
Exceptions
db.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
Exceptions
db.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
Exceptions
db.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
Exceptions
db.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
Exceptions
db.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
Exceptions
db.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
Exceptions
db.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
Exceptions
db.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
"executionStats" : {
"nReturned" : 2,
"executionTimeMillis" : 23,
"totalKeysExamined" : 9001,
"totalDocsExamined" : 2,
Exceptions
db.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
Exceptions
db.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
2001 2000 2015 2019 2019
{score:2} {score:1} {score:5000} {score:9001} {score:9000}
… …
Exceptions
db.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
… …
2000 2001 2015 2019 2019
{score:2} {score:1} {score:5000} {score:9001} {score:9000}
Exceptions
db.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
… …
2000 2001 2015 2019 2019
{score:2} {score:1} {score:5000} {score:9001} {score:9000}
Exceptions
db.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
… …
2000 2001 2015 2019 2019
{score:2} {score:1} {score:5000} {score:9001} {score:9000}
BS
"executionStats" : {
"nReturned" : 2,
"executionTimeMillis" : 0,
"totalKeysExamined" : 2,
"totalDocsExamined" : 2,
Exceptions
db.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
… …
2000 2001 2015 2019 2019
{score:2} {score:1} {score:5000}
"executionStats" : {
"nReturned" : 2,
"executionTimeMillis" : 0,
"totalKeysExamined" : 2,
"totalDocsExamined" : 2,
"executionStages" : {
"stage" : "SORT",
"memUsage" : 154,
"memLimit" : 33554432,
{score:9001}{score:9000}
BS
Exceptions
db.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
……… …
BS
S
R
E
R
E
E-S-R Guidance
A good starting place applicable to most use cases
Place keys in the following order:
• Equality first
• Sort next
• Range last
Remember that equality is an exact match of a single value
E-S-R Guidance
A good starting place applicable to most use cases
Place keys in the following order:
• Equality first
• Sort next
• Range last
Remember that equality is an exact match of a single value
I see isMultiKey:true in
the explain output. What
does that mean?
Roadmap
§ E-S-R
§ Overview
§ Predicate Type Check
§ Sequential Prefix
§ Exceptions?
§ Multikey Index
§ Definition
§ Semantics
§ Performance
Multikey
Index
A special type of index which
supports efficient querying for
array fields
Index Nomenclature
Single Field Index
The index entries reference
a single field in the
document
Can be Multikey
Compound Index
The index entries reference
more than one field in the
document
Can be Multikey
Multikey Index
There is separate entry in
the index for every array in
the document
Single Field Index
Ace Doyen
{ gamertag: "Ace",
games:["Mario", "Halo"] }
{ gamertag: "Doyen",
games:["Fortnite", "GTA", "Minecraft"] }{} {}
Single Field Index - Multikey
{} {}
MarioHaloGTAFortnite
Minecraft
DoyenAce
Compound Index - Multikey
{} {}
MarioHaloGTAFortnite
Minecraft
Compound Index - Multikey
HaloMinecraftGTAFortnite
Mario
AceDoyen
{}{}
We tried to use arrays but get
incorrect results and queries are
slow. What gives?
Roadmap
§ E-S-R
§ Overview
§ Predicate Type Check
§ Sequential Prefix
§ Exceptions?
§ Multikey Index
§ Definition
§ Semantics
§ Performance
Semantics
{ _id: 1, players: [ { name: "Doyen", rank : 1 },
{ name: "Ace", rank : 2 } ] }
{ _id: 2, players: [ { name: "Ace", rank : 1 },
{ name: "Doyen", rank : 2 } ] }
{ _id: 3, players: [ { name: "Doyen", rank : 1 },
{ name: "Cali", rank : 2 } ] }
Semantics
{ _id: 1, players: [ { name: "Doyen", rank : 1 },
{ name: "Ace", rank : 2 } ] }
{ _id: 2, players: [ { name: "Ace", rank : 1 },
{ name: "Doyen", rank : 2 } ] }
{ _id: 3, players: [ { name: "Doyen", rank : 1 },
{ name: "Cali", rank : 2 } ] }
Semantics
{ _id: 1, players: [ { name: "Doyen", rank : 1 },
{ name: "Ace", rank : 2 } ] }
{ _id: 2, players: [ { name: "Ace", rank : 1 },
{ name: "Doyen", rank : 2 } ] }
{ _id: 3, players: [ { name: "Doyen", rank : 1 },
{ name: "Cali", rank : 2 } ] }
Semantics
{ _id: 1, players: [ { name: "Doyen", rank : 1 },
{ name: "Ace", rank : 2 } ] }
{ _id: 2, players: [ { name: "Ace", rank : 1 },
{ name: "Doyen", rank : 2 } ] }
{ _id: 3, players: [ { name: "Doyen", rank : 1 },
{ name: "Cali", rank : 2 } ] }
db.matches.find({ "players.name": "Ace",
"players.rank": 1 })
Semantics
{ _id: 1, players: [ { name: "Doyen", rank : 1 },
{ name: "Ace", rank : 2 } ] }
{ _id: 2, players: [ { name: "Ace", rank : 1 },
{ name: "Doyen", rank : 2 } ] }
{ _id: 3, players: [ { name: "Doyen", rank : 1 },
{ name: "Cali", rank : 2 } ] }
db.matches.find({ "players.name": "Ace",
"players.rank": 1 })
Semantics
{ _id: 1, players: [ { name: "Doyen", rank : 1 },
{ name: "Ace", rank : 2 } ] }
{ _id: 2, players: [ { name: "Ace", rank : 1 },
{ name: "Doyen", rank : 2 } ] }
{ _id: 3, players: [ { name: "Doyen", rank : 1 },
{ name: "Cali", rank : 2 } ] }
db.matches.find({ "players.name": "Ace",
"players.rank": 1 })
Semantics
{ _id: 1, players: [ { name: "Doyen", rank : 1 },
{ name: "Ace", rank : 2 } ] }
{ _id: 2, players: [ { name: "Ace", rank : 1 },
{ name: "Doyen", rank : 2 } ] }
{ _id: 3, players: [ { name: "Doyen", rank : 1 },
{ name: "Cali", rank : 2 } ] }
"You can specify the query such that either a single array element meets these conditions
Semantics
{ _id: 1, players: [ { name: "Doyen", rank : 1 },
{ name: "Ace", rank : 2 } ] }
{ _id: 2, players: [ { name: "Ace", rank : 1 },
{ name: "Doyen", rank : 2 } ] }
{ _id: 3, players: [ { name: "Doyen", rank : 1 },
{ name: "Cali", rank : 2 } ] }
"You can specify the query such that either a single array element meets these conditions or
any combination of array elements meets the conditions."
Semantics
{ _id: 1, players: [ { name: "Doyen", rank : 1 },
{ name: "Ace", rank : 2 } ] }
{ _id: 2, players: [ { name: "Ace", rank : 1 },
{ name: "Doyen", rank : 2 } ] }
{ _id: 3, players: [ { name: "Doyen", rank : 1 },
{ name: "Cali", rank : 2 } ] }
"You can specify the query such that either a single array element meets these conditions or
any combination of array elements meets the conditions."
db.matches.find({ "players.name": "Ace", "players.rank": 1 })
Semantics
{ _id: 1, players: [ { name: "Doyen", rank : 1 },
{ name: "Ace", rank : 2 } ] }
{ _id: 2, players: [ { name: "Ace", rank : 1 },
{ name: "Doyen", rank : 2 } ] }
{ _id: 3, players: [ { name: "Doyen", rank : 1 },
{ name: "Cali", rank : 2 } ] }
"You can specify the query such that either a single array element meets these conditions or
any combination of array elements meets the conditions."
db.matches.find({ "players.name": "Ace", "players.rank": 1 })
Semantics
{ _id: 1, players: [ { name: "Doyen", rank : 1 },
{ name: "Ace", rank : 2 } ] }
{ _id: 2, players: [ { name: "Ace", rank : 1 },
{ name: "Doyen", rank : 2 } ] }
{ _id: 3, players: [ { name: "Doyen", rank : 1 },
{ name: "Cali", rank : 2 } ] }
"You can specify the query such that either a single array element meets these conditions or
any combination of array elements meets the conditions."
db.matches.find({ "players.name": "Ace", "players.rank": 1 })
Semantics
{ _id: 1, players: [ { name: "Doyen", rank : 1 },
{ name: "Ace", rank : 2 } ] }
{ _id: 2, players: [ { name: "Ace", rank : 1 },
{ name: "Doyen", rank : 2 } ] }
{ _id: 3, players: [ { name: "Doyen", rank : 1 },
{ name: "Cali", rank : 2 } ] }
"You can specify the query such that either a single array element meets these conditions or
any combination of array elements meets the conditions."
db.matches.find({ "players.name": "Ace", "players.rank": 1 })
Semantics
{ _id: 1, players: [ { name: "Doyen", rank : 1 },
{ name: "Ace", rank : 2 } ] }
{ _id: 2, players: [ { name: "Ace", rank : 1 },
{ name: "Doyen", rank : 2 } ] }
{ _id: 3, players: [ { name: "Doyen", rank : 1 },
{ name: "Cali", rank : 2 } ] }
"You can specify the query such that either a single array element meets these conditions or
any combination of array elements meets the conditions."
db.matches.find({ "players.name": "Ace", "players.rank": 1 })
Semantics
{ _id: 1, players: [ { name: "Doyen", rank : 1 },
{ name: "Ace", rank : 2 } ] }
{ _id: 2, players: [ { name: "Ace", rank : 1 },
{ name: "Doyen", rank : 2 } ] }
{ _id: 3, players: [ { name: "Doyen", rank : 1 },
{ name: "Cali", rank : 2 } ] }
"You can specify the query such that either a single array element meets these conditions or
any combination of array elements meets the conditions."
db.matches.find({ "players.name": "Ace", "players.rank": 1 })
Semantics
{ _id: 1, players: [ { name: "Doyen", rank : 1 },
{ name: "Ace", rank : 2 } ] }
{ _id: 2, players: [ { name: "Ace", rank : 1 },
{ name: "Doyen", rank : 2 } ] }
{ _id: 3, players: [ { name: "Doyen", rank : 1 },
{ name: "Cali", rank : 2 } ] }
"You can specify the query such that either a single array element meets these conditions or
any combination of array elements meets the conditions."
db.matches.find({ "players.name": "Ace", "players.rank": 1 })
Semantics
{ _id: 1, players: [ { name: "Doyen", rank : 1 },
{ name: "Ace", rank : 2 } ] }
{ _id: 2, players: [ { name: "Ace", rank : 1 },
{ name: "Doyen", rank : 2 } ] }
{ _id: 3, players: [ { name: "Doyen", rank : 1 },
{ name: "Cali", rank : 2 } ] }
"You can specify the query such that either a single array element meets these conditions or
any combination of array elements meets the conditions."
db.matches.find({ "players.name": "Ace", "players.rank": 1 })
Semantics
{ _id: 1, players: [ { name: "Doyen", rank : 1 },
{ name: "Ace", rank : 2 } ] }
{ _id: 2, players: [ { name: "Ace", rank : 1 },
{ name: "Doyen", rank : 2 } ] }
{ _id: 3, players: [ { name: "Doyen", rank : 1 },
{ name: "Cali", rank : 2 } ] }
"You can specify the query such that either a single array element meets these conditions or
any combination of array elements meets the conditions."
db.matches.find({ "players.name": "Ace", "players.rank": 1 })
Semantics
{ _id: 1, players: [ { name: "Doyen", rank : 1 },
{ name: "Ace", rank : 2 } ] }
{ _id: 2, players: [ { name: "Ace", rank : 1 },
{ name: "Doyen", rank : 2 } ] }
{ _id: 3, players: [ { name: "Doyen", rank : 1 },
{ name: "Cali", rank : 2 } ] }
"You can specify the query such that either a single array element meets these conditions or
any combination of array elements meets the conditions."
db.matches.find({ "players.name": "Ace", "players.rank": 1 })
Semantics
{ _id: 1, players: [ { name: "Doyen", rank : 1 },
{ name: "Ace", rank : 2 } ] }
{ _id: 2, players: [ { name: "Ace", rank : 1 },
{ name: "Doyen", rank : 2 } ] }
{ _id: 3, players: [ { name: "Doyen", rank : 1 },
{ name: "Cali", rank : 2 } ] }
"You can specify the query such that either a single array element meets these conditions or
any combination of array elements meets the conditions."
db.matches.find({ "players.name": "Ace", "players.rank": 1 })
Semantics - $elemMatch
{ _id: 1, players: [ { name: "Doyen", rank : 1 },
{ name: "Ace", rank : 2 } ] }
{ _id: 2, players: [ { name: "Ace", rank : 1 },
{ name: "Doyen", rank : 2 } ] }
db.matches.find({ "players.name": "Ace", "players.rank": 1 })
Semantics - $elemMatch
{ _id: 1, players: [ { name: "Doyen", rank : 1 },
{ name: "Ace", rank : 2 } ] }
{ _id: 2, players: [ { name: "Ace", rank : 1 },
{ name: "Doyen", rank : 2 } ] }
db.matches.find({ "players.name": "Ace", "players.rank": 1 })
db.matches.find({ "players":
{ $elemMatch: { name: "Ace", "rank": 1} }
})
Semantics - $elemMatch
Use $elemMatch to query multiple fields of a single array element
Not necessary when querying on a single predicate
Semantics - $elemMatch
Use $elemMatch to query multiple fields of a single array element
Not necessary when querying on a single predicate
Okay, that change got us
correct results. But what
about the performance?
Roadmap
§ E-S-R
§ Overview
§ Predicate Type Check
§ Sequential Prefix
§ Exceptions?
§ Multikey Index
§ Definition
§ Semantics
§ Performance
Multikey Path Tracking
{
"_id" : 1,
"game" : "Halo",
"players" : [
"Ace",
"Doyen",
"Cali",
"Bob"
],
"date" : ISODate("2019-02-15T00:00:00Z")
}
Multikey Path Tracking
{
"_id" : 1,
"game" : "Halo",
"players" : [
"Ace",
"Doyen",
"Cali",
"Bob"
],
"date" : ISODate("2019-02-15T00:00:00Z")
}
db.matches.find({
players:"Ace",
date:{
$gte:ISODate("2019-02-01"), $lte:ISODate("2019-02-28")
}
})
Multikey Path Tracking
{
"_id" : 1,
"game" : "Halo",
"players" : [
"Ace",
"Doyen",
"Cali",
"Bob"
],
"date" : ISODate("2019-02-15T00:00:00Z")
}
db.matches.find({
players:"Ace",
date:{
$gte:ISODate("2019-02-01"), $lte:ISODate("2019-02-28")
}
})
.explain()
…
"indexBounds" : {
"players" : [
"["Ace", "Ace"]"
],
"date" : [
"(true, new Date(1551312000000)]"
]
}
Multikey Path Tracking
{
"_id" : 1,
"game" : "Halo",
"players" : [
"Ace",
"Doyen",
"Cali",
"Bob"
],
"date" : ISODate("2019-02-15T00:00:00Z")
}
db.matches.find({
players:"Ace",
date:{
$gte:ISODate("2019-02-01"), $lte:ISODate("2019-02-28")
}
})
.explain()
…
"indexBounds" : {
"players" : [
"["Ace", "Ace"]"
],
"date" : [
"(true, new Date(1551312000000)]"
]
}
Multikey Path Tracking
{
"_id" : 1,
"game" : "Halo",
"players" : [
"Ace",
"Doyen",
"Cali",
"Bob"
],
"date" : ISODate("2019-02-15T00:00:00Z")
}
db.matches.find({
players:"Ace",
date:{
$gte:ISODate("2019-02-01"), $lte:ISODate("2019-02-28")
}
})
.explain()
…
"indexBounds" : {
"players" : [
"["Ace", "Ace"]"
],
"date" : [
"(true, new Date(1551312000000)]"
]
}
Multikey Path Tracking
{
"_id" : 1,
"game" : "Halo",
"players" : [
"Ace",
"Doyen",
"Cali",
"Bob"
],
"date" : ISODate("2019-02-15T00:00:00Z")
}
db.matches.find({
players:"Ace",
date:{
$gte:ISODate("2019-02-01"), $lte:ISODate("2019-02-28")
}
})
.explain()
…
"indexBounds" : {
"players" : [
"["Ace", "Ace"]"
],
"date" : [
"(true, new Date(1551312000000)]"
]
}
Multikey Path Tracking
Before MongoDB 3.4:
§ Database only contained coarse isMultiKey flag for index
§ Did not know which field was the array
§ Conservative behavior to ensure correct results
Multikey Path Tracking
Before MongoDB 3.4:
"stage" : "IXSCAN",
"indexName" : "players_1_date_1",
"isMultiKey" : true,
"indexBounds" : {
"players" : [
"["Ace", "Ace"]"
],
"date" : [
"(true, new Date(1551312000000)]"
]
}
3.4+:
...
"multiKeyPaths" : {
"players" : [ "players" ],
"date" : [ ]
},
"indexBounds" : {
"players" : [
"["Ace", "Ace"]"
],
"date" : [
"[new Date(1548979200000),
new Date(1551312000000)]"
]
}
Multikey Path Tracking
Take advantage of the improvement
§ Index needs to be rebuilt when running 3.4 binaries
§ Just running on 3.4 is not sufficient
§ Look for multiKeyPaths field in explain output
§ v:2 index would be a deterministic check
§ Multikey index cannot cover queries on the array field
Multikey Path Tracking
Take advantage of the improvement
§ Index needs to be rebuilt when running 3.4 binaries
§ Just running on 3.4 is not sufficient
§ Look for multiKeyPaths field in explain output
§ v:2 index would be a deterministic check
§ Multikey index cannot cover queries on the array field
Wow! Everything is running at
Web Scale now!
Summary
§ E-S-R
§ Overview
§ Predicate Type Check
§ Sequential Prefix
§ Exceptions?
§ Multikey Index
§ Definition
§ Semantics
§ Performance
Q&A about Q&I
Additional Resources
Key Ordering Resources
Blog Post
My colleague Jesse wrote an article
which explores the performance
characteristics of different
arrangements.
MongoDB University
My colleague Kirby covers many
indexing topics in greater detail,
including key ordering, in M201:
MongoDB Performance.
Please provide Session Feedback
1. Go to slido.com
2. Enter event code #MDBW19
3. Click on Room Name and Provide Session
Feedback
Feedback poll will remain open for 10 minutes after the talk
ends
Questions?
Meet me now in the Leaf Lounge on the second floor of the
Partner Pavilion
YOU ARE IN MURRAY HILL
MongoDB World 2019: Tips and Tricks++ for Querying and Indexing MongoDB

More Related Content

What's hot

What's hot (20)

Indexing with MongoDB
Indexing with MongoDBIndexing with MongoDB
Indexing with MongoDB
 
Unsafe JAX-RS: Breaking REST API
Unsafe JAX-RS: Breaking REST APIUnsafe JAX-RS: Breaking REST API
Unsafe JAX-RS: Breaking REST API
 
MongoDB Aggregation Performance
MongoDB Aggregation PerformanceMongoDB Aggregation Performance
MongoDB Aggregation Performance
 
Building a Complex, Real-Time Data Management Application
Building a Complex, Real-Time Data Management ApplicationBuilding a Complex, Real-Time Data Management Application
Building a Complex, Real-Time Data Management Application
 
MongoDB Aggregation Framework
MongoDB Aggregation FrameworkMongoDB Aggregation Framework
MongoDB Aggregation Framework
 
ORM2Pwn: Exploiting injections in Hibernate ORM
ORM2Pwn: Exploiting injections in Hibernate ORMORM2Pwn: Exploiting injections in Hibernate ORM
ORM2Pwn: Exploiting injections in Hibernate ORM
 
Mongo DB 성능최적화 전략
Mongo DB 성능최적화 전략Mongo DB 성능최적화 전략
Mongo DB 성능최적화 전략
 
What is new in PostgreSQL 14?
What is new in PostgreSQL 14?What is new in PostgreSQL 14?
What is new in PostgreSQL 14?
 
An Enterprise Architect's View of MongoDB
An Enterprise Architect's View of MongoDBAn Enterprise Architect's View of MongoDB
An Enterprise Architect's View of MongoDB
 
MongoDB at Scale
MongoDB at ScaleMongoDB at Scale
MongoDB at Scale
 
MongoDB - Aggregation Pipeline
MongoDB - Aggregation PipelineMongoDB - Aggregation Pipeline
MongoDB - Aggregation Pipeline
 
Inside MongoDB: the Internals of an Open-Source Database
Inside MongoDB: the Internals of an Open-Source DatabaseInside MongoDB: the Internals of an Open-Source Database
Inside MongoDB: the Internals of an Open-Source Database
 
Creating Continuously Up to Date Materialized Aggregates
Creating Continuously Up to Date Materialized AggregatesCreating Continuously Up to Date Materialized Aggregates
Creating Continuously Up to Date Materialized Aggregates
 
Introduction to redis
Introduction to redisIntroduction to redis
Introduction to redis
 
MySQL Index Cookbook
MySQL Index CookbookMySQL Index Cookbook
MySQL Index Cookbook
 
New methods for exploiting ORM injections in Java applications
New methods for exploiting ORM injections in Java applicationsNew methods for exploiting ORM injections in Java applications
New methods for exploiting ORM injections in Java applications
 
Using Optimizer Hints to Improve MySQL Query Performance
Using Optimizer Hints to Improve MySQL Query PerformanceUsing Optimizer Hints to Improve MySQL Query Performance
Using Optimizer Hints to Improve MySQL Query Performance
 
MongoDB and Indexes - MUG Denver - 20160329
MongoDB and Indexes - MUG Denver - 20160329MongoDB and Indexes - MUG Denver - 20160329
MongoDB and Indexes - MUG Denver - 20160329
 
A Technical Introduction to WiredTiger
A Technical Introduction to WiredTigerA Technical Introduction to WiredTiger
A Technical Introduction to WiredTiger
 
Neat tricks to bypass CSRF-protection
Neat tricks to bypass CSRF-protectionNeat tricks to bypass CSRF-protection
Neat tricks to bypass CSRF-protection
 

Similar to MongoDB World 2019: Tips and Tricks++ for Querying and Indexing MongoDB

Tips and Tricks for Avoiding Common Query Pitfalls
Tips and Tricks for Avoiding Common Query PitfallsTips and Tricks for Avoiding Common Query Pitfalls
Tips and Tricks for Avoiding Common Query Pitfalls
MongoDB
 
ACI-Webinar-3-MinMaxAlphaBetaPruning-TicTacToe.pptx
ACI-Webinar-3-MinMaxAlphaBetaPruning-TicTacToe.pptxACI-Webinar-3-MinMaxAlphaBetaPruning-TicTacToe.pptx
ACI-Webinar-3-MinMaxAlphaBetaPruning-TicTacToe.pptx
ssuser1eba67
 

Similar to MongoDB World 2019: Tips and Tricks++ for Querying and Indexing MongoDB (17)

MongoDB .local Houston 2019:Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local Houston 2019:Tips and Tricks++ for Querying and Indexing MongoDBMongoDB .local Houston 2019:Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local Houston 2019:Tips and Tricks++ for Querying and Indexing MongoDB
 
MongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDBMongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDB
 
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
 
MongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDBMongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDB
 
MongoDB .local Bengaluru 2019: Tips and Tricks++ for Querying and Indexing Mo...
MongoDB .local Bengaluru 2019: Tips and Tricks++ for Querying and Indexing Mo...MongoDB .local Bengaluru 2019: Tips and Tricks++ for Querying and Indexing Mo...
MongoDB .local Bengaluru 2019: Tips and Tricks++ for Querying and Indexing Mo...
 
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDBMongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDB
 
Avoid Query Pitfalls
Avoid Query PitfallsAvoid Query Pitfalls
Avoid Query Pitfalls
 
MongoDB.local Dallas 2019: Tips & Tricks for Avoiding Common Query Pitfalls
MongoDB.local Dallas 2019: Tips & Tricks for Avoiding Common Query PitfallsMongoDB.local Dallas 2019: Tips & Tricks for Avoiding Common Query Pitfalls
MongoDB.local Dallas 2019: Tips & Tricks for Avoiding Common Query Pitfalls
 
MongoDB.local Austin 2018: Tips and Tricks for Avoiding Common Query Pitfalls
MongoDB.local Austin 2018: Tips and Tricks for Avoiding Common Query PitfallsMongoDB.local Austin 2018: Tips and Tricks for Avoiding Common Query Pitfalls
MongoDB.local Austin 2018: Tips and Tricks for Avoiding Common Query Pitfalls
 
Tips and Tricks for Avoiding Common Query Pitfalls
Tips and Tricks for Avoiding Common Query PitfallsTips and Tricks for Avoiding Common Query Pitfalls
Tips and Tricks for Avoiding Common Query Pitfalls
 
Tips and Tricks for Avoiding Common Query Pitfalls
Tips and Tricks for Avoiding Common Query PitfallsTips and Tricks for Avoiding Common Query Pitfalls
Tips and Tricks for Avoiding Common Query Pitfalls
 
MongoDB.local Sydney 2019: Tips and Tricks for Avoiding Common Query Pitfalls
MongoDB.local Sydney 2019: Tips and Tricks for Avoiding Common Query PitfallsMongoDB.local Sydney 2019: Tips and Tricks for Avoiding Common Query Pitfalls
MongoDB.local Sydney 2019: Tips and Tricks for Avoiding Common Query Pitfalls
 
MongoDB World 2018: Tips and Tricks for Avoiding Common Query Pitfalls
MongoDB World 2018: Tips and Tricks for Avoiding Common Query PitfallsMongoDB World 2018: Tips and Tricks for Avoiding Common Query Pitfalls
MongoDB World 2018: Tips and Tricks for Avoiding Common Query Pitfalls
 
MongoDB.local Seattle 2019: Tips & Tricks for Avoiding Common Query Pitfalls
MongoDB.local Seattle 2019: Tips & Tricks for Avoiding Common Query PitfallsMongoDB.local Seattle 2019: Tips & Tricks for Avoiding Common Query Pitfalls
MongoDB.local Seattle 2019: Tips & Tricks for Avoiding Common Query Pitfalls
 
Tips and Tricks for Avoiding Common Query Pitfalls Christian Kurze
Tips and Tricks for Avoiding Common Query Pitfalls Christian KurzeTips and Tricks for Avoiding Common Query Pitfalls Christian Kurze
Tips and Tricks for Avoiding Common Query Pitfalls Christian Kurze
 
ACI-Webinar-3-MinMaxAlphaBetaPruning-TicTacToe.pptx
ACI-Webinar-3-MinMaxAlphaBetaPruning-TicTacToe.pptxACI-Webinar-3-MinMaxAlphaBetaPruning-TicTacToe.pptx
ACI-Webinar-3-MinMaxAlphaBetaPruning-TicTacToe.pptx
 
MongoDB World 2019: How to Keep an Average API Response Time Less than 5ms wi...
MongoDB World 2019: How to Keep an Average API Response Time Less than 5ms wi...MongoDB World 2019: How to Keep an Average API Response Time Less than 5ms wi...
MongoDB World 2019: How to Keep an Average API Response Time Less than 5ms wi...
 

More from MongoDB

More from MongoDB (20)

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

Recently uploaded

EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 

Recently uploaded (20)

What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 

MongoDB World 2019: Tips and Tricks++ for Querying and Indexing MongoDB

  • 1. Chris Harris Tips and Tricks++ for Querying MongoDB
  • 2. Chris Harris Lead Technical Expert for Queries and Indexing
  • 4. Introductions I identified slow queries. What index do I make?
  • 5. Roadmap § E-S-R § Overview § Predicate Type Check § Sequential Prefix § Exceptions? § Multikey Index § Definition § Semantics § Performance
  • 6. Roadmap § E-S-R § Overview § Predicate Type Check § Sequential Prefix § Exceptions? § Multikey Index § Definition § Semantics § Performance
  • 8. E – S - R The ordering of index keys in a compound index is critically important. E-S-R provides guidance that is useful in most cases: • Equality first • Sort next • Range last
  • 9. E – S - R The ordering of index keys in a compound index is critically important. E-S-R provides guidance that is useful in most cases: • Equality first • Sort next • Range last What is the difference between Equality and Range?
  • 10. Definitions Equality Fields An exact match on a single value. For example: • {x:123} • {x:{$eq:123}} • {x:"123"} • {"x.y":123}
  • 11. Definitions Equality Fields An exact match on a single value. For example: • {x:123} • {x:{$eq:123}} • {x:"123"} • {"x.y":123} Sort The (entire) requested sort. .sort({x:1, y:-1})
  • 12. Definitions Equality Fields An exact match on a single value. For example: • {x:123} • {x:{$eq:123}} • {x:"123"} • {"x.y":123} Sort The (entire) requested sort. .sort({x:1, y:-1}) Range Predicates Any predicates that are not exact matches. Some operators include: • {x:{$gt:0}} • {x:{$lte:1000}}
  • 13. Equality Equality keys are placed first in any order If present in the query shape, equality fields should always form the prefix for the index. db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
  • 14. Equality Equality keys are placed first in any order If present in the query shape, equality fields should always form the prefix for the index. db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
  • 15. Equality db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {gamertag: "Ace", score: 100} {gamertag: "Ace", score: 99,999} {gamertag: "Bob", score: 15,000} {gamertag: "Bob", score: 50,000}
  • 16. Equality db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {}{} 100 15,000 50,000 99,999 Ace Bob Bob Ace {gamertag: "Ace", score: 100} {gamertag: "Ace", score: 99,999} {gamertag: "Bob", score: 15,000} {gamertag: "Bob", score: 50,000}
  • 17. Equality 100 15,000 50,000 99,999 Ace Bob Bob Ace db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {}
  • 18. Equality 100 15,000 50,000 99,999 Ace Bob Bob Ace db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {}
  • 19. Equality 100 15,000 50,000 99,999 Ace Bob Bob Ace db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {}
  • 20. Equality 100 15,000 50,000 99,999 Ace Bob Bob Ace db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {}
  • 21. Equality 100 15,000 50,000 99,999 Ace Bob Bob Ace db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {}
  • 22. Equality 100 15,000 50,000 99,999 Ace Bob Bob Ace db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {}
  • 23. Equality 100 15,000 50,000 99,999 Ace Bob Bob Ace db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {}
  • 24. Equality 100 15,000 50,000 99,999 Ace Bob Bob Ace db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {}
  • 25. Equality Ace Bob Bob Ace db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) 100 99,999 15,000 50,000 {} {} {} {}
  • 26. Equality 100 Ace Bob 99,999 15,000 50,000 db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {}
  • 27. Equality 100 Ace Bob 99,999 15,000 50,000 db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {}
  • 28. Equality 100 Ace Bob 99,999 15,000 50,000 db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {}
  • 29. Equality before Range db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) R E R E
  • 30. Sort Sort fields are placed next Placing sort predicates after sequential equality keys allow for the index to: • Provide a non-blocking sort. • Minimize the amount of scanning required. db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
  • 31. Sort db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) 100 15,000 50,000 99,999 Ace Bob Bob Ace {} {}{} {}
  • 32. Sort db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) 100 15,000 50,000 99,999 Ace Bob Bob Ace {} {}{} {}
  • 33. Sort db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) {} 100 15,000 50,000 99,999 Ace Bob Bob Ace {} {} {}
  • 34. Sort db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) 15,000 50,000 99,999 Ace Bob Bob Ace {} {}{} {} 100
  • 35. Sort db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) 100 15,000 50,000 99,999 Ace Bob Bob Ace {} {}{} {}
  • 36. Sort db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) 100 15,000 50,000 99,999 Ace Bob Bob Ace {} {}{} {}
  • 37. Sort db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) 100 15,000 50,000 99,999 Ace Bob Bob Ace {} {}{} {}
  • 38. Sort db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) 100 15,000 50,000 99,999 Ace Bob Bob Ace {} {}{} {}
  • 39. Sort db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) 100 15,000 50,000 99,999 Ace Bob Bob Ace {} {}{} {}
  • 40. Sort db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) 100 15,000 50,000 99,999 Ace Bob Bob Ace {} {}{} {}
  • 41. Sort db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) 100 15,000 50,000 99,999 Ace Bob Bob Ace {} {}{} {}
  • 42. Sort Ace Bob Bob Ace 100 99,999 15,000 50,000 {} {} {} {} db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
  • 43. Sort 100 Ace Bob {} 99,999 15,000 50,000 {} {} db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) {}
  • 44. Sort 100 Ace Bob {} 99,999 15,000 50,000 {} {} db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) {}
  • 45. Sort 100 Ace Bob {} 99,999 15,000 50,000 {} {} db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) {}
  • 46. Sort 100 Ace Bob {} 99,999 15,000 50,000 {} {} db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) {}
  • 47. Sort after Equality db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) S E S E
  • 48. Range Range fields are usually last Generally range predicates should be placed last. This allows them to still participate in filtering the data, but does not force a blocking sort. db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
  • 49. Range after Equality db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) R E R E
  • 50. Range db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) Should range come after sort too? R E R E
  • 51. Range db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1}) Should range come after sort too? R E R E
  • 52. Range db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1}) 100 15,000 50,000 99,999 Ace Bob Cali Ace {} {}{} {}
  • 53. Range db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1}) 100 15,000 50,000 99,999 Ace Bob Cali Ace {} {}{} {}{1}{3}{2}
  • 54. {1}{3}{2} Range db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1}) 100 15,000 50,000 99,999 Ace Bob Cali Ace {}
  • 55. {1}{3}{2} Range 100 15,000 50,000 99,999 Ace Bob Cali Ace {} db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
  • 56. {1}{3}{2} Range 100 15,000 50,000 99,999 Ace Bob Cali Ace {} db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
  • 57. {1}{3}{2} Range 100 15,000 50,000 99,999 Ace Bob Cali Ace {} db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
  • 58. {1}{3}{2} Range 100 15,000 50,000 99,999 Ace Bob Cali Ace {} db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
  • 59. {1}{3}{2} Range 100 15,000 50,000 99,999 Ace Bob Cali Ace {} db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
  • 60. {1}{3}{2} Range 100 15,000 50,000 99,999 Ace Bob Cali Ace {} db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
  • 61. {1}{3}{2} Range 100 15,000 50,000 99,999 Ace Bob Cali Ace {} db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
  • 62. {1}{3}{2} Range {} db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
  • 63. {1}{3}{2} Range db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1}) Blocking SortBlocking Sort BS
  • 64. {1}{3}{2} Range db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1}) BS
  • 65. Range 100 15,000 50,000 99,999 Ace Bob Cali Ace db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
  • 66. Range Ace Bob Cali Ace 100 15,000 50,00099,999 {1} {3}{2}{} db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
  • 67. Range 100 15,000 50,00099,999 Ace Bob Cali {1} {3}{2}{} db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
  • 68. Range 100 15,000 50,00099,999 Ace Bob Cali {1} {3}{2}{} db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
  • 69. Range 100 15,000 50,00099,999 Ace Bob Cali {1} {3}{2}{} db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
  • 70. Range 100 15,000 50,00099,999 Ace Bob Cali {1} {3}{2}{} db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
  • 71. Range 100 15,000 50,00099,999 Ace Bob Cali {1} {3}{2}{} db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
  • 72. Range 100 15,000 50,00099,999 Ace Bob Cali {1} {3}{2}{} db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
  • 73. Range 100 15,000 50,00099,999 Ace Bob Cali {1} {3}{2}{} db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1})
  • 74. Range after Sort db.games.find( {score: {$gt: 9000}} ).sort({gamertag: 1}) BS R S R S
  • 75. Roadmap § E-S-R § Overview § Predicate Type Check § Sequential Prefix § Exceptions? § Multikey Index § Definition § Semantics § Performance
  • 76. Predicate Type Check What are the types of the following operators?
  • 77. Predicate Type Check - Inequality Inequality operators, such as the following, are E, S, or R? § $ne:123 § $nin:[1,2] Range!
  • 78. Predicate Type Check - Inequality Inequality operators, such as the following, are E, S, or R? § $ne:123 § $nin:[1,2] Range! How do you know?
  • 79. Predicate Type Check - Inequality Inequality operators, such as the following, are E, S, or R? § $ne:123 § $nin:[1,2] Range! "indexBounds" : { "x" : [ "[MinKey, 123.0)", "(123.0, MaxKey]" ] }
  • 80. Predicate Type Check - Inequality Range! "indexBounds" : { "x" : [ "[MinKey, 123.0)", "(123.0, MaxKey]" ] } 50 123 999
  • 81. Predicate Type Check - Inequality Range! "indexBounds" : { "x" : [ "[MinKey, 123.0)", "(123.0, MaxKey]" ] } 50 123 999
  • 82. Predicate Type Check - Regex Regex operators, such as the following, are E, S, or R? § {str:/car/} § {str:/^car/i} Range!
  • 83. Predicate Type Check - Regex Regex operators, such as the following, are E, S, or R? § {str:/car/} § {str:/^car/i} Range!
  • 84. Predicate Type Check - Regex Regex operators, such as the following, are E, S, or R? § {str:/car/} § {str:/^car/i} Range! planecar racecar
  • 85. Predicate Type Check - Regex Regex operators, such as the following, are E, S, or R? § {str:/car/} § {str:/^car/i} Range! planecar racecar
  • 86. Predicate Type Check - Regex Regex operators, such as the following, are E, S, or R? § {str:/car/} § {str:/^car/i} Range! planecar racecar
  • 87. Predicate Type Check - Regex Regex operators, such as the following, are E, S, or R? § {str:/car/} § {str:/^car/i} Range!
  • 88. Predicate Type Check - Regex Regex operators, such as the following, are E, S, or R? § {str:/car/} § {str:/^car/i} Range! raincarry Carpool
  • 89. Predicate Type Check - Regex Regex operators, such as the following, are E, S, or R? § {str:/car/} § {str:/^car/i} Range! raincarry Carpool
  • 90. Predicate Type Check - Regex Regex operators, such as the following, are E, S, or R? § {str:/car/} § {str:/^car/i} Range! raincarry Carpool
  • 91. Predicate Type Check - $in $in filters, as demonstrated below, are E, S, or R? § {field:{$in:[1,3]}} … it depends! Can be Equality or Range in terms of the key ordering
  • 92. Predicate Type Check - $in {field:{$in:[1,3]}} "indexBounds" : { "field" : [ "[1.0, 1.0]", "[3.0, 3.0]" ], "sortField" : [ "[MinKey, MaxKey]" ] } 1 2 3 C G B F A D
  • 93. Predicate Type Check - $in {field:{$in:[1,3]}} "indexBounds" : { "field" : [ "[1.0, 1.0]", "[3.0, 3.0]" ], "sortField" : [ "[MinKey, MaxKey]" ] } 1 2 3 C G B F A D
  • 94. Predicate Type Check - $in {field:{$in:[1,3]}} "indexBounds" : { "field" : [ "[1.0, 1.0]", "[3.0, 3.0]" ], "sortField" : [ "[MinKey, MaxKey]" ] } 1 2 3 C G B F A D
  • 95. Predicate Type Check - $in {field:{$in:[1,3]}} "indexBounds" : { "field" : [ "[1.0, 1.0]", "[3.0, 3.0]" ], "sortField" : [ "[MinKey, MaxKey]" ] } 1 2 3 C G B F A D
  • 96. Predicate Type Check - $in {field:{$in:[1,3]}} "indexBounds" : { "field" : [ "[1.0, 1.0]", "[3.0, 3.0]" ], "sortField" : [ "[MinKey, MaxKey]" ] } 1 2 3 C G B F A D
  • 97. Predicate Type Check - $in {field:{$in:[1,3]}} "indexBounds" : { "field" : [ "[1.0, 1.0]", "[3.0, 3.0]" ], "sortField" : [ "[MinKey, MaxKey]" ] } 1 2 3 C G B F A D BS
  • 98. Predicate Type Check - $in {field:{$in:[1,3]}} "indexBounds" : { "field" : [ "[1.0, 1.0]", "[3.0, 3.0]" ], "sortField" : [ "[MinKey, MaxKey]" ] }
  • 99. Predicate Type Check - $in {field:{$in:[1,3]}}
  • 100. Predicate Type Check - $in {field:{$in:[1,3]}} "indexBounds" : { "field" : [ "[1.0, 1.0]" ], "sortField" : [ "[MinKey, MaxKey]" ] } 1 2 3 C G B F A D {} {} {} {} {} {}
  • 101. Predicate Type Check - $in 1 2 3 C G B F A D 1 2 3 C G B F A D {} {} {} {} {} {} {} {} {} {} {} {} {field:{$in:[1,3]}} "indexBounds" : { "field" : [ "[1.0, 1.0]" ], "sortField" : [ "[MinKey, MaxKey]" ] } "indexBounds" : { "field" : [ "[3.0, 3.0]" ], "sortField" : [ "[MinKey, MaxKey]" ] }
  • 102. Predicate Type Check - $in {field:{$in:[1,3]}} "indexBounds" : { "field" : [ "[1.0, 1.0]" ], "sortField" : [ "[MinKey, MaxKey]" ] } "indexBounds" : { "field" : [ "[3.0, 3.0]" ], "sortField" : [ "[MinKey, MaxKey]" ] } 1 2 3 C G B F A D 1 2 3 C G B F A D Sort Merge {} {} {} {} {} {} {} {} {} {} {} {}
  • 103. Predicate Type Check - $in BS Depends on the length of the $in list S M
  • 104. Roadmap § E-S-R § Overview § Predicate Type Check § Sequential Prefix § Exceptions? § Multikey Index § Definition § Semantics § Performance
  • 105. Sequential Equality Keys Does it matter if there is missing predicate in the equality key list? For example, given: § Query: {gamertag:"Ace", game: "Halo"} § Index: {gamertag:1, date:1, game:1} Is that index as efficient as the following one? {gamertag:1, game:1, date:1}
  • 106. Sequential Equality Keys Answer: It depends! … but probably not "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[MinKey, MaxKey]" ], "game" : [ "["Halo", "Halo"]" ] }
  • 107. Sequential Equality Keys Ace Mario Halo 2016 2017 Mario Halo 2018 2019 "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[MinKey, MaxKey]" ], "game" : [ "["Halo", "Halo"]" ] }
  • 108. Sequential Equality Keys Ace Mario Halo 2016 2017 Mario Halo 2018 2019 "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[MinKey, MaxKey]" ], "game" : [ "["Halo", "Halo"]" ] }
  • 109. Sequential Equality Keys Ace Mario Halo 2016 2017 Mario Halo 2018 2019 "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[MinKey, MaxKey]" ], "game" : [ "["Halo", "Halo"]" ] }
  • 110. Sequential Equality Keys Ace Mario Halo 2016 2017 Mario Halo 2018 2019 "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[MinKey, MaxKey]" ], "game" : [ "["Halo", "Halo"]" ] }
  • 111. Sequential Equality Keys Ace Mario Halo 2016 2017 Mario Halo 2018 2019 "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[MinKey, MaxKey]" ], "game" : [ "["Halo", "Halo"]" ] }
  • 112. Sequential Equality Keys Ace Mario Halo 2016 2017 Mario Halo 2018 2019 "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[MinKey, MaxKey]" ], "game" : [ "["Halo", "Halo"]" ] }
  • 113. Sequential Equality Keys Ace Mario Halo 2016 2017 Mario Halo 2018 2019 "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[MinKey, MaxKey]" ], "game" : [ "["Halo", "Halo"]" ] }
  • 114. Sequential Equality Keys Ace Mario Halo 2016 2017 Mario Halo 2018 2019 "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[MinKey, MaxKey]" ], "game" : [ "["Halo", "Halo"]" ] }
  • 115. Sequential Equality Keys Ace Mario Halo 2016 2017 Mario Halo 2018 2019 "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[MinKey, MaxKey]" ], "game" : [ "["Halo", "Halo"]" ] }
  • 116. "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "game" : [ "["Halo", "Halo"]" ] } Sequential Equality Keys Ace Mario Halo 2016 2017 Mario Halo 2018 2019 "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[MinKey, MaxKey]" ], "game" : [ "["Halo", "Halo"]" ] }
  • 117. Halo Sequential Equality Keys Ace Mario Halo 2016 2017 Mario 2018 2019 "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[MinKey, MaxKey]" ], "game" : [ "["Halo", "Halo"]" ] } "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "game" : [ "["Halo", "Halo"]" ] }
  • 118. "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "game" : [ "["Halo", "Halo"]" ] } "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "game" : [ "["Halo", "Halo"]" ] } "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "game" : [ "["Halo", "Halo"]" ], "date" : [ "[MinKey, MaxKey]" ] } Sequential Equality Keys Ace 2016 2017Mario2018 2019Halo
  • 120. Roadmap § E-S-R § Overview § Predicate Type Check § Sequential Prefix § Exceptions? § Multikey Index § Definition § Semantics § Performance
  • 121. Exceptions Is this "rule" always optimal? Not always. db.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1})
  • 123. Exceptions Ace 1 5,000 9,0012 9,000 … … 2001 2000 2015 2019 2019 db.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1})
  • 134. Exceptions db.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace 1 5,000 9,0012 9,000 … … 2001 2000 2015 2019 2019 "executionStats" : { "nReturned" : 2, "executionTimeMillis" : 23, "totalKeysExamined" : 9001, "totalDocsExamined" : 2,
  • 136. Exceptions db.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace 2001 2000 2015 2019 2019 {score:2} {score:1} {score:5000} {score:9001} {score:9000} … …
  • 137. Exceptions db.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace … … 2000 2001 2015 2019 2019 {score:2} {score:1} {score:5000} {score:9001} {score:9000}
  • 138. Exceptions db.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace … … 2000 2001 2015 2019 2019 {score:2} {score:1} {score:5000} {score:9001} {score:9000}
  • 139. Exceptions db.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace … … 2000 2001 2015 2019 2019 {score:2} {score:1} {score:5000} {score:9001} {score:9000} BS "executionStats" : { "nReturned" : 2, "executionTimeMillis" : 0, "totalKeysExamined" : 2, "totalDocsExamined" : 2,
  • 140. Exceptions db.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace … … 2000 2001 2015 2019 2019 {score:2} {score:1} {score:5000} "executionStats" : { "nReturned" : 2, "executionTimeMillis" : 0, "totalKeysExamined" : 2, "totalDocsExamined" : 2, "executionStages" : { "stage" : "SORT", "memUsage" : 154, "memLimit" : 33554432, {score:9001}{score:9000} BS
  • 142. E-S-R Guidance A good starting place applicable to most use cases Place keys in the following order: • Equality first • Sort next • Range last Remember that equality is an exact match of a single value
  • 143. E-S-R Guidance A good starting place applicable to most use cases Place keys in the following order: • Equality first • Sort next • Range last Remember that equality is an exact match of a single value I see isMultiKey:true in the explain output. What does that mean?
  • 144. Roadmap § E-S-R § Overview § Predicate Type Check § Sequential Prefix § Exceptions? § Multikey Index § Definition § Semantics § Performance
  • 145. Multikey Index A special type of index which supports efficient querying for array fields
  • 146. Index Nomenclature Single Field Index The index entries reference a single field in the document Can be Multikey Compound Index The index entries reference more than one field in the document Can be Multikey Multikey Index There is separate entry in the index for every array in the document
  • 147. Single Field Index Ace Doyen { gamertag: "Ace", games:["Mario", "Halo"] } { gamertag: "Doyen", games:["Fortnite", "GTA", "Minecraft"] }{} {}
  • 148. Single Field Index - Multikey {} {} MarioHaloGTAFortnite Minecraft
  • 149. DoyenAce Compound Index - Multikey {} {} MarioHaloGTAFortnite Minecraft
  • 150. Compound Index - Multikey HaloMinecraftGTAFortnite Mario AceDoyen {}{} We tried to use arrays but get incorrect results and queries are slow. What gives?
  • 151. Roadmap § E-S-R § Overview § Predicate Type Check § Sequential Prefix § Exceptions? § Multikey Index § Definition § Semantics § Performance
  • 152. Semantics { _id: 1, players: [ { name: "Doyen", rank : 1 }, { name: "Ace", rank : 2 } ] } { _id: 2, players: [ { name: "Ace", rank : 1 }, { name: "Doyen", rank : 2 } ] } { _id: 3, players: [ { name: "Doyen", rank : 1 }, { name: "Cali", rank : 2 } ] }
  • 153. Semantics { _id: 1, players: [ { name: "Doyen", rank : 1 }, { name: "Ace", rank : 2 } ] } { _id: 2, players: [ { name: "Ace", rank : 1 }, { name: "Doyen", rank : 2 } ] } { _id: 3, players: [ { name: "Doyen", rank : 1 }, { name: "Cali", rank : 2 } ] }
  • 154. Semantics { _id: 1, players: [ { name: "Doyen", rank : 1 }, { name: "Ace", rank : 2 } ] } { _id: 2, players: [ { name: "Ace", rank : 1 }, { name: "Doyen", rank : 2 } ] } { _id: 3, players: [ { name: "Doyen", rank : 1 }, { name: "Cali", rank : 2 } ] }
  • 155. Semantics { _id: 1, players: [ { name: "Doyen", rank : 1 }, { name: "Ace", rank : 2 } ] } { _id: 2, players: [ { name: "Ace", rank : 1 }, { name: "Doyen", rank : 2 } ] } { _id: 3, players: [ { name: "Doyen", rank : 1 }, { name: "Cali", rank : 2 } ] } db.matches.find({ "players.name": "Ace", "players.rank": 1 })
  • 156. Semantics { _id: 1, players: [ { name: "Doyen", rank : 1 }, { name: "Ace", rank : 2 } ] } { _id: 2, players: [ { name: "Ace", rank : 1 }, { name: "Doyen", rank : 2 } ] } { _id: 3, players: [ { name: "Doyen", rank : 1 }, { name: "Cali", rank : 2 } ] } db.matches.find({ "players.name": "Ace", "players.rank": 1 })
  • 157. Semantics { _id: 1, players: [ { name: "Doyen", rank : 1 }, { name: "Ace", rank : 2 } ] } { _id: 2, players: [ { name: "Ace", rank : 1 }, { name: "Doyen", rank : 2 } ] } { _id: 3, players: [ { name: "Doyen", rank : 1 }, { name: "Cali", rank : 2 } ] } db.matches.find({ "players.name": "Ace", "players.rank": 1 })
  • 158. Semantics { _id: 1, players: [ { name: "Doyen", rank : 1 }, { name: "Ace", rank : 2 } ] } { _id: 2, players: [ { name: "Ace", rank : 1 }, { name: "Doyen", rank : 2 } ] } { _id: 3, players: [ { name: "Doyen", rank : 1 }, { name: "Cali", rank : 2 } ] } "You can specify the query such that either a single array element meets these conditions
  • 159. Semantics { _id: 1, players: [ { name: "Doyen", rank : 1 }, { name: "Ace", rank : 2 } ] } { _id: 2, players: [ { name: "Ace", rank : 1 }, { name: "Doyen", rank : 2 } ] } { _id: 3, players: [ { name: "Doyen", rank : 1 }, { name: "Cali", rank : 2 } ] } "You can specify the query such that either a single array element meets these conditions or any combination of array elements meets the conditions."
  • 160. Semantics { _id: 1, players: [ { name: "Doyen", rank : 1 }, { name: "Ace", rank : 2 } ] } { _id: 2, players: [ { name: "Ace", rank : 1 }, { name: "Doyen", rank : 2 } ] } { _id: 3, players: [ { name: "Doyen", rank : 1 }, { name: "Cali", rank : 2 } ] } "You can specify the query such that either a single array element meets these conditions or any combination of array elements meets the conditions." db.matches.find({ "players.name": "Ace", "players.rank": 1 })
  • 161. Semantics { _id: 1, players: [ { name: "Doyen", rank : 1 }, { name: "Ace", rank : 2 } ] } { _id: 2, players: [ { name: "Ace", rank : 1 }, { name: "Doyen", rank : 2 } ] } { _id: 3, players: [ { name: "Doyen", rank : 1 }, { name: "Cali", rank : 2 } ] } "You can specify the query such that either a single array element meets these conditions or any combination of array elements meets the conditions." db.matches.find({ "players.name": "Ace", "players.rank": 1 })
  • 162. Semantics { _id: 1, players: [ { name: "Doyen", rank : 1 }, { name: "Ace", rank : 2 } ] } { _id: 2, players: [ { name: "Ace", rank : 1 }, { name: "Doyen", rank : 2 } ] } { _id: 3, players: [ { name: "Doyen", rank : 1 }, { name: "Cali", rank : 2 } ] } "You can specify the query such that either a single array element meets these conditions or any combination of array elements meets the conditions." db.matches.find({ "players.name": "Ace", "players.rank": 1 })
  • 163. Semantics { _id: 1, players: [ { name: "Doyen", rank : 1 }, { name: "Ace", rank : 2 } ] } { _id: 2, players: [ { name: "Ace", rank : 1 }, { name: "Doyen", rank : 2 } ] } { _id: 3, players: [ { name: "Doyen", rank : 1 }, { name: "Cali", rank : 2 } ] } "You can specify the query such that either a single array element meets these conditions or any combination of array elements meets the conditions." db.matches.find({ "players.name": "Ace", "players.rank": 1 })
  • 164. Semantics { _id: 1, players: [ { name: "Doyen", rank : 1 }, { name: "Ace", rank : 2 } ] } { _id: 2, players: [ { name: "Ace", rank : 1 }, { name: "Doyen", rank : 2 } ] } { _id: 3, players: [ { name: "Doyen", rank : 1 }, { name: "Cali", rank : 2 } ] } "You can specify the query such that either a single array element meets these conditions or any combination of array elements meets the conditions." db.matches.find({ "players.name": "Ace", "players.rank": 1 })
  • 165. Semantics { _id: 1, players: [ { name: "Doyen", rank : 1 }, { name: "Ace", rank : 2 } ] } { _id: 2, players: [ { name: "Ace", rank : 1 }, { name: "Doyen", rank : 2 } ] } { _id: 3, players: [ { name: "Doyen", rank : 1 }, { name: "Cali", rank : 2 } ] } "You can specify the query such that either a single array element meets these conditions or any combination of array elements meets the conditions." db.matches.find({ "players.name": "Ace", "players.rank": 1 })
  • 166. Semantics { _id: 1, players: [ { name: "Doyen", rank : 1 }, { name: "Ace", rank : 2 } ] } { _id: 2, players: [ { name: "Ace", rank : 1 }, { name: "Doyen", rank : 2 } ] } { _id: 3, players: [ { name: "Doyen", rank : 1 }, { name: "Cali", rank : 2 } ] } "You can specify the query such that either a single array element meets these conditions or any combination of array elements meets the conditions." db.matches.find({ "players.name": "Ace", "players.rank": 1 })
  • 167. Semantics { _id: 1, players: [ { name: "Doyen", rank : 1 }, { name: "Ace", rank : 2 } ] } { _id: 2, players: [ { name: "Ace", rank : 1 }, { name: "Doyen", rank : 2 } ] } { _id: 3, players: [ { name: "Doyen", rank : 1 }, { name: "Cali", rank : 2 } ] } "You can specify the query such that either a single array element meets these conditions or any combination of array elements meets the conditions." db.matches.find({ "players.name": "Ace", "players.rank": 1 })
  • 168. Semantics { _id: 1, players: [ { name: "Doyen", rank : 1 }, { name: "Ace", rank : 2 } ] } { _id: 2, players: [ { name: "Ace", rank : 1 }, { name: "Doyen", rank : 2 } ] } { _id: 3, players: [ { name: "Doyen", rank : 1 }, { name: "Cali", rank : 2 } ] } "You can specify the query such that either a single array element meets these conditions or any combination of array elements meets the conditions." db.matches.find({ "players.name": "Ace", "players.rank": 1 })
  • 169. Semantics { _id: 1, players: [ { name: "Doyen", rank : 1 }, { name: "Ace", rank : 2 } ] } { _id: 2, players: [ { name: "Ace", rank : 1 }, { name: "Doyen", rank : 2 } ] } { _id: 3, players: [ { name: "Doyen", rank : 1 }, { name: "Cali", rank : 2 } ] } "You can specify the query such that either a single array element meets these conditions or any combination of array elements meets the conditions." db.matches.find({ "players.name": "Ace", "players.rank": 1 })
  • 170. Semantics { _id: 1, players: [ { name: "Doyen", rank : 1 }, { name: "Ace", rank : 2 } ] } { _id: 2, players: [ { name: "Ace", rank : 1 }, { name: "Doyen", rank : 2 } ] } { _id: 3, players: [ { name: "Doyen", rank : 1 }, { name: "Cali", rank : 2 } ] } "You can specify the query such that either a single array element meets these conditions or any combination of array elements meets the conditions." db.matches.find({ "players.name": "Ace", "players.rank": 1 })
  • 171. Semantics - $elemMatch { _id: 1, players: [ { name: "Doyen", rank : 1 }, { name: "Ace", rank : 2 } ] } { _id: 2, players: [ { name: "Ace", rank : 1 }, { name: "Doyen", rank : 2 } ] } db.matches.find({ "players.name": "Ace", "players.rank": 1 })
  • 172. Semantics - $elemMatch { _id: 1, players: [ { name: "Doyen", rank : 1 }, { name: "Ace", rank : 2 } ] } { _id: 2, players: [ { name: "Ace", rank : 1 }, { name: "Doyen", rank : 2 } ] } db.matches.find({ "players.name": "Ace", "players.rank": 1 }) db.matches.find({ "players": { $elemMatch: { name: "Ace", "rank": 1} } })
  • 173. Semantics - $elemMatch Use $elemMatch to query multiple fields of a single array element Not necessary when querying on a single predicate
  • 174. Semantics - $elemMatch Use $elemMatch to query multiple fields of a single array element Not necessary when querying on a single predicate Okay, that change got us correct results. But what about the performance?
  • 175. Roadmap § E-S-R § Overview § Predicate Type Check § Sequential Prefix § Exceptions? § Multikey Index § Definition § Semantics § Performance
  • 176. Multikey Path Tracking { "_id" : 1, "game" : "Halo", "players" : [ "Ace", "Doyen", "Cali", "Bob" ], "date" : ISODate("2019-02-15T00:00:00Z") }
  • 177. Multikey Path Tracking { "_id" : 1, "game" : "Halo", "players" : [ "Ace", "Doyen", "Cali", "Bob" ], "date" : ISODate("2019-02-15T00:00:00Z") } db.matches.find({ players:"Ace", date:{ $gte:ISODate("2019-02-01"), $lte:ISODate("2019-02-28") } })
  • 178. Multikey Path Tracking { "_id" : 1, "game" : "Halo", "players" : [ "Ace", "Doyen", "Cali", "Bob" ], "date" : ISODate("2019-02-15T00:00:00Z") } db.matches.find({ players:"Ace", date:{ $gte:ISODate("2019-02-01"), $lte:ISODate("2019-02-28") } }) .explain() … "indexBounds" : { "players" : [ "["Ace", "Ace"]" ], "date" : [ "(true, new Date(1551312000000)]" ] }
  • 179. Multikey Path Tracking { "_id" : 1, "game" : "Halo", "players" : [ "Ace", "Doyen", "Cali", "Bob" ], "date" : ISODate("2019-02-15T00:00:00Z") } db.matches.find({ players:"Ace", date:{ $gte:ISODate("2019-02-01"), $lte:ISODate("2019-02-28") } }) .explain() … "indexBounds" : { "players" : [ "["Ace", "Ace"]" ], "date" : [ "(true, new Date(1551312000000)]" ] }
  • 180. Multikey Path Tracking { "_id" : 1, "game" : "Halo", "players" : [ "Ace", "Doyen", "Cali", "Bob" ], "date" : ISODate("2019-02-15T00:00:00Z") } db.matches.find({ players:"Ace", date:{ $gte:ISODate("2019-02-01"), $lte:ISODate("2019-02-28") } }) .explain() … "indexBounds" : { "players" : [ "["Ace", "Ace"]" ], "date" : [ "(true, new Date(1551312000000)]" ] }
  • 181. Multikey Path Tracking { "_id" : 1, "game" : "Halo", "players" : [ "Ace", "Doyen", "Cali", "Bob" ], "date" : ISODate("2019-02-15T00:00:00Z") } db.matches.find({ players:"Ace", date:{ $gte:ISODate("2019-02-01"), $lte:ISODate("2019-02-28") } }) .explain() … "indexBounds" : { "players" : [ "["Ace", "Ace"]" ], "date" : [ "(true, new Date(1551312000000)]" ] }
  • 182. Multikey Path Tracking Before MongoDB 3.4: § Database only contained coarse isMultiKey flag for index § Did not know which field was the array § Conservative behavior to ensure correct results
  • 183. Multikey Path Tracking Before MongoDB 3.4: "stage" : "IXSCAN", "indexName" : "players_1_date_1", "isMultiKey" : true, "indexBounds" : { "players" : [ "["Ace", "Ace"]" ], "date" : [ "(true, new Date(1551312000000)]" ] } 3.4+: ... "multiKeyPaths" : { "players" : [ "players" ], "date" : [ ] }, "indexBounds" : { "players" : [ "["Ace", "Ace"]" ], "date" : [ "[new Date(1548979200000), new Date(1551312000000)]" ] }
  • 184. Multikey Path Tracking Take advantage of the improvement § Index needs to be rebuilt when running 3.4 binaries § Just running on 3.4 is not sufficient § Look for multiKeyPaths field in explain output § v:2 index would be a deterministic check § Multikey index cannot cover queries on the array field
  • 185. Multikey Path Tracking Take advantage of the improvement § Index needs to be rebuilt when running 3.4 binaries § Just running on 3.4 is not sufficient § Look for multiKeyPaths field in explain output § v:2 index would be a deterministic check § Multikey index cannot cover queries on the array field Wow! Everything is running at Web Scale now!
  • 187. § E-S-R § Overview § Predicate Type Check § Sequential Prefix § Exceptions? § Multikey Index § Definition § Semantics § Performance
  • 190. Key Ordering Resources Blog Post My colleague Jesse wrote an article which explores the performance characteristics of different arrangements. MongoDB University My colleague Kirby covers many indexing topics in greater detail, including key ordering, in M201: MongoDB Performance.
  • 191. Please provide Session Feedback 1. Go to slido.com 2. Enter event code #MDBW19 3. Click on Room Name and Provide Session Feedback Feedback poll will remain open for 10 minutes after the talk ends Questions? Meet me now in the Leaf Lounge on the second floor of the Partner Pavilion YOU ARE IN MURRAY HILL