Files
GKNB_MSTM071/Backend_ppt/Database/aggregates.tex
T
2026-02-17 21:17:42 +01:00

371 lines
9.1 KiB
TeX

\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 - Product}
\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())
}
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Példa séma (folyt.)}
\begin{block}{schema.prisma - Category}
\begin{lstlisting}[language=JavaScript]
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}`);
}
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Count - Számlálás (szűréssel)}
\begin{block}{Szűrt számlálás}
\begin{lstlisting}[language=JavaScript]
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}
});
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Aggregate - Alapok (folyt.)}
\begin{block}{Egyszerű aggregáció}
\begin{lstlisting}[language=JavaScript]
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}