MongoDB Mastery: Setup and Getting Started - Part 1

Learn how to set up MongoDB, understand its architecture, and perform basic operations with practical examples using C# and .NET.

FSI
Full Stack Insights
12 min read...

MongoDB Mastery: Setup and Getting Started - Part 1

Introduction

MongoDB is a powerful NoSQL document database that stores data in flexible, JSON-like documents. Unlike traditional relational databases, MongoDB allows you to store data without predefined schemas, making it perfect for applications with evolving data structures.

This multipart series will take you from MongoDB beginner to advanced user. In this first part, we'll cover installation, basic concepts, and getting started with your first database operations using C# and the MongoDB .NET driver.

📚 Series Overview:

  • Part 1: Setup and Getting Started (This article)
  • Part 2: CRUD Operations with Real-World Examples
  • Part 3: Advanced Features and Performance Optimization

Section 1: Understanding MongoDB

What is MongoDB?

MongoDB is a document-oriented NoSQL database designed for ease of development and scaling. Key features include:

  • Document Model: Data stored as BSON (Binary JSON) documents
  • Dynamic Schema: No fixed schema required
  • Horizontal Scaling: Built-in sharding for distributed deployments
  • Rich Query Language: Powerful querying capabilities
  • Indexing: Multiple indexing strategies for performance
  • Aggregation Framework: Advanced data processing pipelines

When to Use MongoDB

MongoDB excels in scenarios like:

  • Applications with frequently changing schemas
  • Real-time analytics and logging
  • Content management systems
  • Mobile and social applications
  • IoT data storage

Section 2: Installation and Setup

Choose the option that best fits your needs. For beginners, we recommend MongoDB Atlas (no installation required). For local development, Docker is the easiest. For production-like setups, use direct installation.

Option 1: MongoDB Atlas (Cloud - Recommended for Beginners)

MongoDB Atlas is a fully managed cloud database. It's free to get started and requires no installation.

  1. Go to MongoDB Atlas and create a free account.
  2. Create a new cluster (free tier is available - M0 Sandbox).
  3. Set up a database user and whitelist your IP address.
  4. Get your connection string from the "Connect" button.

Example connection string:

mongodb+srv://username:password@cluster0.xxxxx.mongodb.net/?retryWrites=true&w=majority

💡 Pro Tip: Replace username and password with your actual credentials. The cluster URL will be unique to your account.

Option 2: Docker (Containerized - Easy Local Setup)

If you have Docker installed, this is the quickest way to run MongoDB locally.

# Pull and run MongoDB in a container
docker run -d -p 27017:27017 --name mongodb mongo:latest

# Verify it's running
docker ps

# To stop: docker stop mongodb
# To start again: docker start mongodb
# To remove: docker rm mongodb

Connection string: mongodb://localhost:27017

⚠️ Note: If you don't have Docker, install it from docker.com.

Option 3: Direct Installation (Traditional)

Windows Installation

# Download and install MongoDB
# Visit https://www.mongodb.com/try/download/community
# Or use Chocolatey
choco install mongodb

Linux Installation (Ubuntu/Debian)

# Import the public key
wget -qO - https://www.mongodb.org/static/pgp/server-7.0.asc | sudo apt-key add -

# Create list file
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list

# Update and install
sudo apt-get update
sudo apt-get install -y mongodb-org

Starting MongoDB

For direct installation:

Windows (as Service)

# Start MongoDB service
net start MongoDB

# Or run manually
"C:\Program Files\MongoDB\Server\7.0\bin\mongod.exe"

Linux

# Start MongoDB
sudo systemctl start mongod

# Enable auto-start
sudo systemctl enable mongod

# Check status
sudo systemctl status mongod

MongoDB Compass (GUI Tool)

Download MongoDB Compass from the official website for a graphical interface to manage your databases.

# Windows
choco install mongodb-compass

For Atlas, connect using your Atlas connection string. For local installations (Docker or direct), use mongodb://localhost:27017.

Section 3: Setting Up C# Project

Creating a New .NET Project

# Create a new console application
dotnet new console -n MongoDBExample
cd MongoDBExample

