MongoDB  >  CRUD Operations

CRUD Operations

Create New Document(s) in Collection

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// /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 & 6Choose which db and collection to connect to
Line 12Chooses which request body elements you need from frontend to push to collection
Line 15Optional checks to make sure the correct values are given from frontend
Line 29Add all the fields as a JSON array to push as document in Mongo
Line 44Insert 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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// /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 2Limit for # of items to return
Line 12-15Filters the collection if you have search and filters
Line 28Create 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).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// /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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// /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.