MongoDB is a popular document-oriented NoSQL database that stores data in flexible, JSON-like documents. This guide covers installing the Countries States Cities database in MongoDB using the provided BSON dump files.
MongoDB installation typically takes 2-4 minutes and requires approximately 180MB of disk space.

Prerequisites

Before starting, ensure you have:
  • MongoDB 4.0+ installed (MongoDB 5.0+ recommended)
  • MongoDB server running on your system
  • At least 300MB free disk space
  • Downloaded the mongodb-dump/world-mongodb-dump.tar.gz file from our GitHub repository
MongoDB uses BSON (Binary JSON) format rather than SQL, so the installation process differs from relational databases.

Installation Steps

1

Extract MongoDB Archive

tar -xzvf mongodb-dump/world-mongodb-dump.tar.gz
This extracts the MongoDB dump files to a mongodb-dump/world directory containing:
  • regions.bson and regions.metadata.json
  • countries.bson and countries.metadata.json
  • states.bson and states.metadata.json
  • cities.bson and cities.metadata.json
2

Restore Database

mongorestore --host localhost:27017 --db world mongodb-dump/world
Adjust the host and port parameters according to your MongoDB configuration. Default is usually localhost:27017.
3

Verify Installation

mongo world --eval "
printjson({
  regions: db.regions.count(),
  countries: db.countries.count(),  
  states: db.states.count(),
  cities: db.cities.count()
})
"
Expected output:
{
  "regions": 5,
  "countries": 250,
  "states": 5038,
  "cities": 151024
}

Alternative Installation Methods

Using MongoDB Compass

1

Connect to Database

Open MongoDB Compass and connect to your MongoDB server.
2

Create Database

  • Click “Create Database”
  • Database Name: “world”
  • Collection Name: “countries” (initial collection)
3

Import Collections

For each collection (regions, countries, states, cities):
  • Select the collection
  • Click “ADD DATA” → “Import File”
  • Choose the corresponding .json file
  • Select JSON format and import

Using Docker

1

Run MongoDB Container

docker run -d \
  --name mongodb-csc \
  -p 27017:27017 \
  -v $(pwd)/mongodb-data:/data/db \
  mongo:5.0
2

Copy Dump Files

docker cp mongodb-dump/world mongodb-csc:/tmp/world
3

Restore Inside Container

docker exec mongodb-csc mongorestore --db world /tmp/world

Database Structure

MongoDB stores the data in four main collections:
// Sample region document
{
  "_id": ObjectId("..."),
  "id": 1,
  "name": "Africa",
  "subregions": [
    "Northern Africa",
    "Western Africa", 
    "Eastern Africa",
    "Southern Africa",
    "Middle Africa"
  ]
}

MongoDB-Specific Operations

Basic Queries

// Connect to the database
use world

// Find all countries in Europe
db.countries.find({"region": "Europe"}).limit(5)

// Find cities in California
db.cities.find({
  "country_code": "US",
  "state_code": "CA"
}).limit(10)

// Find countries with specific currency
db.countries.find({"currency": "USD"})

// Find cities by coordinates (nearby locations)
db.cities.find({
  "latitude": {$gte: "40", $lte: "41"},
  "longitude": {$gte: "-74", $lte: "-73"}
})

Create Indexes

1

Basic Indexes

// Essential indexes for query performance
db.countries.createIndex({"iso2": 1})
db.countries.createIndex({"iso3": 1})
db.countries.createIndex({"region": 1})
db.countries.createIndex({"subregion": 1})

db.states.createIndex({"country_id": 1})
db.states.createIndex({"country_code": 1})

db.cities.createIndex({"state_id": 1})
db.cities.createIndex({"country_id": 1})
db.cities.createIndex({"country_code": 1})
db.cities.createIndex({"state_code": 1})
2

Geospatial Indexes

// Create 2dsphere index for geospatial queries
db.cities.createIndex({
  "location": "2dsphere"
})

// Add location field to existing documents
db.cities.updateMany(
  {},
  [{
    $set: {
      location: {
        type: "Point",
        coordinates: [
          { $toDouble: "$longitude" },
          { $toDouble: "$latitude" }
        ]
      }
    }
  }]
)
3

Text Search Indexes

// Create text indexes for search functionality
db.countries.createIndex({
  "name": "text",
  "native": "text",
  "capital": "text"
})

db.cities.createIndex({
  "name": "text",
  "state_name": "text",
  "country_name": "text"
})

Connection Examples

from pymongo import MongoClient
from pprint import pprint
import json

class WorldDatabase:
    def __init__(self, connection_string="mongodb://localhost:27017/"):
        self.client = MongoClient(connection_string)
        self.db = self.client.world
        
    def get_countries(self, region=None, limit=None):
        query = {}
        if region:
            query["region"] = region
            
        cursor = self.db.countries.find(query)
        if limit:
            cursor = cursor.limit(limit)
            
        return list(cursor)
    
    def get_cities_by_country(self, country_code, limit=None):
        query = {"country_code": country_code}
        cursor = self.db.cities.find(query)
        if limit:
            cursor = cursor.limit(limit)
        return list(cursor)
    
    def search_cities(self, search_term, limit=10):
        # Using text search
        return list(self.db.cities.find(
            {"$text": {"$search": search_term}},
            {"score": {"$meta": "textScore"}}
        ).sort([("score", {"$meta": "textScore"})]).limit(limit))
    
    def find_nearby_cities(self, longitude, latitude, max_distance=100000):
        # Geospatial query (requires 2dsphere index on location field)
        return list(self.db.cities.find({
            "location": {
                "$near": {
                    "$geometry": {
                        "type": "Point",
                        "coordinates": [longitude, latitude]
                    },
                    "$maxDistance": max_distance
                }
            }
        }))
    
    def get_country_statistics(self):
        pipeline = [
            {
                "$group": {
                    "_id": "$region",
                    "countries": {"$sum": 1},
                    "currencies": {"$addToSet": "$currency"}
                }
            },
            {"$sort": {"countries": -1}}
        ]
        return list(self.db.countries.aggregate(pipeline))
    
    def close(self):
        self.client.close()

