1 00:00:02,420 --> 00:00:07,270 Now that we had a look at one-to-one and one-to-many relationships, the obvious missing thing is one-to- 2 00:00:07,280 --> 00:00:08,050 many. 3 00:00:08,390 --> 00:00:12,110 So let's say we have customers who can buy products, 4 00:00:12,110 --> 00:00:14,050 so we're looking at orders, 5 00:00:14,210 --> 00:00:20,960 a customer might buy multiple products and a product might be bought by different customers, 6 00:00:20,990 --> 00:00:24,740 so one customer many products, one product many customers. 7 00:00:24,860 --> 00:00:27,860 So this is a typical many-to-many relationship, 8 00:00:27,920 --> 00:00:31,100 how could we model that? To say it right away, 9 00:00:31,100 --> 00:00:35,160 often you'll model many-to-many relationships with references. 10 00:00:35,480 --> 00:00:41,300 So let me again create a new database or join a new database, 11 00:00:41,450 --> 00:00:47,630 my shop database and there, I might have products, so I'll insert a product here, 12 00:00:51,050 --> 00:00:59,510 that product will have a title, let's say a book and the price 12.99. 13 00:00:59,670 --> 00:01:09,510 I also will have customers, so I'll also insert a new customer into my customers collection, name Max, 14 00:01:10,080 --> 00:01:11,420 age 29 15 00:01:11,910 --> 00:01:22,960 and now with that, we could create an orders collection, orders to insert one order and there, we could now have 16 00:01:23,170 --> 00:01:33,650 a productId and simply take that id of the product we added and we could have a customerId and take 17 00:01:33,650 --> 00:01:42,100 that customer here and now we have that too. Now this would be the SQL world approach where we have 18 00:01:42,160 --> 00:01:49,420 three tables in SQL and we have that join table in the middle which matches products and customers. 19 00:01:49,890 --> 00:01:54,460 Now we can do a bit better in quotation marks in mongodb, 20 00:01:54,790 --> 00:02:01,340 we can make it work with two tables only, so I can actually drop my orders collection, 21 00:02:01,450 --> 00:02:05,870 so db.orders can be dropped, 22 00:02:05,870 --> 00:02:09,820 so if you now find that, you find nothing because I've dropped that and all the data in it. 23 00:02:10,250 --> 00:02:15,350 And with that dropped, I still have my products by the way, so we still have the products and we still 24 00:02:15,350 --> 00:02:18,680 have the customers, 25 00:02:18,830 --> 00:02:20,310 so we have these two tables, 26 00:02:20,330 --> 00:02:27,380 I can now add orders without adding a third table and for that, I'll go to my customers let's say because 27 00:02:27,380 --> 00:02:33,260 typically, I want to add that relation on the customer because you could say yes the product got bought 28 00:02:33,680 --> 00:02:38,900 but actually customer is the active person and it's more realistic that you're fetching the orders for 29 00:02:38,930 --> 00:02:43,780 a given customer than that you want to display orders for a given product 30 00:02:43,790 --> 00:02:47,610 but that would be possible too and you can use that approach on both tables here. 31 00:02:47,720 --> 00:02:52,280 So I'll show it on the customer and I'll simply update my customer here, 32 00:02:52,280 --> 00:02:55,670 obviously you could also insert new customer with existing orders, 33 00:02:55,730 --> 00:03:03,820 so I'll update the customer with $set and then add orders here as an array 34 00:03:04,160 --> 00:03:12,020 and now every order could simply be an object where I have my productId and that still is the ID 35 00:03:12,020 --> 00:03:13,340 I have up there, 36 00:03:13,640 --> 00:03:15,600 so I use this ID down there 37 00:03:15,890 --> 00:03:21,480 and then maybe something like the quantity. We could have also added that quantity to that third in-between 38 00:03:21,560 --> 00:03:23,370 table earlier by the away. 39 00:03:23,510 --> 00:03:30,980 So now if I do that and I find one customer, you see now we have the orders and that might look like I embed the 40 00:03:30,980 --> 00:03:32,360 document because it is 41 00:03:32,480 --> 00:03:37,370 but actually we're still using a reference approach here because we did not embed the product data, 42 00:03:37,610 --> 00:03:39,770 we just added some metadata for the order 43 00:03:39,890 --> 00:03:42,480 but I'm just referencing the product data. 44 00:03:42,620 --> 00:03:48,050 So we're using a reference driven approach here and we could add the same orders array to the products 45 00:03:48,080 --> 00:03:50,600 if we want to match it the other way around too, 46 00:03:50,630 --> 00:03:54,020 so both is possible or either of the one like we have it here. 47 00:03:54,080 --> 00:03:59,240 So now we have a many-to-many relationship with references, with two tables which would be the mongodb 48 00:03:59,240 --> 00:04:04,710 way of displaying or creating such a many-to-many relationship with references. 49 00:04:04,790 --> 00:04:10,100 You could also argue that you don't necessarily need to use references here, 50 00:04:10,100 --> 00:04:11,050 often you will 51 00:04:11,090 --> 00:04:17,330 and if that's your use case, it's fine but let's have a look at the embedded alternative and for that, 52 00:04:17,350 --> 00:04:22,460 I'll update my orders array here and that will replace it, 53 00:04:22,460 --> 00:04:24,590 it will not add this element, 54 00:04:24,620 --> 00:04:26,630 we'll see how we can add elements to arrays later. 55 00:04:26,630 --> 00:04:35,460 For now we'll replace that orders array with a new one, with a new array of documents of orders, here 56 00:04:35,480 --> 00:04:42,410 I now have a title of my product because say I fetched that in my application when the order was placed, 57 00:04:43,800 --> 00:04:46,140 with the price 12.99, 58 00:04:46,530 --> 00:04:56,590 so I'm manually copying this so to say and a quantity too. Now if I look into my customers collection, we 59 00:04:56,590 --> 00:05:02,980 do have an embedded document, this is now not a reference driven approach but I embedded the product data along 60 00:05:03,070 --> 00:05:05,760 with the metadata for the order. 61 00:05:06,100 --> 00:05:08,960 Now what could be a disadvantage of this approach? 62 00:05:10,320 --> 00:05:12,720 A disadvantage is the data duplication, 63 00:05:12,870 --> 00:05:19,410 we've got the title and price of that product in orders here and keep in mind that this user might order 64 00:05:19,410 --> 00:05:22,750 this product multiple times and other users could do, 65 00:05:22,890 --> 00:05:26,370 so you will probably duplicate this data a lot 66 00:05:26,790 --> 00:05:32,550 and if you ever change that data, you not only need to change it in the products collection where you 67 00:05:32,550 --> 00:05:38,010 store it and that is the product data which is displayed in your shop for users to buy it but you would 68 00:05:38,010 --> 00:05:41,320 also have to change it in all the orders, well 69 00:05:41,340 --> 00:05:42,320 or do you 70 00:05:42,330 --> 00:05:45,440 and that is the reason why such an embedded approach might be fine. 71 00:05:45,930 --> 00:05:52,860 Once the order was placed, even if the price changed for the product, we will not change it for the existing 72 00:05:52,890 --> 00:05:53,410 orders 73 00:05:53,430 --> 00:05:53,800 right, 74 00:05:53,830 --> 00:05:57,190 the people don't have to pay more after they bought it, 75 00:05:57,270 --> 00:05:59,880 so the price here is logged in anyways. 76 00:06:00,180 --> 00:06:05,420 The title might change a bit but do we really care about this in our orders? 77 00:06:05,490 --> 00:06:06,590 We might not care, 78 00:06:06,630 --> 00:06:11,690 it's not going to change from a book to a T-shirt because it's still the same product in the end, it 79 00:06:11,700 --> 00:06:16,460 still has its own unique ID and we would probably also store the ID along with the product here 80 00:06:16,460 --> 00:06:23,010 by the way. So probably we don't care about a title change too because if it's a nice book now instead 81 00:06:23,010 --> 00:06:26,100 of a book, doesn't really matter for us. 82 00:06:26,100 --> 00:06:33,570 So if we have an application where we kind of take a snapshot of the data anyways, we might not worry 83 00:06:33,570 --> 00:06:38,850 too much about duplicating that data because we might not need to change it in all the places where 84 00:06:38,850 --> 00:06:40,040 we did duplicate it 85 00:06:40,180 --> 00:06:47,250 if the original data changes and that of course highly depends on your application. For a shop and the 86 00:06:47,250 --> 00:06:49,110 products and the orders, 87 00:06:49,320 --> 00:06:54,400 this might make sense, in other use cases you might absolutely need 88 00:06:54,450 --> 00:06:58,650 the latest data everywhere and we'll have a look at such a use case next. 89 00:06:58,920 --> 00:07:02,620 But I want you to not automatically say many-to-many, 90 00:07:02,700 --> 00:07:04,820 I will use a reference. Instead 91 00:07:04,860 --> 00:07:07,470 think about how do you fetch your data, 92 00:07:07,470 --> 00:07:09,160 how often do you change it 93 00:07:09,180 --> 00:07:14,610 and if you change it, do you need to change it everywhere or might duplicates be fine?