MongoDB¶
A labor során a MongoDB NoSQL adatbáziskezelő rendszer és a Mongo C# driver használatát gyakoroljuk komplexebb feladatokon keresztül.
Előfeltételek, felkészülés¶
A labor elvégzéséhez szükséges eszközök:
- Windows, Linux, vagy MacOS: Minden szükséges program platform független, vagy van platformfüggetlen alternatívája.
-
MongoDB Community Server (letöltés)
-
Telepítés nélkül Docker segítségével az alábbi paranccsal futtathatod a szervert
docker run --name swlab1-mongo -p 27017:27017 -d mongo
-
-
VSCode
- MongoDB for VSCode kiegészítő
- Minta adatbázis kódja (mongo.js)
- GitHub account és egy git kliens
- Microsoft Visual Studio 2022 az itt található beállításokkal
- Linux és MacOS esetén Visual Studio Code és a .NET SDK-val települő dotnet CLI használható.
-
.NET 8.0
A feladat megoldásához 8.0-es .NET SDK telepítése szükséges.
Windows-on Visual Studio verzió függvényében lehet, hogy telepítve van (lásd itt az ellenőrzés módját); ha nem, akkor a fenti linkről kell telepíteni (az SDK-t és nem a runtime-ot.) Linux és MacOS esetén telepíteni szükséges.
A labor elvégzéséhez használható segédanyagok és felkészülési anyagok:
- MongoDB adatbáziskezelő rendszer és a C# driver használata
- Lásd az Adatvezérelt rendszerek c. tárgy jegyzetei és gyakorlati anyagai között
- Hivatalos Microsoft tutorial Mongo-t használó Web API készítéséhez
- A labor során nem WebAPI-t készítünk, de a Mongo használat azonos formában történik.
Előkészület¶
A feladatok megoldása során ne felejtsd el követni a feladat beadás folyamatát.
Git repository létrehozása és letöltése¶
-
Moodle-ben keresd meg a laborhoz tartozó meghívó URL-jét és annak segítségével hozd létre a saját repository-dat.
-
Várd meg, míg elkészül a repository, majd checkout-old ki.
Jelszó a laborokban
Egyetemi laborokban, ha a checkout során nem kér a rendszer felhasználónevet és jelszót, és nem sikerül a checkout, akkor valószínűleg a gépen korábban megjegyzett felhasználónévvel próbálkozott a rendszer. Először töröld ki a mentett belépési adatokat (lásd itt), és próbáld újra.
-
Hozz létre egy új ágat
megoldasnéven, és ezen az ágon dolgozz. -
A
neptun.txtfájlba írd bele a Neptun kódodat. A fájlban semmi más ne szerepeljen, csak egyetlen sorban a Neptun kód 6 karaktere.
Adatbázis létrehozása¶
Kövesd a gyakorlatanyagban leírt utasításokat az adatbáziskezelő rendszer elindításához és az adatbázis létrehozásához.
1. Feladat: Termékek lekérdezése és módosítása (7 pont)¶
Ebben a feladatban a Product entitáshoz tartozó CRUD (létrehozás, listázás/olvasás, módosítás és törlés) utasításokat fogjuk megvalósítani.
Visual Studio solution megnyitása¶
Nyisd meg a letöltött repository-ban a Visual Studio solution-t (.sln fájl). Ha a megnyitás során a Visual Studio azt jelezné, hogy a projekt típus nem támogatott, akkor telepítsd a Visual Studio hiányzó komponenseit (lásd itt).
NE frissíts semmilyen verziót
Ne frissítsd se a projektet, se a .NET verziót, se a NuGet csomagokat! Ha ilyen kérdéssel találkozol a solution megnyitása során, akkor mindig mondj nemet!
Munkád során a Dal.Repository osztályba dolgozz! Ezen fájl tartalmát tetszőlegesen módosíthatod (feltéve, hogy továbbra is megvalósítja a Dal.IRepository interfészt, továbbra is van egy konstruktora egyetlen IMongoDatabase paraméterrel és természetesen továbbra is fordul a kód).
Az adatbázis elérése a Dal.MongoConnectionConfig osztályban van. Ha szükséges, az adatbázis nevét megváltoztathatod a forrásban jelölt helyen.
A projekt minden egyéb tartalma már elő van készítve a munkához, a fentieken kívül máshol NE módosítsd!
Razor Pages
A webalkalmazás egy un. Razor Pages típusú ASP.NET Core projekt. Ez egy szerver oldalon renderelt megjelenítési réteg, ahol tehát a weboldal html kódját C# kód és a Razor template állítja elő. (A megjelenítési réteggel nem lesz feladatod, az már elő van készítve számodra.)
Webalkalmazás elindítása¶
Próbáld ki, hogy elindul-e a program.
-
Fordítsd le és indítsd el Visual Studio-ból az alkalmazást.
-
Nyisd meg böngészőben a http://localhost:5000/ oldalt.
Ha minden rendben ment, akkor bejött egy oldal, ahol az egyes feladatokat ki fogod tudni próbálni. (Az egyes feladatokra mutató linkek mögötti oldalak még nem működnek. Előbb még meg kell valósítani az adatelérési réteget.)
Neptun kód megjelenítése a weboldalon¶
A forráskód melletti képernyőképeken szerepelnie kell a Neptun kódodnak.
-
Nyisd meg a
Pages\Shared\_Layout.cshtmlfájlt. A fájl közepe felé keresd meg az alábbi részt, és írd át benne a Neptun kódodat.<div class="container body-content"> @RenderBody() <hr /> <footer> <p>@ViewData["Title"] - NEPTUN</p> </footer> </div> -
Fordítsd le és indítsd el az alkalmazást ismét, nézd meg a kezdőoldalt. Az alján kell lásd a saját Neptun kódod.
FONTOS
A Neptun kódnak a fentiek szerint szerepelnie kell minden képernyőképen!
Listázás/olvasás¶
-
Első lépésként szükség lesz az adatbázisban található
productskollekció elérésére a kódból. Ehhez vegyél fel egy új mezőt aRepositoryosztályban, és inicializáld ezt a konstruktorban. Az ehhez szükségesIMongoDatabaseobjektumot Dependency Injection segítségével, konstruktorparaméterként kaphatod meg.private readonly IMongoCollection<Entities.Product> _productCollection; public Repository(IMongoDatabase database) { this._productCollection = database.GetCollection<Entities.Product>("products"); } -
A
_productCollectionsegítségével már tudunk lekérdező/listázó utasításokat írni. Valósítsuk meg először aListProductsfüggvényt. Ez a függvény két lépésből áll: először lekérdezzük az adatbázisból a termékek listáját, majd pedig átkonvertáljuk az elvártModels.Productosztály elemekből álló listára.A lekérdezés a következőképpen néz ki:
var dbProducts = _productCollection .Find(_ => true) // minden terméket listázunk — üres filter .ToList();Ezt a listát aztán transzformálva adjuk vissza.
return dbProducts .Select(t => new Product { Id = t.Id.ToString(), Name = t.Name, Price = t.Price, Stock = t.Stock }) .ToList(); -
A
FindProduct(string id)függvény megvalósítása nagyon hasonlít az előzőhöz, csupán annyiban különbözik, hogy itt egyetlen terméket kérdezünk le,idalapján. Ügyeljünk rá, hogy azid-t szövegként kapjuk, ígyObjectId-vá kell alakítani.A modellé konvertáló lépés ugyanúgy megmarad. Ebben az esetben oda kell figyelnünk azonban, hogy ha nem találjuk az adott terméket, akkor adjunk vissza
nullértéket, ne próbáljunk konvertálni.A lekérdező lépés a következőre módosul:
var dbProduct = _productCollection .Find(t => t.Id == ObjectId.Parse(id)) .SingleOrDefault(); // ... model konverzioFigyeljük itt meg, hogy hogyan módosult a filter kifejezés! Fontos továbbá, hogy itt
ToListhelyett aSingleOrDefaultkiértékelő kifejezést használjuk. Ez a megszokott módon vagy egy konkrét terméket ad vissza, vagynullértéket. Így tudunk tehátIdalapján megtalálni egy entitást az adatbázisban. Jegyezzük ezt meg, mert ez még sok következő feladatban hasznos lesz!A konvertáló kifejezést már megírtuk egyszer az előző kifejezésben, ezt használhatjuk itt is — figyeljünk azonban oda, hogy a
dbProductértéke lehetnullis. Ebben az esetben ne konvertáljunk, csupán adjunk visszanullértéket mi is. -
Próbáld ki a megírt függvények működését! Indítsd el a programot, és navigálj tetszőleges böngészőben a http://localhost:5000 weboldalra. Itt a
Productsmenüpontban már látnod kell a termékeket felsoroló táblázatot. Ha valamelyik sorban aDetailsmenüpontra kattintasz, akkor egy adott termék részleteit is látnod kell.
Ha nem látsz egyetlen terméket se
Ha a weboldalon egyetlen termék se jelenik meg, de az oldal betöltésre kerül és nincs hiba, akkor az adatbázis elérésével van probléma. Valószínűleg nem létezik a megadott nevű adatbázis. Lásd fentebb az adatbázis konfigurálását.
Létrehozás¶
-
Ebben a pontban az
InsertProduct(Product product)függvényt valósítjuk meg. A bemenőModels.Productmodell adatait a felhasználó szolgáltatja a felhasználói felületen keresztül. -
Egy termék létrehozásához először létre kell hoznunk egy új adatbázisentitás objektumot. Jelen esetben ez egy
Entites.Productobjektum lesz. AzIdértéket nem kell megadnunk — ezt majd az adatbázis generálja. AName,PriceésStockértékeket a felhasználó szolgáltatja. Két érték maradt ki: azVatés aCategoryId. Az előbbinek adjunk tetszőleges értéket, az utóbbinak pedig keressünk egy szimpatikus kategóriát az adatbázisban a Studio 3T segítségével, és annak az_idértékét drótozzuk be!var dbProduct = new Entities.Product { Name = product.Name, Price = product.Price, Stock = product.Stock, Vat = new Entities.Vat { Name = "General", Percentage = 20 }, CategoryId = ObjectId.Parse("5d7e4370cffa8e1030fd2d99"), }; _productCollection.InsertOne(dbProduct);Ha megvan az adatbázisentitás objektum, akkor az
InsertOneutasítás segítségével tudjuk elmenteni az adatbázisba. -
A függvény kipróbálásához indítsd el megint a programot, és a termékek táblázata feletti
Add new productlinkre kattints. Itt meg tudod adni a szükséges adatokat, amivel meghívódik a kódod.
Törlés¶
-
A törlés megvalósításához a
DeleteProduct(string id)függvényt kell implementálni. Itt a kollekcióDeleteOnefüggvényét kell használni. Ehhez meg kell adni egy filter kifejezést: itt használjuk ugyanazt a filtert, amit az egy konkrét termék lekérdezéséhez használtunk aFindProduct(string id)metódusban. -
Ezt a metódust is ki tudod próbálni, ha a termékek táblázatában valamelyik sorban a
Deletelinkre kattintasz.
Módosítás¶
-
A termékek módosító utasításaként az eladást fogjuk megvalósítani, a
bool SellProduct(string id, int amount)függvényben. A függvény akkor és csak akkor térjen visszatrueértékkel, ha létezik azidazonosítójú termék, és legalábbamountdarab van belőle raktáron, amit el is tudtunk adni. Ha nem létezik a termék vagy nincs belőle elegendő, akkor térjen visszafalseértékkel. -
A MongoDB atomicitását kihasználva ezt a feladatot egyetlen utasítás kiadásával fogjuk megvalósítani. A filter kifejezésben fogunk rászűrni a megadott
id-ra, és arra is, hogy elegendő termék van-e raktáron. A módosító kifejezésben fogjuk csökkenteni a raktárkészletet — csak akkor, ha létezik a termék, és elegendő van belőle raktáron.var result = _productCollection.UpdateOne( filter: t => t.Id == ObjectId.Parse(id) && t.Stock >= amount, update: Builders<Entities.Product>.Update.Inc(t => t.Stock, -amount), options: new UpdateOptions { IsUpsert = false });Fontos megfigyelni, hogy az
UpdateOptionssegítségével jeleztük az adatbázisnak, hogy NE upsertet hajtson végre — tehát ne tegyen semmit ha nem találja a filterben megadott terméket.A módosító utasítást a
Builders-ben találhatóUpdatebuilder segítségével tudjuk összerakni. Esetünkbenamount-tal akarjuk csökkenteni az értéket — ez-amount-tal történő inkrementálást jelent.A visszatérési értéket az update
result-jából tudjuk meghatározni. Amennyiben talált olyan terméket, ami megfelelt a filternek, akkor sikeres volt a módosítás, teháttrueértékkel térhetünk vissza. Egyébként a visszatérési értékfalse.return result.MatchedCount > 0; -
Ezt a metódust is ki tudod próbálni, ha a termékek táblázatában valamelyik sorban a
Buylinkre kattintasz. Próbáld ki úgy is, ha túl nagy értéket írsz be!
BEADANDÓ
Készíts egy képernyőképet a termék listázó weboldalról miután felvettél legalább egy új terméket. A képet a megoldásban f1.png néven add be. A képernyőképen látszódjon a termék lista. Ellenőrizd, hogy a Neptun kódod (az oldal aljáról) látható-e a képen! A képernyőkép szükséges feltétele a pontszám megszerzésének.
2. Feladat: Kategóriák listázása (4 pont)¶
Ebben a feladatban a kategóriákat fogjuk listázni — az adott kategóriába tartozó termékek számával együtt. Ehhez már aggregációs utasítást is használnunk kell majd. Továbbra is a Dal.Repository osztályba dolgozunk.
A megvalósítandó függvény a IList<Category> ListCategories(). Ennek minden kategóriát vissza kell adnia. A Models.Category osztály 3 adattagot tartalmaz.
Name: értelemszerűen a kategória neveParentCategoryName: a kategória szülőkategóriájának neve. Amennyiben nincs szülőkategória, értéke legyennull.NumberOfProducts: a kategóriába tartozó termékek száma. Amennyiben nincs ilyen, értéke legyen 0.
A megvalósítás lépései a következők.
-
Első lépésként a
_productCollectionmintájára vedd fel és inicializáld a_categoryCollection-t is. Az adatbázisban a kollekció nevecategories— ezt Studio 3T segítségével tudod ellenőrizni. -
A
ListCategories()metódusban először kérdezzük le a kategóriák teljes listáját. Ez pontosan ugyanúgy történik, mint az előző feladatban a termékek esetében. A lekérdezés értékét tegyük adbCategoriesváltozóba. -
Ezután kérdezzük le, hogy az egyes
CategoryId-khez hány darab termék tartozik. Ehhez aggregációs pipeline-t kell használnunk, azon belül pedig a$grouplépést.var productCounts = _productCollection .Aggregate() .Group(t => t.CategoryId, g => new { CategoryID = g.Key, NumberOfProducts = g.Count() }) .ToList();Ez az utasítás egy olyan listával tér vissza, melyben minden elem egy
CategoryIDértéket tartalmaz a hozzá tartozó termékek számával együtt. -
Ezen a ponton minden számunkra szükséges információ rendelkezésünkre áll — ismerjük az összes kategóriát (a szülőkategória megkereséséhez), és ismerjük a kategóriákhoz tartozó termékek számát. Egyetlen dolgunk van, hogy ezeket az információkat (C# kódból) "összefésüljük".
return dbCategories .Select(k => new Category { Name = k.Name, ParentCategoryName = k.ParentCategoryId.HasValue ? dbCategories.Single(p => p.Id == k.ParentCategoryId.Value).Name : null, NumberOfProducts = productCounts.SingleOrDefault(pc => pc.CategoryID == k.Id)?.NumberOfProducts ?? 0 }) .ToList();Láthatjuk, hogy mind a két lépést egyszerűen elintézhetjük C#-ban LINQ segítségével. A szülőkategória nevéhez a kategóriák között kell keresnünk, a termékek darabszámához pedig az aggregáció eredményében keresünk.
Join Mongo-ban
Nem ez az egyetlen módja a gyűjtemények "összekapcsolásának" MongoDB-ben. Ugyan
joinnincs, de léteznek megoldások a gyűjteményeken átívelő lekérdezésekre. A fenti megoldás az adatbázis helyett C# kódban végzi el az összekapcsolást. Ez akkor praktikus, ha nem nagy méretű adathalmazzal dolgozunk, és nincs (jó) szűrésünk. Ha szűrni kellene az adathalmazt, a fenti megoldás is bonyolultabb lenne a hatékonyság érdekében. -
A kód kipróbálásához a weboldal
Categoriesmenüpontjára kell navigálni. Itt táblázatos formában megjelenítve láthatod az összegyűjtött információkat. Teszteléshez alkalmazhatod az előző feladatban elkészítettAdd new productfunkciót — itt a hozzáadás esetén az egyik kategória mellett növekednie kell a hozzá tartozó termékek darabszámának. (A termék beszúrásakor a kategória ID-ját bedrótoztuk a kódba, tehát annak a kategóriának kell nőnie, amelyiknek az ID-ja a kódban szerepel.)
BEADANDÓ
Készíts egy képernyőképet a kategória listázó weboldalról. A képet a megoldásban f2.png néven add be. A képernyőképen látszódjon a kategória lista. Ellenőrizd, hogy a Neptun kódod (az oldal aljáról) látható-e a képen! A képernyőkép szükséges feltétele a pontszám megszerzésének.
3. Feladat: Megrendelések lekérdezése és módosítása (5 pont)¶
Ebben a feladatban a Megrendelés (Order) entitáshoz tartozó CRUD (létrehozás, listázás/olvasás, módosítás és törlés) utasításokat fogjuk megvalósítani. Ez a feladat nagyon hasonlít az első feladathoz, amennyiben elakadnál nyugodtan meríts ihletet az ottani megoldásokból!
A Models.Order entitás adattagjai:
Id: az adatbázisentitásId-ja,ToString-gel sorosítvaDate,Deadline,Status: egy az egyben másolandók az adatbázis entitásbólPaymentMethod: az adatbázis entitásban találhatóPaymentMethodkomplex objektumMethodmezőjeTotal: a megrendelésben található tételek (OrderItems)AmountésPriceszorzatainak összege
Ennek a feladatnak a megoldásához a megrendeléssel kapcsolatos metódusok implementációja szükséges (ListOrders, FindOrder, InsertOrder, DeleteOrder és UpdateOrder).
Az alábbi feladatok előtt ne felejtsd el felvenni és inicializálni a _orderCollection-t a repository osztályba a korábban látottak mintájára!
Listázás/olvasás¶
-
A
ListOrdersfüggvény paraméterként kap egystring statusértéket. Ha ez az érték üres vagynull(lásd:string.IsNullOrEmpty), akkor minden megrendelést listázz. Ellenkező esetben csak azokat a megrendeléseket listázd, melyeknek aStatusértéke teljesen egyezik a paraméterben érkezőstatusértékkel. -
A
FindOrdermetódus egy konkrét megrendelés adatait adja vissza astring idérték alapján szűrve. Figyelj oda, ha az adottIDérték nem található az adatbázisban, akkornullértéket adj vissza!
Létrehozás¶
-
Az
InsertOrdermetódusban a létrehozást kell megvalósítanod. Ehhez háromféle információt kapsz:Order order,Product productésint amount. -
Az adatbázisentitás létrehozásához a következő információkra van szükség:
CustomerId,SiteId: az adatbázisból keresd ki egy tetszőleges vevőhöz (Customer) tartozó dokumentum_idésmainSiteIdértékét. Ezeket az értékeket drótozd bele a kódodba.Date,Deadline,Status: ezeket az értékeket azorderparaméterből vehetedPaymentMethod: hozz létre egy újPaymentMethodobjektumot. AMethodlegyen azorderparaméterben találhatóPaymentMethodérték. ADeadlinemaradjonnull!OrderItems: egyetlen tételt hozz létre! Ennek adattagjai:ProductIdésPrice: aproductparaméterből vehetedAmount: a függvényparaméteramountparaméterből jönStatus: azorderparaméterStatusmezőjével egyezik meg
- minden más adattag (a számlázással kapcsolatos információk) maradjon
nullértéken!
Törlés¶
A DeleteOrder törölje a megadott Id-hoz tartozó megrendelést.
Módosítás¶
A módosító utasításban (UpdateOrder) arra figyelj oda, hogy csak azokat a mezőket írd felül, melyek a Models.Order osztályban megtalálhatóak: Date, Deadline, Status és PaymentMethod. Az Total-t itt nem kell figyelembe venni, ennek értéke nem fog változni.
Tipp
Több módosító kifejezést a Builders<Entities.Order>.Update.Combine segítségével lehet összevonni.
Itt is figyelj oda, hogy az update során az IsUpsert beállítás értéke legyen false!
A metódus visszatérési értéke akkor és csak akkor legyen true, ha létezik megrendelés a megadott ID-val — azaz volt illeszkedés a filterre.
Kipróbálás¶
A megírt függvényeket a weboldalon a Orders menüpont alatt tudod kipróbálni. Teszteld le a Filter, Add new order, Edit, Details és Delete opciókat is!
BEADANDÓ
Készíts egy képernyőképet a megrendelés listázó weboldalról miután felvettél legalább egy új megrendelést. A képet a megoldásban f3.png néven add be. A képernyőképen látszódjon a megrendelések listája. Ellenőrizd, hogy a Neptun kódod (az oldal aljáról) látható-e a képen! A képernyőkép szükséges feltétele a pontszám megszerzésének.
4. Feladat: Vevők listázása (4 pont)¶
Ebben a feladatban a vevőket fogjuk listázni — az általuk megrendelt termékek összértékével együtt. Ehhez a második feladathoz hasonlatosan aggregációs utasítást és C# kódban történő "összefésülést" kell majd használnunk.
A megvalósítandó metódus az IList<Customer> ListCustomers(). Ennek minden vevőt vissza kell adnia. A Models.Customer entitás adattagjai:
Name: a vevő neveZipCode,City,Street: a vevő központi telephelyéhez tartozó címTotalOrders: a vevőhöz tartozó összes megrendelés összértékének (lásd előző feladat) összege. Amennyiben még nincs az adott vevőhöz tartozó megrendelés, akkor ennek az értéke legyennull!
A feladat megoldásához ajánlott lépések:
-
Vedd fel és inicializáld a
_customerCollection-t! -
Listázd ki az összes vevőt. A vevő entitásban megtalálod a telephelyek listáját (
Sites) és a központi telephely azonosítóját (MainSiteId) is. Ez utóbbit kell megkeresned az előbbi listában, hogy megkapd a központi telephelyet (és így a hozzá tartozó címet). -
A megrendelések kollekcióján aggregációs pipeline-t használva meg tudod állapítani az adott
CustomerId-hez tartozó összmegrendelések értékét. -
Végezetül csak a meglevő információkat kell "összefésülnöd". Központi telephelye minden vevőnek van, viszont megrendelése nem garantált — figyelj oda, hogy ekkor a
TotalOrderselvárt értékenull! -
A kód kipróbálásához a weboldal
Customersmenüpontjára kell navigálni. Itt táblázatos formában megjelenítve láthatod az összegyűjtött információkat. Teszteléshez alkalmazhatod az előző feladatban elkészítettAdd new orderfunkciót — itt új megrendelés felvétele esetén az előző feladatban bedrótozott vevő mellett növekednie kell a hozzá tartozó megrendelések összértékének.
BEADANDÓ
Készíts egy képernyőképet a vevő listázó weboldalról. A képet a megoldásban f4.png néven add be. A képernyőképen látszódjon a vevők listája. Ellenőrizd, hogy a Neptun kódod (az oldal aljáról) látható-e a képen! A képernyőkép szükséges feltétele a pontszám megszerzésének.
5. Feladat: Opcionális (iMSc) feladat (3 iMsc pont)¶
Ebben a feladatban az adatbázisban található megrendeléseket fogjuk dátum szerint csoportosítani — kíváncsiak vagyunk ugyanis az elmúlt időszakokban a megrendelések mennyiségének és összértékének alakulására. Ennek megvalósításához a $bucket aggregációs lépést fogjuk használni.
Követelmények¶
A megvalósítandó metódus az OrderGroups GroupOrders(int groupsCount). Ez az adatbázisban található megrendeléseket groupsCount egyenlő időintervallumra csoportosítja. A visszatérési érték két adattagot tartalmaz:
IList<DateTime> Thresholds: Az időpontok amik az időintervallumok határait jelentik.- Az intervallumok alsó határa inkluzív, a felső határ exkluzív
ndarab intervallum esetén aThresholdslistan + 1elemű- Pl.: Ha a
Thresholdslista elemeia, b, c, d, akkor az időintervallumok a következők:[a, b[,[b, c[és[c, d[.
IList<OrderGroup> Groups: A megrendelések csoportjai. AOrderGroupentitás adattagjai:Date: Az adott intervallum kezdő dátuma. Tehát[a, b[intervallum eseténa.Pieces: Az adott intervallumba eső megrendelések darabszáma.Total: Az adott intervallumba tartozó összes megrendelés összértékének összege (lásd előző feladat).
További követelmények:
- Pontosan
groupsCountintervallumra bontsd a megrendeléseket.- A
Thresholdslista elemszáma így pontosangroupsCount + 1. - A
Groupselemszáma legfeljebbgroupsCount— az üres (megrendelést nem tartalmazó) intervallumoknak nem kell listaelem
- A
- A legelső határ legyen az adatbázisban található legrégebbi megrendelés dátuma
- A legutolsó határ legyen az adatbázisban található legújabb megrendelés dátuma + 1 óra
- Ez azért kell, mert az intervallum felső határa exkluzív. Így garantáljuk, hogy az adatbázisban található minden megrendelés belekerül egy intervallumba.
- Tipp: a következő módon tudsz egy órát hozzáadni egy dátumhoz:
date.AddHours(1).
- Az intervallumok legyenek egyenlő méretűek
- Tipp: a C# nyelv beépítve kezeli matematikai műveletek végzését dátum (
DateTime) és időtartam (TimeSpan) objektumokon — lásd pl. előző pont.
- Tipp: a C# nyelv beépítve kezeli matematikai műveletek végzését dátum (
A megoldás során feltételezheted a következőket:
- Az adatbázisban található minden megrendelésnek van
Dateértéke, annak ellenére, hogy az adattag típusa nullable (DateTime?).- Használd tehát nyugodtan a
date.Valueértéket adate.HasValueérték ellenőrzése nélkül.
- Használd tehát nyugodtan a
- A
groupsCountegy pozitív egész szám (tehát értéke legalább 1).
Megoldás vázlata¶
-
Kérdezd le az adatbázisból a legrégebbi és a legújabb megrendelés dátumát.
- Tipp: Ezt megoldhatod két lekérdezéssel vagy akár egyetlen aggregáció segítségével is.
-
Számold ki az intervallumok határait a követelményeknek megfelelően.
- Ezzel már meg is fogod kapni a visszatérési értékben szükséges
Thresholdslistát.
- Ezzel már meg is fogod kapni a visszatérési értékben szükséges
-
A megrendelések kollekción hajts végre egy
$bucketaggregációt. Ennek dokumentációját itt találhatod meg.- a
groupBykifejezés a megrendelés dátuma lesz - a
boundarieskifejezés pontosan abban a formában várja az értékeket, amit a követelmények között is olvashattál, tehát az előző pontban előállított lista pontosan megfelel - az
outputkifejezésben fogalmazhatod meg a szükséges kiszámolandó értékeket (darabszám, összérték)
Tipp
Ha
"Element '...' does not match any field or property of class..."kezdetű exceptiont kapsz, akkor azoutputkifejezésben írj át minden property-t kisbetűsre (pl.:Pieces->pieces). Úgy tűnik, hogy a Mongo C# driver ezen a ponton nem konzisztensen transzformálja az adattagok neveit. - a
-
A
$bucketaggregáció az elvárt követelményeknek pontosan megfelelő intervallumokkal fog visszatérni, így az eredményét már csak transzformálni kell a megfelelőOrderGroupobjektumok listájává, majd pedig előállítani a visszatérési értéket. -
A kód kipróbálásához a weboldal
Group ordersmenüpontjára kell navigálni. Itt diagramokon megjelenítve láthatod az összegyűjtött információkat. Tesztelés során módosítsd a csoportok számát, és vegyél fel új megrendeléseket különböző dátumokkal korábbi feladatokban elkészítettAdd new ordersegítségével!
BEADANDÓ
Készíts egy képernyőképet a diagramokat mutató weboldalról. A képet a megoldásban f5.png néven add be. A képernyőképen látszódjon a két diagram (ehhez csökkentsd a böngészőben a nagyítást, hogy kiférjenek egy képernyőre). Ellenőrizd, hogy a Neptun kódod (az oldal aljáról) látható-e a képen! A képernyőkép szükséges feltétele a pontszám megszerzésének.
