Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Week4/homework/ db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a data import file in your PR. Can you explain how you got your data into your db?

From the README:

Find a way to get the data in the csv file into your MongoDB database.

const { MongoClient } = require("mongodb");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You haven't included any package.json file in your changes. How should we access these third party packages?


async function connectDB() {
const client = new MongoClient("mongodb://localhost:27017");
await client.connect();
const db = client.db("databaseWeek4");
return { db, client };
}

module.exports = connectDB;
40 changes: 40 additions & 0 deletions Week4/homework/ index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Be very careful with leading or trailing whitespaces in file names, e.g. here your file is names homework/ index.js. This can cause big (and easily avoidable) issues when importing/exporting, referencing, pushing to git, and naming other files.


const connectDB = require("./db");

const {
getPopulationByCountryPerYear,
getContinentPopulationByYearAndAge
} = require("./ex1-aggregation/queries");

const setup = require("./ex2-transactions/setup");
const transfer = require("./ex2-transactions/transfer");

async function main() {
console.log("Running Setup...");
await setup();

console.log("\nRunning Transfer Transaction...");
await transfer(101, 102, 1000, "Test transfer");

console.log("\n=== Accounts After Transfer ===");
const { db, client } = await connectDB();
const accounts = await db.collection("accounts").find().toArray();
console.log(accounts);
await client.close();

console.log("\nRunning Aggregation Queries...");
const { db: db2, client: client2 } = await connectDB();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure you need to open/close your connection to the db multiple times? You could do it just once, run your operations, and then close at the end.


const agg1 = await getPopulationByCountryPerYear(db2, "Netherlands");
console.log("\nPopulation by Year for Netherlands:");
console.log(agg1);

const agg2 = await getContinentPopulationByYearAndAge(db2, 2020, "100+");
console.log("\nContinents Data for age 100+ in 2020:");
console.log(agg2);

await client2.close();
}

main();
29 changes: 29 additions & 0 deletions Week4/homework/ex1-aggregation/queries.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

async function getPopulationByCountryPerYear(db, countryName) {
return await db.collection("population").aggregate([
Copy link

@crevulus crevulus Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to change this now - just bear this in mind!

Something you may want to consider when you're working with CSV data: Spreadsheets often use Title Case for their headings (Country, Year, etc.). When we're designing databses, we don't usually use this case. We usually use lowercase or snake_case, removing any whitespace and standardising the cases of the letters.

When converting from CSV to database columns you might want to consider your naming conventions. But you do not need to do that for this exercise - jsut something to remember for the future as not following naming conventions will make it harder/less intuitive for other people to work with your databases.

{ $match: { Country: countryName } },
{
$group: {
_id: "$Year",
countPopulation: { $sum: { $add: ["$M", "$F"] } }
}
},
{ $sort: { _id: 1 } }
]).toArray();
}

async function getContinentPopulationByYearAndAge(db, year, age) {
return await db.collection("population").aggregate([
{ $match: { Year: year, Age: age } },
{
$addFields: {
TotalPopulation: { $add: ["$M", "$F"] }
}
}
]).toArray();
}

module.exports = {
getPopulationByCountryPerYear,
getContinentPopulationByYearAndAge
};
32 changes: 32 additions & 0 deletions Week4/homework/ex2-transactions/setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

const connectDB = require("../db");

async function setup() {
const { db, client } = await connectDB();
const accounts = db.collection("accounts");

await accounts.deleteMany({});

await accounts.insertMany([
{
account_number: 101,
balance: 5000,
account_changes: []
},
{
account_number: 102,
balance: 2000,
account_changes: []
},
{
account_number: 103,
balance: 8000,
account_changes: []
}
]);

console.log("Setup done: accounts created.");
await client.close();
}

module.exports = setup;
66 changes: 66 additions & 0 deletions Week4/homework/ex2-transactions/transfer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@

const connectDB = require("../db");

async function transfer(fromAcc, toAcc, amount, remark) {
const { db, client } = await connectDB();
const accounts = db.collection("accounts");

const session = client.startSession();

try {
await session.withTransaction(async () => {
const from = await accounts.findOne({ account_number: fromAcc }, { session });
const to = await accounts.findOne({ account_number: toAcc }, { session });

if (!from || !to) throw new Error("Account not found.");
if (from.balance < amount) throw new Error("Insufficient funds.");

const nextChangeFrom =
(from.account_changes.at(-1)?.change_number || 0) + 1;

const nextChangeTo =
(to.account_changes.at(-1)?.change_number || 0) + 1;

await accounts.updateOne(
{ account_number: fromAcc },
{
$inc: { balance: -amount },
$push: {
account_changes: {
change_number: nextChangeFrom,
amount: -amount,
changed_date: new Date(),
remark
}
}
},
{ session }
);

await accounts.updateOne(
{ account_number: toAcc },
{
$inc: { balance: amount },
$push: {
account_changes: {
change_number: nextChangeTo,
amount: amount,
changed_date: new Date(),
remark
}
}
},
{ session }
);
});

console.log(`Transfer of ${amount} from ${fromAcc} to ${toAcc} completed.`);
} catch (err) {
console.log("Transaction failed:", err.message);
} finally {
await session.endSession();
await client.close();
}
}

module.exports = transfer;