MongoDB > CRUD Operations
CRUD Operations
Create New Document(s) in Collection
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657// /src/pages/api/index.js import clientPromise from '@/lib/mongodb'; export default async function handler(req, res) { const client = await clientPromise; const db = client.db('my_app'); // Add DB Name const collection = db.collection('trades'); // Add Collection Name if (req.method === 'POST') { const payload = Array.isArray(req.body) ? req.body : [req.body]; // Get body of payload passed const docs = []; for (const t of payload) { // Get values from body const { symbol, name, buyPrice, sellPrice, shares, leverage, boughtAt, soldAt } = t || {}; // Check if values are correct if (!symbol || buyPrice == null || shares == null || leverage == null) { return res.status(400).json({ error: 'symbol, buyPrice, shares, leverage are required' }); } const levNum = Number(leverage); if (!Number.isFinite(levNum) || levNum <= 0) { return res.status(400).json({ error: 'leverage must be a positive number' }); } const hasSoldDate = !!soldAt; const hasSellPrice = sellPrice != null && sellPrice !== ''; if (hasSoldDate !== hasSellPrice) { return res.status(400).json({ error: 'soldAt and sellPrice must be provided together or both omitted' }); } // Push to docs JSON variable docs.push({ symbol, name: name || symbol, buyPrice: Number(buyPrice), sellPrice: hasSellPrice ? Number(sellPrice) : null, shares: Number(shares), leverage: levNum, boughtAt: boughtAt ? new Date(boughtAt) : null, soldAt: hasSoldDate ? new Date(soldAt) : null, createdAt: new Date(), lastModified: new Date(), }); } // Create new collection(s) if (docs.length === 1) { const r = await collection.insertOne(docs[0]); return res.status(201).json({ _id: r.insertedId, ...docs[0] }); } else { const r = await collection.insertMany(docs); return res.status(201).json({ insertedCount: r.insertedCount, ids: Object.values(r.insertedIds) }); } } res.setHeader('Allow', ['GET', 'POST']); res.status(405).end('Method Not Allowed'); }
The code above is messy, but the table below explains which comments to look for.
Line 5 & 6 | Choose which db and collection to connect to |
Line 12 | Chooses which request body elements you need from frontend to push to collection |
Line 15 | Optional checks to make sure the correct values are given from frontend |
Line 29 | Add all the fields as a JSON array to push as document in Mongo |
Line 44 | Insert JSON arrays in mongo to store as documents in collection |
Fetch Document(s) in Collection
Add this if statement to the same file as the Create, above the POST if statement.
12345678910111213141516171819202122232425262728293031323334353637// /src/pages/api/index.js if (req.method === 'GET') { // Limit for # of items to return const page = Math.max(1, parseInt(req.query.page || '1', 10)); const pageSize = Math.min(50, Math.max(1, parseInt(req.query.pageSize || '10', 10))); const skip = (page - 1) * pageSize; // Search Params const q = (req.query.q || '').trim(); const legacyName = (req.query.name || '').trim(); const status = (req.query.status || '').trim(); /** * Search for Name or Symbol * Filter Open, Closed Status */ const and = []; if (q) { and.push({ $or: [ { name: { $regex: q, $options: 'i' } }, { symbol: { $regex: q, $options: 'i' } }, ]}); } else if (legacyName) { and.push({ name: { $regex: legacyName, $options: 'i' } }); } if (status === 'open') and.push({ soldAt: { $in: [null, undefined] } }); if (status === 'closed') and.push({ soldAt: { $ne: null } }); // Create Filter and Find Docuemnts in Collection to the Limit Set const filter = and.length ? { $and: and } : {}; const [items, total] = await Promise.all([ collection.find(filter).sort({ createdAt: -1 }).skip(skip).limit(pageSize).toArray(), collection.countDocuments(filter), ]); return res.status(200).json({ items, total, page, pageSize, q: q || legacyName, status }); }
The code above is messy, but the table below explains which comments to look for.
Line 2 | Limit for # of items to return |
Line 12-15 | Filters the collection if you have search and filters |
Line 28 | Create filter and searches collection |
Update or Delete Single Document in Collection
The reason we have update and delete in the same document is because we are modifing a specific document which is found through a unique key (Object ID).
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960// /src/pages/api/[id].js import clientPromise from '@/lib/mongodb'; import { ObjectId } from 'mongodb'; export default async function handler(req, res) { const { id } = req.query; if (!id || !ObjectId.isValid(id)) return res.status(400).json({ error: 'Invalid id' }); const client = await clientPromise; const db = client.db('my_app'); // Add DB Name const collection = db.collection('trades'); // Add Collection Name const _id = new ObjectId(id); if (req.method === 'PUT') { const { buyPrice, sellPrice, shares, leverage, boughtAt, soldAt } = req.body || {}; if (buyPrice == null || shares == null || leverage == null) { return res.status(400).json({ error: 'buyPrice, shares, and leverage are required' }); } const levNum = Number(leverage); if (!Number.isFinite(levNum) || levNum <= 0) { return res.status(400).json({ error: 'leverage must be a positive number' }); } const existing = await collection.findOne({ _id }); if (!existing) return res.status(404).json({ error: 'Not found' }); // both-or-none rule const hasSoldDate = !!soldAt; const hasSellPrice = sellPrice != null && sellPrice !== ''; if (hasSoldDate !== hasSellPrice) { return res.status(400).json({ error: 'soldAt and sellPrice must be provided together or both omitted' }); } const update = { buyPrice: Number(buyPrice), shares: Number(shares), leverage: levNum, boughtAt: boughtAt ? new Date(boughtAt) : null, lastModified: new Date(), }; if (hasSoldDate) { update.soldAt = new Date(soldAt); update.sellPrice = Number(sellPrice); } else { update.soldAt = null; update.sellPrice = null; } const result = await collection.updateOne({ _id }, { $set: update }); return res.status(200).json({ ok: result.modifiedCount === 1 }); } if (req.method === 'DELETE') { const r = await collection.deleteOne({ _id }); return res.status(200).json({ ok: r.deletedCount === 1 }); } res.setHeader('Allow', ['PUT', 'DELETE']); res.status(405).end('Method Not Allowed'); }
Delete Multiple Documents in Collection
123456789101112131415161718192021222324252627282930313233343536373839404142// /src/pages/api/bulk-delete.js import clientPromise from '@/lib/mongodb'; import { ObjectId } from 'mongodb'; export default async function handler(req, res) { if (req.method !== 'POST') { res.setHeader('Allow', ['POST']); return res.status(405).json({ error: 'Method Not Allowed' }); } try { const { ids } = req.body || {}; if (!Array.isArray(ids) || ids.length === 0) { return res.status(400).json({ error: 'ids array required' }); } // Convert to ObjectId, skip invalids const objectIds = ids .map((id) => { try { return new ObjectId(id); } catch { return null; } }) .filter(Boolean); if (objectIds.length === 0) { return res.status(400).json({ error: 'No valid ids' }); } const client = await clientPromise; const db = client.db('my_app'); // Add DB Name const result = await db.collection('trades').deleteMany({ _id: { $in: objectIds } }); // Add Collection Name return res.status(200).json({ ok: true, deletedCount: result.deletedCount || 0, requested: ids.length, processed: objectIds.length, }); } catch (e) { console.error('bulk-delete error', e); return res.status(500).json({ error: 'Internal Server Error' }); } }
🙌 Congrats, you've setup the API calls that you would need to make in your app to modify your Mongo database.