Slide 1

Slide 1 text

Think You Know MongoDB? PHP User Group Munich

Slide 2

Slide 2 text

Think You Know MongoDB? PHP User Group Munich

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

Getting Started

Slide 5

Slide 5 text

$ brew install mongodb-atlas-cli $ atlas setup

Slide 6

Slide 6 text

Yes, it’s FREE!

Slide 7

Slide 7 text

MongoDB Atlas

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

MongoDB Atlas Free clusters • M0 shared clusters are free • Allows quick testing without stability guarantees • Limitations apply • Don’t run production on it! • Really, don’t!

Slide 10

Slide 10 text

MongoDB Atlas Dedicated Clusters • Support production usage • More storage and automatic scaling • Automatic cluster tier scaling • Supports backups and point-in-time restore • Includes Enterprise features

Slide 11

Slide 11 text

MongoDB Atlas Serverless tier • Minimal con fi guration • Production-ready for variable workloads • Great for startups

Slide 12

Slide 12 text

You can still host MongoDB yourself

Slide 13

Slide 13 text

On-premise deployments You’re in charge • Deploy MongoDB on your own hardware • Decide which cluster con fi guration to run • Manage upgrades and backups yourself • Community Edition is free • Enterprise Edition for advanced features

Slide 14

Slide 14 text

The Database

Slide 15

Slide 15 text

The Database Document model { "name": "alcaeus", "email": [ { "type": "work", "address": "" }, { "type": "private", "address": "" } ], "phone": [ { "type": "mobile", "number": "" }, { "type": "home", "number": "" } ] }

Slide 16

Slide 16 text

The Database Replication

Slide 17

Slide 17 text

The Database Scaling via replication

Slide 18

Slide 18 text

The Database Sharding

Slide 19

Slide 19 text

Global Clusters MongoDB Atlas makes it easy

Slide 20

Slide 20 text

The Driver(s)

Slide 21

Slide 21 text

Drivers Choose your fi ghter

Slide 22

Slide 22 text

Drivers Your connection to MongoDB • Connect your application to a MongoDB deployment • Monitor deployment and route commands • Provide a rich database API

Slide 23

Slide 23 text

Drivers Putting the “No” in NoSQL • Driver API is common across programming languages • Client object to interact with a deployment • Database object to interact with a database • Collection object to interact with a collection • Driver speci fi cation is public

Slide 24

Slide 24 text

PHP Driver Collection API interface Collection { public function insertMany(array $documents, array $options = []); public function insertOne($document, array $options = []); public function find($filter = [], array $options = []); public function findOne($filter = [], array $options = []); public function updateMany($filter, $update, array $options = []); public function updateOne($filter, $update, array $options = []); public function deleteMany($filter, array $options = []); public function deleteOne($filter, array $options = []); }

Slide 25

Slide 25 text

PHP Driver Getting started $client = new MongoDB\Client('mongodb+srv://[...].mongodb.net'); $client->db->coll->insertOne(['name' => 'alcaeus']); $client->db->coll->findOne(['name' => 'alcaeus']);

Slide 26

Slide 26 text

PHP Driver Collection API (2) interface Collection { public function aggregate(array $pipeline, array $options = []); public function findOneAndUpdate($filter, $update, array $options = []); public function findOneAndDelete($filter, array $options = []); public function watch(array $pipeline = [], array $options = []); }

Slide 27

Slide 27 text

The Queries

Slide 28

Slide 28 text

Queries Atomic array operations $collection->updateOne( ['_id' => 1], [ '$currentDate' => ['updated_at' => true], '$pull' => ['vegetables' => 'tomato'], '$push' => ['fruits' => 'tomato'], ] );

Slide 29

Slide 29 text

Queries Atomic update errors $collection->updateOne( ['_id' => 1], [ '$pull' => ['fruits' => 'strawberry'], '$push' => ['fruits' => 'tomato'], ] ); // Exception: Updating the path 'fruits' would create a conflict at 'fruits'

Slide 30

Slide 30 text

Queries Separate updates for multiple fi elds $collection->updateOne( ['_id' => 1], ['$pull' => ['fruits' => 'strawberry']] ); $collection->updateOne( ['_id' => 1], ['$push' => ['fruits' => 'tomato']] );

Slide 31

Slide 31 text

Queries Use transactions use function MongoDB\with_transaction; $session = $client->startSession(); with_transaction($session, function (Session $session) use ($collection) { $collection->updateOne( ['_id' => 1], ['$pull' => ['fruits' => 'strawberry']], ['session' => $session] ); $collection->updateOne( ['_id' => 1], ['$push' => ['fruits' => 'tomato']], ['session' => $session] ); });

