import { Stat } from "@/interfaces/user"; import client from "@/lib/mongodb"; const db = client.db(process.env.MONGODB_DB); export const getStatsByUser = async (id: string) => await db.collection("stats").find({ user: id }).toArray(); export const getStatsByUsers = async (ids: string[]) => await db .collection("stats") .find({ user: { $in: ids } }) .toArray(); export const getDetailedStatsByUser = async (id: string, query?: string) => { let aggregateArray: any[] = [ { $match: { user: id } }, { $sort: { "date": 1 } }, ] switch (query) { case "stats": { aggregateArray = aggregateArray.concat([{ $group: { _id: "$session", modules: { $addToSet: "$module" }, documents: { $push: "$$ROOT" }, totalCorrect: { $sum: "$score.correct" }, totalQuestions: { $sum: "$score.total" } } }, { $project: { _id: 0, hasAllModules: { $eq: [ { $size: { $setIntersection: ["$modules", ["reading", "listening", "writing", "speaking"]] } }, 4 ] }, uniqueModulesCount: { $size: "$modules" }, averageScore: { $cond: [ { $gt: ["$totalQuestions", 0] }, { $multiply: [{ $divide: ["$totalCorrect", "$totalQuestions"] }, 100] }, 0 ] }, documents: 1 } }, { $group: { _id: null, fullExams: { $sum: { $cond: ["$hasAllModules", 1, 0] } }, uniqueModules: { $sum: "$uniqueModulesCount" }, averageScore: { $avg: "$averageScore" }, allStats: { $push: "$documents" } } }, { $project: { _id: 0, fullExams: 1, uniqueModules: 1, averageScore: 1, allStats: { $reduce: { input: "$allStats", initialValue: [], in: { $concatArrays: ["$$value", "$$this"] } } } } }]) } break; case "byModule": { aggregateArray = aggregateArray.concat([{ $facet: { moduleCounts: [ { $group: { _id: { module: "$module", session: "$session" } } }, { $group: { _id: "$_id.module", count: { $count: {} } } }, { $project: { _id: 0, module: "$_id", count: "$count" } } ], allDocuments: [ { $project: { _id: 0 } } ] } }, { $project: { moduleCount: { $arrayToObject: { $map: { input: "$moduleCounts", as: "module", in: { k: "$$module.module", v: "$$module.count" } } } }, allDocs: "$allDocuments" } }]) } default: } return await db.collection("stats").aggregate(aggregateArray).toArray().then((result) => query ? result[0] : result ); }