\section{Aggregációk} \begin{frame}{Mi az aggregáció?} \begin{block}{Aggregált lekérdezések} Adatok összesítése és elemzése számítások segítségével \end{block} \begin{block}{Prisma aggregáció műveletek} \begin{itemize} \item \texttt{count} - Rekordok számlálása \item \texttt{avg} - Átlag számítás \item \texttt{sum} - Összegzés \item \texttt{min} - Minimum érték \item \texttt{max} - Maximum érték \item \texttt{groupBy} - Csoportosítás \end{itemize} \end{block} \end{frame} \begin{frame}[fragile]{Példa séma} \begin{block}{schema.prisma} \begin{lstlisting}[language=JavaScript] model Product { id Int @id @default(autoincrement()) name String price Float stock Int categoryId Int category Category @relation(fields: [categoryId], references: [id]) createdAt DateTime @default(now()) } model Category { id Int @id @default(autoincrement()) name String products Product[] } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Count - Számlálás} \begin{block}{Összes rekord számolása} \begin{lstlisting}[language=JavaScript] const prisma = require('./prisma'); async function countProducts() { const count = await prisma.product.count(); console.log(`Összes termék: ${count}`); } // Szűrt számlálás async function countExpensiveProducts() { const count = await prisma.product.count({ where: { price: { gt: 1000 } } }); console.log(`Drága termékek: ${count}`); } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Aggregate - Alapok} \begin{block}{Egyszerű aggregáció} \begin{lstlisting}[language=JavaScript] async function getProductStats() { const stats = await prisma.product.aggregate({ _count: true, _avg: {price: true}, _sum: {stock: true}, _min: {price: true}, _max: {price: true} }); console.log(stats); } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Aggregate - Eredmény} \begin{block}{Visszatérési érték példa} \begin{lstlisting}[language=JavaScript] { _count: 150, _avg: { price: 1250.50 }, _sum: { stock: 5420 }, _min: { price: 99.99 }, _max: { price: 9999.99 }} \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Aggregate - Szűréssel} \begin{block}{Where feltétellel} \begin{lstlisting}[language=JavaScript] async function getCategoryStats(categoryId) { const stats = await prisma.product.aggregate({ where: { categoryId: categoryId }, _count: true, _avg: { price: true }, _sum: { stock: true } }); return stats; } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{GroupBy - Csoportosítás} \begin{block}{Kategóriánkénti csoportosítás} \begin{lstlisting}[language=JavaScript] async function groupByCategory() { const result = await prisma.product.groupBy({ by: ['categoryId'], _count: true, _avg: { price: true }, _sum: { stock: true } }); return result; } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{GroupBy - Eredmény} \begin{block}{Csoportosított adatok} \begin{lstlisting}[language=JavaScript] [ { categoryId: 1, _count: 45, _avg: { price: 599.99 }, _sum: { stock: 1200 } }, { categoryId: 2, _count: 67, _avg: { price: 1299.50 }, _sum: { stock: 890 } } ] \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{GroupBy - Having feltétel} \begin{block}{Szűrés az aggregált eredményen} \begin{lstlisting}[language=JavaScript] async function getCategoriesWithHighAvgPrice() { const result = await prisma.product.groupBy({ by: ['categoryId'], _avg: {price: true}, _count: true, having: { price: { _avg: {gt: 1000} } } }); return result; } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{GroupBy - Rendezés} \begin{block}{OrderBy aggregált mezőn} \begin{lstlisting}[language=JavaScript] async function getCategoriesOrderedByAvgPrice() { const result = await prisma.product.groupBy({ by: ['categoryId'], _avg: {price: true}, _count: true, orderBy: { _avg: {price: 'desc'} } }); return result; } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Több mező szerinti csoportosítás} \begin{block}{Összetett GroupBy} \begin{lstlisting}[language=JavaScript] // Bővített séma szükséges: inStock boolean mező async function groupByCategoryAndStock() { const result = await prisma.product.groupBy({ by: ['categoryId', 'inStock'], _count: true, _avg: {price: true}, orderBy: {categoryId: 'asc'} }); return result; } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Relációk és aggregáció} \begin{block}{Kapcsolt táblák aggregálása} \begin{lstlisting}[language=JavaScript] async function getCategoriesWithProductCount() { const categories = await prisma.category.findMany({ include: { _count: { select: { products: true } } } }); // Eredmény: [{ id: 1, name: 'Electronics', // _count: { products: 45 } }, ...] return categories; } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Relációs szűrés aggregációval} \begin{block}{Több mint N termékkel rendelkező kategóriák} \begin{lstlisting}[language=JavaScript] async function getCategoriesWithManyProducts() { const categories = await prisma.category.findMany({ where: { products: {some: {}} }, include: { _count: { select: {products: true} } }}); // Csak azok a kategóriák, amikhez van termék return categories.filter(c => c._count.products > 10); } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Express API - Statisztika endpoint} \begin{block}{Aggregált adatok REST API-n keresztül} \begin{lstlisting}[language=JavaScript] const express = require('express'); const prisma = require('./prisma'); const app = express(); app.get('/api/stats/products', async (req, res) => { const stats = await prisma.product.aggregate({ _count: true, _avg: { price: true }, _sum: { stock: true }, _min: { price: true }, _max: { price: true } }); res.json(stats); }); \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Express API - Csoportosított adatok} \begin{block}{GroupBy endpoint} \begin{lstlisting}[language=JavaScript] app.get('/api/stats/by-category', async (req, res) => { const stats = await prisma.product.groupBy({ by: ['categoryId'], _count: true, _avg: { price: true }, _sum: { stock: true }, orderBy: { _avg: { price: 'desc' } } }); res.json(stats); }); \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Egyedi aggregáció - Raw Query} \begin{block}{SQL használata komplex esetekben} \begin{lstlisting}[language=JavaScript] async function customAggregation() { const result = await prisma.$queryRaw` SELECT "categoryId", COUNT(*) as count, AVG(price) as avgPrice, SUM(stock) as totalStock FROM "Product" WHERE price > 100 GROUP BY "categoryId" HAVING AVG(price) > 500 ORDER BY avgPrice DESC `; return result; } \end{lstlisting} \end{block} \end{frame} \begin{frame}{Aggregáció - Best Practices} \begin{block}{Ajánlások} \begin{itemize} \item Használj \texttt{select} és \texttt{where} feltételeket a teljesítmény növelésére \item GroupBy esetén mindig gondold át az indexelést \item Nagy adathalmazoknál fontold meg a lapozást \item Komplex esetekben raw SQL lehet hatékonyabb \item Cacheld az aggregált eredményeket, ha ritkán változnak \item Használj \texttt{having} feltételt az aggregált adatok szűrésére \end{itemize} \end{block} \end{frame} \begin{frame}{Összefoglalás} \begin{block}{Prisma aggregációk} \begin{itemize} \item \textbf{count} - Egyszerű és szűrt számlálás \item \textbf{aggregate} - Átlag, összeg, min, max számítások \item \textbf{groupBy} - Csoportosítás és aggregálás \item \textbf{having} - Szűrés aggregált eredményen \item \textbf{orderBy} - Rendezés aggregált mezők szerint \item \textbf{\_count} - Kapcsolt rekordok számlálása \end{itemize} \end{block} \end{frame}