Slide 32

Slide 32 text

The Schema

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

Document Model Topic data { "_id": { "$oid": "648ffe160a8daeb5e50506a3" }, "title": "What do you think about MongoDB?", "author_id": { "$oid": "648ffe160a8daeb5e50506a2" }, "num_posts": 1, "created_at": { "$date": { "$numberLong": "1687158294045" } }, "posts": [ { "_id": { "$oid": "648ffe160a8daeb5e50506a4" }, "author_id": { "$oid": "648ffe160a8daeb5e50506a2" }, "body": "I love it, what about you?", "created_at": { "$date": { "$numberLong": "1687158294045" } } } ] }

Slide 35

Slide 35 text

Document Model Identi fi ers { "title": "What do you think about MongoDB?", "author_id": { "$oid": "648ffe160a8daeb5e50506a2" }, "num_posts": 1, "created_at": { "$date": { "$numberLong": "1687158294045" } }, "posts": [ { "_id": { "$oid": "648ffe160a8daeb5e50506a4" }, "author_id": { "$oid": "648ffe160a8daeb5e50506a2" }, "body": "I love it, what about you?", "created_at": { "$date": { "$numberLong": "1687158294045" } } } ] } "_id": { "$oid": "648ffe160a8daeb5e50506a3" },

Slide 36

Slide 36 text

Document Model ObjectIds contain timestamps { "_id": { "$oid": " 0a8daeb5e50506a3" }, "title": "What do you think about MongoDB?", "author_id": { "$oid": "648ffe160a8daeb5e50506a2" }, "num_posts": 1, "created_at": { "$date": { "$numberLong": "1687158294045" } }, "posts": [ { "_id": { "$oid": "648ffe160a8daeb5e50506a4" }, "author_id": { "$oid": "648ffe160a8daeb5e50506a2" }, "body": "I love it, what about you?", "created_at": { "$date": { "$numberLong": "1687158294045" } } } ] } 648ffe16

Slide 37

Slide 37 text

Document Model ObjectIds contain timestamps { "_id": { "$oid": " 0a8daeb5e50506a3" }, "title": "What do you think about MongoDB?", "author_id": { "$oid": "648ffe160a8daeb5e50506a2" }, "num_posts": 1, "created_at": { "$date": { "$numberLong": " 045" } }, "posts": [ { "_id": { "$oid": "648ffe160a8daeb5e50506a4" }, "author_id": { "$oid": "648ffe160a8daeb5e50506a2" }, "body": "I love it, what about you?", "created_at": { "$date": { "$numberLong": "1687158294045" } } } ] } 648ffe16 1687158294

Slide 38

Slide 38 text

Document Model No more created_at { "_id": { "$oid": "648ffe160a8daeb5e50506a3" }, "title": "What do you think about MongoDB?", "author_id": { "$oid": "648ffe160a8daeb5e50506a2" }, "num_posts": 1, "posts": [ { "_id": { "$oid": "648ffe160a8daeb5e50506a4" }, "author_id": { "$oid": "648ffe160a8daeb5e50506a2" }, "body": "I love it, what about you?" } ] }

Slide 39

Slide 39 text

Document Model Embed data { "_id": { "$oid": "648ffe160a8daeb5e50506a3" }, "title": "What do you think about MongoDB?", "author": { "_id": { "$oid": "648ffe160a8daeb5e50506a2" }, "name": "alcaeus", "image": "..." }, "num_posts": 1, "posts": [ { "_id": { "$oid": "648ffe160a8daeb5e50506a4" }, "author": { ... }, "body": "I love it, what about you?" } ] }

Slide 40

Slide 40 text

Document Model Don’t be afraid to duplicate data $collection->updateMany( ['author._id' => $author['_id']], ['$set' => ['author.name' => $author['name']]] ); $collection->updateMany( [], ['$set' => ['posts.$[post].author.name' => $author['name']]], ['arrayFilters' => [['post.author._id' => $author['_id']]]] );

Slide 41

Slide 41 text

Document Model Atomic updates $collection->updateOne( ['_id' => $topic['_id']], [ '$push' => [ 'posts' => [ '_id' => new MongoDB\BSON\ObjectId(), 'author' => $author, 'body' => $body, ], ], '$inc' => ['numPosts' => 1], ] );

Slide 42