# Usage example
db = WorldDatabase()

try:
    # Get European countries
    europe_countries = db.get_countries(region="Europe", limit=5)
    print("European Countries:")
    for country in europe_countries:
        print(f"  {country['name']} ({country['iso2']})")
    
    # Get US cities
    us_cities = db.get_cities_by_country("US", limit=5)
    print(f"\nUS Cities:")
    for city in us_cities:
        print(f"  {city['name']}, {city['state_name']}")
    
    # Search cities
    search_results = db.search_cities("paris", limit=5)
    print(f"\nCities matching 'paris':")
    for city in search_results:
        print(f"  {city['name']}, {city['country_name']}")
    
    # Country statistics
    stats = db.get_country_statistics()
    print(f"\nCountries by region:")
    for stat in stats:
        print(f"  {stat['_id']}: {stat['countries']} countries")

finally:
    db.close()

Advanced Features

Geospatial Queries

// Add GeoJSON location field to all cities
db.cities.updateMany(
  {},
  [{
    $set: {
      location: {
        type: "Point",
        coordinates: [
          { $toDouble: "$longitude" },
          { $toDouble: "$latitude" }
        ]
      }
    }
  }]
)

// Create 2dsphere index
db.cities.createIndex({ "location": "2dsphere" })

Data Validation

// Add validation rules
db.createCollection("countries", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["name", "iso2", "iso3"],
      properties: {
        name: {
          bsonType: "string",
          description: "must be a string and is required"
        },
        iso2: {
          bsonType: "string", 
          minLength: 2,
          maxLength: 2,
          description: "must be a 2-character string"
        },
        iso3: {
          bsonType: "string",
          minLength: 3, 
          maxLength: 3,
          description: "must be a 3-character string"
        }
      }
    }
  }
})

Troubleshooting

Problem: MongoNetworkError: connect ECONNREFUSEDSolutions:
  1. Check if MongoDB service is running: sudo systemctl status mongod
  2. Start MongoDB: sudo systemctl start mongod
  3. Check MongoDB port: netstat -an | grep 27017
  4. Verify connection string format
  5. Check firewall settings
Problem: MongoServerError: Authentication failedSolutions:
  1. Check username/password in connection string
  2. Verify user exists: db.getUsers()
  3. Check user roles: db.getUser("username")
  4. Create user with proper permissions:
    use admin
    db.createUser({
      user: "worlduser",
      pwd: "password",
      roles: [{ role: "readWrite", db: "world" }]
    })
    
Problem: mongorestore fails with various errorsSolutions:
  1. Check MongoDB version compatibility
  2. Ensure sufficient disk space
  3. Verify dump file integrity: tar -tzf world-mongodb-dump.tar.gz
  4. Try importing individual collections:
    mongorestore --db world --collection countries mongodb-dump/world/countries.bson
    
  5. Use --drop flag to overwrite existing data
Problem: Queries are running slowlySolutions:
  1. Create appropriate indexes (see Performance section)
  2. Use explain() to analyze query performance
  3. Optimize aggregation pipelines
  4. Increase MongoDB cache size
  5. Consider sharding for very large datasets

Backup and Maintenance

Backup Strategies

#!/bin/bash
# backup_world_mongodb.sh

DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/path/to/backups"
DB_NAME="world"

# Create dump
mongodump --host localhost:27017 --db $DB_NAME --out "$BACKUP_DIR/mongodb_backup_$DATE"

# Compress backup
tar -czf "$BACKUP_DIR/world_mongodb_backup_$DATE.tar.gz" -C "$BACKUP_DIR" "mongodb_backup_$DATE"

# Remove uncompressed files
rm -rf "$BACKUP_DIR/mongodb_backup_$DATE"

# Keep only last 7 backups
find $BACKUP_DIR -name "world_mongodb_backup_*.tar.gz" -type f -mtime +7 -delete

echo "Backup completed: world_mongodb_backup_$DATE.tar.gz"

Maintenance Tasks

// Check collection statistics
db.countries.stats()
db.cities.stats()

// Rebuild indexes
db.countries.reIndex()
db.cities.reIndex()

// Check index usage
db.cities.aggregate([{ $indexStats: {} }])

// Compact collections (offline operation)
db.runCommand({ compact: "cities" })
MongoDB automatically manages most maintenance tasks, but periodic index optimization and backup verification are recommended.

Next Steps

After successful installation:
  1. Create appropriate indexes for your query patterns
  2. Set up replica sets for high availability
  3. Configure sharding if handling very large datasets
  4. Implement monitoring with MongoDB Compass or third-party tools
  5. Set up automated backups using the provided scripts

Need Help?

Join our community discussions for MongoDB-specific questions and NoSQL optimization tips.