MongoDB Collections Usage Guide - pacificnm/wiki-ai GitHub Wiki
Your MongoDB Atlas database is now fully configured with collections, indexes, and initial data. Here's how to work with the database:
Collections Created:
- ✅ Users (0 documents)
- ✅ Documents (0 documents)
- ✅ Versions (0 documents)
- ✅ Categories (4 documents - with defaults)
- ✅ Comments (0 documents)
Default Categories:
- 📁 General: General documents and notes
- 📁 Technical: Technical documentation
- 📁 Tutorials: How-to guides and tutorials
- 📁 API Documentation: API reference and documentation
# Initialize database (create collections, indexes, default data)
npm run db:init
# Check database status and counts
npm run db:status
# Make a user admin (requires Firebase UID)
npm run make:admin <firebase-uid> <email>
{
firebaseUid: String, // Firebase authentication ID
email: String, // User email (unique)
displayName: String, // User's display name
role: String, // 'admin', 'editor', 'viewer'
isActive: Boolean, // Account status
lastLogin: Date, // Last login timestamp
createdAt: Date, // Account creation
updatedAt: Date // Last update
}
// Indexes: firebaseUid (unique), email (unique), role
{
title: String, // Document title (required)
slug: String, // URL-friendly title (unique)
content: String, // Document content/body
status: String, // 'draft', 'published', 'archived'
category: ObjectId, // Reference to Category
author: ObjectId, // Reference to User
tags: [String], // Array of tags
metadata: Object, // Additional data
publishedAt: Date, // Publication date
createdAt: Date, // Creation date
updatedAt: Date // Last update
}
// Indexes: slug (unique), title (text), content (text), author, category, status, tags
{
document: ObjectId, // Reference to Document
versionNumber: Number, // Version number (1, 2, 3...)
content: String, // Content at this version
changes: String, // Change description
author: ObjectId, // Who made the changes
createdAt: Date // When version was created
}
// Indexes: document + versionNumber (compound, unique), document, author
{
name: String, // Category name (unique)
slug: String, // URL-friendly name (unique)
description: String, // Category description
color: String, // Display color (hex)
icon: String, // Icon name/class
parentCategory: ObjectId, // Reference to parent (optional)
isActive: Boolean, // Category status
sortOrder: Number, // Display order
createdAt: Date, // Creation date
updatedAt: Date // Last update
}
// Indexes: name (unique), slug (unique), parentCategory, isActive
{
document: ObjectId, // Reference to Document
author: ObjectId, // Reference to User
content: String, // Comment content
parentComment: ObjectId, // Reference to parent (for replies)
isApproved: Boolean, // Moderation status
createdAt: Date, // Creation date
updatedAt: Date // Last update
}
// Indexes: document, author, parentComment, isApproved, createdAt
import { User, Document, Version, Category, Comment } from '../models/index.js';
// In your document controller
const createDocument = async (req, res) => {
try {
const document = new Document({
title: req.body.title,
content: req.body.content,
category: req.body.categoryId,
author: req.user.id,
status: 'draft'
});
await document.save();
res.status(201).json(document);
} catch (error) {
res.status(400).json({ error: error.message });
}
};
const getDocuments = async (req, res) => {
try {
const documents = await Document
.find({ status: 'published' })
.populate('author', 'displayName email')
.populate('category', 'name color')
.sort({ publishedAt: -1 })
.limit(10);
res.json(documents);
} catch (error) {
res.status(500).json({ error: error.message });
}
};
const createUser = async (req, res) => {
try {
const user = new User({
firebaseUid: req.user.uid,
email: req.user.email,
displayName: req.user.name || req.user.email,
role: 'viewer'
});
await user.save();
res.status(201).json(user);
} catch (error) {
res.status(400).json({ error: error.message });
}
};
// Text search across title and content
const searchResults = await Document.find({
$text: { $search: "mongodb tutorial" },
status: 'published'
}).populate('author category');
// Filter by category
const techDocs = await Document.find({
status: 'published'
}).populate({
path: 'category',
match: { slug: 'technical' }
});
const versions = await Version
.find({ document: documentId })
.populate('author', 'displayName')
.sort({ versionNumber: -1 });
// Most active authors
const authorStats = await Document.aggregate([
{ $match: { status: 'published' } },
{ $group: {
_id: '$author',
documentCount: { $sum: 1 }
}},
{ $sort: { documentCount: -1 } },
{ $limit: 10 }
]);
All models include:
- Built-in validation (required fields, unique constraints)
- Custom validators (email format, slug format)
- Pre-save hooks (auto-generate slugs, update timestamps)
- Indexes for optimal query performance
Example validation error:
try {
await document.save();
} catch (error) {
if (error.name === 'ValidationError') {
// Handle validation errors
const errors = Object.values(error.errors).map(e => e.message);
return res.status(400).json({ errors });
}
// Handle other errors
res.status(500).json({ error: error.message });
}
- Use Indexes: All collections have optimal indexes for common queries
- Populate Sparingly: Only populate fields you need
-
Limit Results: Always use
.limit()
for large collections - Text Search: Use MongoDB text indexes for search functionality
- Aggregation: Use aggregation pipeline for complex analytics
- Create Controllers: Implement CRUD operations using these models
- Add Routes: Set up Express routes that use the controllers
- Test CRUD: Test creating, reading, updating, and deleting documents
- Add Authentication: Integrate with Firebase authentication middleware
- Implement Search: Use text indexes for document search functionality
Your MongoDB "tables" (collections) are now ready for use! 🚀