Slide 42 text

Document Model It gets BIG { "_id": { "$oid": "648ffe160a8daeb5e50506a3" }, "title": "What do you think about MongoDB?", "author": { "_id": { "$oid": "648ffe160a8daeb5e50506a2" }, "name": "alcaeus", "image": "..." }, "num_posts": 14290, "posts": [ ... ] }

Slide 43

Slide 43 text

Document Limits Just because you can… • Documents have a maximum size of 16 MB • Documents support 255 levels of nesting • Embedding same data multiple times is an anti-pattern • Ever-growing arrays are problematic

Slide 44

Slide 44 text

Document Model Don’t embed everything { "_id": { "$oid": "648ffe160a8daeb5e50506a3" }, "title": "What do you think about MongoDB?", "num_replies": 14289 } "post": { "author": { "_id": { "$oid": "648ffe160a8daeb5e50506a2" }, "name": "alcaeus", "image": "..." }, "body": "I love it, what about you?" },

Slide 45

Slide 45 text

Document Model Embed relevant data { "_id": { "$oid": "648ffe160a8daeb5e50506a3" }, "title": "What do you think about MongoDB?", "post": { ... }, "num_replies": 14289, } "last_reply": { "_id": { "$oid": "648ffe160a8daeb5e50506ce" }, "author": { "_id": { "$oid": "648ffe160a8daeb5e50506a5" }, "name": "youdontknowme", "image": "..." }, "body": "I have a lot to learn about it!" }

Slide 46

Slide 46 text

Document Model The other side: posts { "_id": { "$oid": "648ffe160a8daeb5e50506ce" }, "author": { "_id": { "$oid": "648ffe160a8daeb5e50506a5" }, "name": "youdontknowme", "image": "..." }, "body": "I still have a lot to learn about it!", "topic": { "_id": { "$oid": "648ffe160a8daeb5e50506a3" }, "title": "What do you think about MongoDB?" } }

Slide 47

Slide 47 text

No content

Slide 48

Slide 48 text

Flexible Schema Let’s add polls { "_id": { "$oid": "648ffe160a8daeb5e50506a3" }, "title": "What do you think about MongoDB?", "post": { ... }, "num_replies": 14289, "last_reply": { ... } } "poll": { "question": "Have you used MongoDB?", "options": [ { "title": "Yes" }, { "title": "No" } ] },

Slide 49

Slide 49 text

Schema Updates Add tables and columns CREATE TABLE polls (...); ALTER TABLE topics ADD COLUMN poll_id INTEGER DEFAULT NULL;

Slide 50

Slide 50 text

Schema Update MongoDB makes it easy

Slide 51

Slide 51 text

MongoDB is not schemaless

Slide 52

Slide 52 text

Schema Validation Supports JSON schema { "required": ["_id", "author", "title", "post", "num_replies"], "properties": { "_id": { "bsonType": "objectId" }, "author": { "bsonType": "object", "required": ["_id", "name"], "properties": { "_id": { "bsonType": "objectId" }, "name": { "bsonType": "string" }, "image": { "bsonType": "string" } } }, "title": { "bsonType": "string"}, ... } }

Slide 53

Slide 53 text

Schema Validation Supports JSON schema db.createCollection( "topics", { validator: { $jsonSchema: mySchema }, validationLevel: "moderate", } );

Slide 54

Slide 54 text

Aggregation Pipeline

Slide 55

Slide 55 text

Aggregation Pipeline Raw GPS data { "document": { "_id": { "$oid": "6490311fd97a12c964c25030" }, "time": { "$numberDouble": "1685866107.024" }, "latitude": { "$numberDouble": "44.8859" }, "longitude": { "$numberDouble": "13.873914" }, "altitude": { "$numberDouble": "35.092" }, "speed": { "$numberDouble": "0.663" } } }

Slide 56

Slide 56 text

Aggregation Pipeline Modify data [ { '$addFields': { 'time': { '$toDate': { '$multiply': [ '$time', 1000 ] } }, 'position': { 'type': 'point', 'coordinates': [ '$longitude', '$latitude' ] } } } ]

Slide 57

Slide 57 text