# Create a new ASP.NET Core Web API (for web applications)
dotnet new webapi -n MongoDBWebAPI
cd MongoDBWebAPI

Installing MongoDB .NET Driver

# Install MongoDB driver
dotnet add package MongoDB.Driver

# Optional: Install BSON library for additional features
dotnet add package MongoDB.Bson

Project Configuration

Create appsettings.json with your chosen connection string:

For MongoDB Atlas:

{
  "MongoDB": {
    "ConnectionString": "mongodb+srv://username:password@cluster0.xxxxx.mongodb.net/?retryWrites=true&w=majority",
    "DatabaseName": "BlogDB"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}

For Docker/Local Installation:

{
  "MongoDB": {
    "ConnectionString": "mongodb://localhost:27017",
    "DatabaseName": "BlogDB"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}

🔑 Security Note: Never commit your actual connection string with credentials to version control. Use environment variables or Azure Key Vault for production.


## Section 4: Basic MongoDB Concepts

### Documents and Collections

- **Document**: A record in MongoDB (similar to a row in SQL)
- **Collection**: A group of documents (similar to a table in SQL)
- **Database**: A container for collections

Example document:
```json
{
  "_id": ObjectId("507f1f77bcf86cd799439011"),
  "name": "John Doe",
  "email": "john@example.com",
  "age": 30,
  "address": {
    "street": "123 Main St",
    "city": "New York",
    "zipCode": "10001"
  },
  "tags": ["developer", "mongodb"]
}

Data Types

MongoDB supports various data types:

  • String, Integer, Boolean, Double
  • ObjectId (unique identifier)
  • DateTime, Timestamp
  • Arrays, Objects
  • Binary Data, Regular Expressions

Section 5: Connecting to MongoDB in C#

Basic Connection

using MongoDB.Driver;
using Microsoft.Extensions.Configuration;

namespace MongoDBExample
{
    public class DatabaseContext
    {
        private readonly IMongoDatabase _database;

        public DatabaseContext(IConfiguration configuration)
        {
            var connectionString = configuration["MongoDB:ConnectionString"];
            var databaseName = configuration["MongoDB:DatabaseName"];

            var client = new MongoClient(connectionString);
            _database = client.GetDatabase(databaseName);
        }

        public IMongoCollection<Post> Posts => _database.GetCollection<Post>("posts");
        public IMongoCollection<Category> Categories => _database.GetCollection<Category>("categories");
    }

    // Models
    public class Post
    {
        public ObjectId Id { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }
        public string Author { get; set; }
        public List<string> Tags { get; set; } = new List<string>();
        public bool Published { get; set; }
        public DateTime CreatedAt { get; set; }
        public int Views { get; set; }
    }

    public class Category
    {
        public ObjectId Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public DateTime CreatedAt { get; set; }
    }
}

Dependency Injection Setup (ASP.NET Core)

// Program.cs
using MongoDBExample;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddSingleton<DatabaseContext>();

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

Section 6: Your First Database Operations

Creating Documents

using MongoDB.Driver;
using MongoDB.Bson;

namespace MongoDBExample.Services
{
    public class PostService
    {
        private readonly IMongoCollection<Post> _posts;

        public PostService(DatabaseContext context)
        {
            _posts = context.Posts;
        }

        public async Task<Post> CreatePost(Post post)
        {
            post.CreatedAt = DateTime.UtcNow;
            post.Views = 0;
            await _posts.InsertOneAsync(post);
            return post;
        }

        public async Task<List<Post>> GetAllPosts()
        {
            return await _posts.Find(_ => true).ToListAsync();
        }

        public async Task<Post> GetPostById(string id)
        {
            var objectId = ObjectId.Parse(id);
            return await _posts.Find(p => p.Id == objectId).FirstOrDefaultAsync();
        }

        public async Task<List<Post>> GetPublishedPosts()
        {
            return await _posts.Find(p => p.Published == true).ToListAsync();
        }

        public async Task<List<Post>> GetPostsByAuthor(string author)
        {
            return await _posts.Find(p => p.Author == author).ToListAsync();
        }

        public async Task<List<Post>> GetPostsByTag(string tag)
        {
            return await _posts.Find(p => p.Tags.Contains(tag)).ToListAsync();
        }

        public async Task<bool> UpdatePost(string id, Post updatedPost)
        {
            var objectId = ObjectId.Parse(id);
            var result = await _posts.ReplaceOneAsync(p => p.Id == objectId, updatedPost);
            return result.ModifiedCount > 0;
        }

        public async Task<bool> DeletePost(string id)
        {
            var objectId = ObjectId.Parse(id);
            var result = await _posts.DeleteOneAsync(p => p.Id == objectId);
            return result.DeletedCount > 0;
        }

        public async Task IncrementViews(string id)
        {
            var objectId = ObjectId.Parse(id);
            var update = Builders<Post>.Update.Inc(p => p.Views, 1);
            await _posts.UpdateOneAsync(p => p.Id == objectId, update);
        }
    }
}

Sample Usage

// Program.cs (Console App)
using MongoDBExample;
using MongoDBExample.Services;
using Microsoft.Extensions.Configuration;

class Program
{
    static async Task Main(string[] args)
    {
        var configuration = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .Build();

        var context = new DatabaseContext(configuration);
        var postService = new PostService(context);

        // Create sample posts
        var samplePosts = new List<Post>
        {
            new Post
            {
                Title = "Getting Started with MongoDB",
                Content = "MongoDB is a powerful NoSQL database...",
                Author = "John Doe",
                Tags = new List<string> { "mongodb", "nosql", "database" },
                Published = true
            },
            new Post
            {
                Title = "Advanced MongoDB Queries",
                Content = "Learn about complex queries in MongoDB...",
                Author = "Jane Smith",
                Tags = new List<string> { "mongodb", "queries", "advanced" },
                Published = false
            }
        };

        foreach (var post in samplePosts)
        {
            await postService.CreatePost(post);
            Console.WriteLine($"Created post: {post.Title}");
        }

        // Get all published posts
        var publishedPosts = await postService.GetPublishedPosts();
        Console.WriteLine($"Found {publishedPosts.Count} published posts");

        // Get posts by author
        var johnPosts = await postService.GetPostsByAuthor("John Doe");
        Console.WriteLine($"John Doe has {johnPosts.Count} posts");

        // Get posts by tag
        var mongoPosts = await postService.GetPostsByTag("mongodb");
        Console.WriteLine($"Found {mongoPosts.Count} posts tagged with 'mongodb'");
    }
}

Section 7: Real-World Example - Blog Management System

Let's create a complete blog management system with categories and posts.

Enhanced Models

// Models/Post.cs
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;

namespace MongoDBExample.Models
{
    public class Post
    {
        [BsonId]
        [BsonRepresentation(BsonType.ObjectId)]
        public string Id { get; set; }

        [BsonElement("title")]
        public string Title { get; set; }

        [BsonElement("content")]
        public string Content { get; set; }

        [BsonElement("excerpt")]
        public string Excerpt { get; set; }

        [BsonElement("author")]
        public string Author { get; set; }

        [BsonElement("categoryId")]
        [BsonRepresentation(BsonType.ObjectId)]
        public string CategoryId { get; set; }

        [BsonElement("tags")]
        public List<string> Tags { get; set; } = new List<string>();

        [BsonElement("published")]
        public bool Published { get; set; }

        [BsonElement("createdAt")]
        [BsonDateTimeOptions(Kind = DateTimeKind.Utc)]
        public DateTime CreatedAt { get; set; }

        [BsonElement("updatedAt")]
        [BsonDateTimeOptions(Kind = DateTimeKind.Utc)]
        public DateTime? UpdatedAt { get; set; }

        [BsonElement("views")]
        public int Views { get; set; }

        [BsonElement("likes")]
        public int Likes { get; set; }

        [BsonElement("comments")]
        public List<Comment> Comments { get; set; } = new List<Comment>();
    }

    public class Comment
    {
        [BsonElement("author")]
        public string Author { get; set; }

        [BsonElement("content")]
        public string Content { get; set; }

        [BsonElement("createdAt")]
        [BsonDateTimeOptions(Kind = DateTimeKind.Utc)]
        public DateTime CreatedAt { get; set; }
    }
}

// Models/Category.cs
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;

namespace MongoDBExample.Models
{
    public class Category
    {
        [BsonId]
        [BsonRepresentation(BsonType.ObjectId)]
        public string Id { get; set; }

        [BsonElement("name")]
        public string Name { get; set; }

        [BsonElement("slug")]
        public string Slug { get; set; }

        [BsonElement("description")]
        public string Description { get; set; }

        [BsonElement("createdAt")]
        [BsonDateTimeOptions(Kind = DateTimeKind.Utc)]
        public DateTime CreatedAt { get; set; }

        [BsonElement("postCount")]
        public int PostCount { get; set; }
    }
}

Database Context

// Data/DatabaseContext.cs
using MongoDB.Driver;
using Microsoft.Extensions.Configuration;
using MongoDBExample.Models;

namespace MongoDBExample.Data
{
    public class DatabaseContext
    {
        private readonly IMongoDatabase _database;

        public DatabaseContext(IConfiguration configuration)
        {
            var connectionString = configuration["MongoDB:ConnectionString"];
            var databaseName = configuration["MongoDB:DatabaseName"];

            var client = new MongoClient(connectionString);
            _database = client.GetDatabase(databaseName);
        }

        public IMongoCollection<Post> Posts => _database.GetCollection<Post>("posts");
        public IMongoCollection<Category> Categories => _database.GetCollection<Category>("categories");
    }
}

Services

// Services/BlogService.cs
using MongoDB.Driver;
using MongoDBExample.Data;
using MongoDBExample.Models;
using MongoDB.Bson;

namespace MongoDBExample.Services
{
    public class BlogService
    {
        private readonly IMongoCollection<Post> _posts;
        private readonly IMongoCollection<Category> _categories;

        public BlogService(DatabaseContext context)
        {
            _posts = context.Posts;
            _categories = context.Categories;
        }

        // Post operations
        public async Task<Post> CreatePost(Post post)
        {
            post.CreatedAt = DateTime.UtcNow;
            post.Views = 0;
            post.Likes = 0;
            await _posts.InsertOneAsync(post);
            return post;
        }

        public async Task<List<Post>> GetPublishedPosts()
        {
            return await _posts.Find(p => p.Published).SortByDescending(p => p.CreatedAt).ToListAsync();
        }

        public async Task<Post> GetPostById(string id)
        {
            return await _posts.Find(p => p.Id == id).FirstOrDefaultAsync();
        }

        public async Task<List<Post>> GetPostsByCategory(string categoryId)
        {
            return await _posts.Find(p => p.CategoryId == categoryId && p.Published)
                             .SortByDescending(p => p.CreatedAt)
                             .ToListAsync();
        }

        public async Task<List<Post>> GetPostsByTag(string tag)
        {
            return await _posts.Find(p => p.Tags.Contains(tag) && p.Published)
                             .SortByDescending(p => p.CreatedAt)
                             .ToListAsync();
        }

        public async Task<bool> UpdatePost(string id, Post updatedPost)
        {
            updatedPost.UpdatedAt = DateTime.UtcNow;
            var result = await _posts.ReplaceOneAsync(p => p.Id == id, updatedPost);
            return result.ModifiedCount > 0;
        }

        public async Task<bool> DeletePost(string id)
        {
            var result = await _posts.DeleteOneAsync(p => p.Id == id);
            return result.DeletedCount > 0;
        }

        public async Task IncrementViews(string id)
        {
            var update = Builders<Post>.Update.Inc(p => p.Views, 1);
            await _posts.UpdateOneAsync(p => p.Id == id, update);
        }

        public async Task AddComment(string postId, Comment comment)
        {
            comment.CreatedAt = DateTime.UtcNow;
            var update = Builders<Post>.Update.Push(p => p.Comments, comment);
            await _posts.UpdateOneAsync(p => p.Id == postId, update);
        }

        // Category operations
        public async Task<Category> CreateCategory(Category category)
        {
            category.CreatedAt = DateTime.UtcNow;
            category.PostCount = 0;
            await _categories.InsertOneAsync(category);
            return category;
        }

        public async Task<List<Category>> GetAllCategories()
        {
            return await _categories.Find(_ => true).SortBy(c => c.Name).ToListAsync();
        }

        public async Task<Category> GetCategoryById(string id)
        {
            return await _categories.Find(c => c.Id == id).FirstOrDefaultAsync();
        }

        public async Task UpdatePostCount(string categoryId)
        {
            var postCount = await _posts.CountDocumentsAsync(p => p.CategoryId == categoryId && p.Published);
            var update = Builders<Category>.Update.Set(c => c.PostCount, (int)postCount);
            await _categories.UpdateOneAsync(c => c.Id == categoryId, update);
        }
    }
}

API Controller (ASP.NET Core)

// Controllers/BlogController.cs
using Microsoft.AspNetCore.Mvc;
using MongoDBExample.Services;
using MongoDBExample.Models;

namespace MongoDBExample.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class BlogController : ControllerBase
    {
        private readonly BlogService _blogService;

        public BlogController(BlogService blogService)
        {
            _blogService = blogService;
        }

        // GET: api/blog/posts
        [HttpGet("posts")]
        public async Task<ActionResult<List<Post>>> GetPublishedPosts()
        {
            var posts = await _blogService.GetPublishedPosts();
            return Ok(posts);
        }

        // GET: api/blog/posts/{id}
        [HttpGet("posts/{id}")]
        public async Task<ActionResult<Post>> GetPost(string id)
        {
            var post = await _blogService.GetPostById(id);
            if (post == null)
                return NotFound();

            await _blogService.IncrementViews(id);
            return Ok(post);
        }

        // POST: api/blog/posts
        [HttpPost("posts")]
        public async Task<ActionResult<Post>> CreatePost(Post post)
        {
            var createdPost = await _blogService.CreatePost(post);
            return CreatedAtAction(nameof(GetPost), new { id = createdPost.Id }, createdPost);
        }

        // PUT: api/blog/posts/{id}
        [HttpPut("posts/{id}")]
        public async Task<IActionResult> UpdatePost(string id, Post post)
        {
            var updated = await _blogService.UpdatePost(id, post);
            if (!updated)
                return NotFound();
            return NoContent();
        }

        // DELETE: api/blog/posts/{id}
        [HttpDelete("posts/{id}")]
        public async Task<IActionResult> DeletePost(string id)
        {
            var deleted = await _blogService.DeletePost(id);
            if (!deleted)
                return NotFound();
            return NoContent();
        }

        // POST: api/blog/posts/{id}/comments
        [HttpPost("posts/{id}/comments")]
        public async Task<IActionResult> AddComment(string id, Comment comment)
        {
            await _blogService.AddComment(id, comment);
            return Ok();
        }

        // GET: api/blog/categories
        [HttpGet("categories")]
        public async Task<ActionResult<List<Category>>> GetCategories()
        {
            var categories = await _blogService.GetAllCategories();
            return Ok(categories);
        }

        // GET: api/blog/categories/{id}/posts
        [HttpGet("categories/{id}/posts")]
        public async Task<ActionResult<List<Post>>> GetPostsByCategory(string id)
        {
            var posts = await _blogService.GetPostsByCategory(id);
            return Ok(posts);
        }
    }
}

Conclusion

In this first part, we've covered:

  • MongoDB installation and setup
  • Setting up C# projects with MongoDB .NET driver
  • Basic concepts (documents, collections, databases)
  • Connecting to MongoDB programmatically
  • Basic CRUD operations
  • A real-world blog management system example

In the next part, we'll dive deeper into advanced CRUD operations, complex queries, indexing, and build a complete e-commerce product catalog system.

🚀 Next Steps:

  • Experiment with the code examples above
  • Try creating your own collections and documents
  • Explore MongoDB Compass for visual data management
  • Stay tuned for Part 2: Advanced CRUD Operations with Real-World Examples

This is Part 1 of our MongoDB Mastery series. Read Part 2: CRUD Operations with Real-World Examples | Read Part 3: Advanced Features

Share this article:

Related Articles

FSI

Full Stack Insights

Software Engineer

Passionate about software development, architecture, and sharing knowledge with the community.