Aggregation Pipeline Complex operations [ { '$setWindowFields': { 'sortBy': { 'time': 1 }, 'output': { 'previousPosition': { '$shift': { 'by': -1, 'default': null, 'output': { 'time': '$time', 'latitude': '$latitude', 'longitude': '$longitude' } } } } }}, { '$addFields': { 'bearing': { '$radiansToDegrees': { '$atan2': [ { '$multiply': [ { '$cos': '$latitude' }, { '$sin': { '$subtract': [ '$longitude', '$previousPosition.longitude' ] } } ]}, { '$subtract': [ { '$multiply': [ { '$cos': '$previousPosition.latitude' }, { '$sin': '$latitude' } ]}, { '$multiply': [ { '$sin': '$previousPosition.latitude' }, { '$cos': '$latitude' }, { '$cos': { '$subtract': ['$longitude', '$previousPosition.longitude'] } } ]} ]} ] } } }} ]

Slide 58

Slide 58 text

Aggregation Pipeline Use for views db.createView( "telemetry", // View name "gpsdata", // Source collection [ { '$addFields': { 'time': { '$toDate': { '$multiply': [ '$time', 1000 ] } }, 'position': { 'type': 'point', 'coordinates': [ '$longitude', '$latitude' ] } } }, // ... more stages ] );

Slide 59

Slide 59 text

Aggregation Pipeline On-demand materialised views { '$merge': { 'into': 'telemetry', 'on': '_id', 'whenMatched': 'replace', 'whenNotMatched': 'insert' } }

Slide 60

Slide 60 text

MongoDB Atlas

Slide 61

Slide 61 text

Charts

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

No content

Slide 64

Slide 64 text

MongoDB Atlas Data Federation • Query and move data from various sources • Atlas Clusters • Atlas Data Lake • AWS S3 buckets • HTTPS endpoints

Slide 65

Slide 65 text

No content

Slide 66

Slide 66 text

Data API Request $ curl --location --request POST 'https://.../v1/action/findOne' \ --header 'Content-Type: application/json' \ --header 'Access-Control-Request-Headers: *' \ --header 'api-key: 0fUMoHadYlL2QiI5vxQ7HyWIxNZ6jwHdFAyrb4zUB2ZZlGozFdXX5aiLNDYQu3K1' \ --header 'Accept: application/ejson' \ --data-raw '{ "collection":"gpsdata", "database":"karting", "dataSource":"Cluster95038" }'

Slide 67

Slide 67 text

Data API Response { "document": { "_id": { "$oid": "6490311fd97a12c964c25030" }, "time": { "$numberDouble": "1685866107.024" }, "latitude": { "$numberDouble": "44.8859" }, "longitude": { "$numberDouble": "13.873914" }, "altitude": { "$numberDouble": "35.092" }, "speed": { "$numberDouble": "0.663" } } }

Slide 68

Slide 68 text

MongoDB Atlas Atlas Search • Full-text search embedded in MongoDB Atlas • Built on Apache Lucene • Search data directly without duplicating it

Slide 69

Slide 69 text

MongoDB Atlas Other features • Atlas Data Lake • Triggers • Encryption at Rest • Self-managed X.509 Authentication • App Services • In-Use Encryption

Slide 70

Slide 70 text

Don’t Trust Anyone

Slide 71

Slide 71 text

Don’t Trust Anyone Encrypt your data • MongoDB supports Client-Side Field Level Encryption • You have the key, we don’t • Data is encrypted in the driver • Schema to de fi ne encrypted fi elds and keys • Equality queries on deterministically encrypted fi elds only

Slide 72

Slide 72 text

Don’t Trust Anyone Queryable Encryption • Searchable encryption scheme • In public preview, stay tuned • Equality queries on randomised encrypted data • More query types coming soon

Slide 73

Slide 73 text

Your data is protected

Slide 74

Slide 74 text

What’s next?

Slide 75

Slide 75 text

What’s Next MongoDB 7.0 • Will be announced Thursday • Atlas Search Index management • Delete Time Series data • And more…

Slide 76

Slide 76 text

What’s Next PHP Driver • Aggregation Pipeline builder • Laravel Integration • Native BSON classes • Lazy BSON deserialisation for more performance

Slide 77

Slide 77 text

Things I didn’t mention There isn’t enough time for everything • Mirrored and hedged reads • Time Series collections • Clustered collections • Wildcard Indexes • Cloud Manager • Kubernetes Operator • Compass

Slide 78

Slide 78 text

Join me at WSC! • Learn schema design patterns • JSONb, composite types in PostgreSQL • Migrate existing schema to MongoDB • Leverage aggregation pipeline for complex workloads Want to learn more?

Slide 79

Slide 79 text

No content

Slide 80

Slide 80 text

Thanks! @alcaeus github.com/alcaeus symfony-devs: @alcaeus