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
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
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.
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
Connect to Database
Open MongoDB Compass and connect to your MongoDB server.
Create Database
Click “Create Database”
Database Name: “world”
Collection Name: “countries” (initial collection)
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
Run MongoDB Container
docker run -d \
--name mongodb-csc \
-p 27017:27017 \
-v $( pwd ) /mongodb-data:/data/db \
mongo:5.0
Copy Dump Files
docker cp mongodb-dump/world mongodb-csc:/tmp/world
Restore Inside Container
docker exec mongodb-csc mongorestore --db world /tmp/world
Database Structure
MongoDB stores the data in four main collections:
Regions Collection
Countries Collection
Cities Collection
// 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
Find Operations
Aggregation 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
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 })
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" }
]
}
}
}]
)
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
Python (PyMongo)
Node.js
Java (Spring Data)
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 " \n US 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 " \n Cities matching 'paris':" )
for city in search_results:
print ( f " { city[ 'name' ] } , { city[ 'country_name' ] } " )
# Country statistics
stats = db.get_country_statistics()
print ( f " \n Countries by region:" )
for stat in stats:
print ( f " { stat[ '_id' ] } : { stat[ 'countries' ] } countries" )
finally :
db.close()
const { MongoClient } = require ( 'mongodb' );
class WorldDatabase {
constructor ( connectionString = 'mongodb://localhost:27017' ) {
this . connectionString = connectionString ;
this . client = null ;
this . db = null ;
}
async connect () {
this . client = new MongoClient ( this . connectionString );
await this . client . connect ();
this . db = this . client . db ( 'world' );
}
async getCountries ( region = null , limit = null ) {
const query = region ? { region } : {};
let cursor = this . db . collection ( 'countries' ). find ( query );
if ( limit ) cursor = cursor . limit ( limit );
return await cursor . toArray ();
}
async getCitiesByCountry ( countryCode , limit = null ) {
const query = { country_code: countryCode };
let cursor = this . db . collection ( 'cities' ). find ( query );
if ( limit ) cursor = cursor . limit ( limit );
return await cursor . toArray ();
}
async searchCities ( searchTerm , limit = 10 ) {
return await this . db . collection ( 'cities' )
. find (
{ $text: { $search: searchTerm } },
{ projection: { score: { $meta: 'textScore' } } }
)
. sort ({ score: { $meta: 'textScore' } })
. limit ( limit )
. toArray ();
}
async findNearbyCities ( longitude , latitude , maxDistance = 100000 ) {
return await this . db . collection ( 'cities' ). find ({
location: {
$near: {
$geometry: {
type: "Point" ,
coordinates: [ longitude , latitude ]
},
$maxDistance: maxDistance
}
}
}). toArray ();
}
async getCountryStatistics () {
const pipeline = [
{
$group: {
_id: "$region" ,
countries: { $sum: 1 },
currencies: { $addToSet: "$currency" }
}
},
{ $sort: { countries: - 1 } }
];
return await this . db . collection ( 'countries' ). aggregate ( pipeline ). toArray ();
}
async close () {
if ( this . client ) {
await this . client . close ();
}
}
}
// Usage example
async function example () {
const db = new WorldDatabase ();
try {
await db . connect ();
// Get European countries
const europeCountries = await db . getCountries ( 'Europe' , 5 );
console . log ( 'European Countries:' );
europeCountries . forEach ( country => {
console . log ( ` ${ country . name } ( ${ country . iso2 } )` );
});
// Get US cities
const usCities = await db . getCitiesByCountry ( 'US' , 5 );
console . log ( ' \n US Cities:' );
usCities . forEach ( city => {
console . log ( ` ${ city . name } , ${ city . state_name } ` );
});
// Search cities
const searchResults = await db . searchCities ( 'paris' , 5 );
console . log ( ' \n Cities matching "paris":' );
searchResults . forEach ( city => {
console . log ( ` ${ city . name } , ${ city . country_name } ` );
});
// Country statistics
const stats = await db . getCountryStatistics ();
console . log ( ' \n Countries by region:' );
stats . forEach ( stat => {
console . log ( ` ${ stat . _id } : ${ stat . countries } countries` );
});
} catch ( error ) {
console . error ( 'Database error:' , error );
} finally {
await db . close ();
}
}
example ();
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.TextCriteria;
import org.springframework.data.mongodb.core.query.TextQuery;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Metrics;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.query.NearQuery;
import java.util.List;
public class WorldDatabase {
private final MongoTemplate mongoTemplate ;
public WorldDatabase ( MongoTemplate mongoTemplate ) {
this . mongoTemplate = mongoTemplate;
}
public List < Country > getCountries ( String region , Integer limit ) {
Query query = new Query ();
if (region != null ) {
query . addCriteria ( Criteria . where ( "region" ). is (region));
}
if (limit != null ) {
query . limit (limit);
}
return mongoTemplate . find (query, Country . class , "countries" );
}
public List < City > getCitiesByCountry ( String countryCode , Integer limit ) {
Query query = new Query ( Criteria . where ( "country_code" ). is (countryCode));
if (limit != null ) {
query . limit (limit);
}
return mongoTemplate . find (query, City . class , "cities" );
}
public List < City > searchCities ( String searchTerm , int limit ) {
TextCriteria criteria = TextCriteria . forDefaultLanguage (). matchingAny (searchTerm);
Query query = TextQuery . queryText (criteria). sortByScore (). limit (limit);
return mongoTemplate . find (query, City . class , "cities" );
}
public List < City > findNearbyCities ( double longitude , double latitude , double maxDistanceKm ) {
Point location = new Point (longitude, latitude);
Distance distance = new Distance (maxDistanceKm, Metrics . KILOMETERS );
Query query = new Query ( Criteria . where ( "location" ). near (location). maxDistance ( distance . getNormalizedValue ()));
return mongoTemplate . find (query, City . class , "cities" );
}
}
// Entity classes
@ Document ( collection = "countries" )
public class Country {
@ Id
private String id ;
private String name ;
private String iso2 ;
private String iso3 ;
private String region ;
private String subregion ;
private String capital ;
private String currency ;
private String phone_code ;
// Getters and setters...
}
@ Document ( collection = "cities" )
public class City {
@ Id
private String id ;
private String name ;
private String state_name ;
private String country_name ;
private String country_code ;
private String state_code ;
private String latitude ;
private String longitude ;
// Getters and setters...
}
Advanced Features
Geospatial Queries
Setup Geospatial Data
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 :
Check if MongoDB service is running: sudo systemctl status mongod
Start MongoDB: sudo systemctl start mongod
Check MongoDB port: netstat -an | grep 27017
Verify connection string format
Check firewall settings
Problem : MongoServerError: Authentication failedSolutions :
Check username/password in connection string
Verify user exists: db.getUsers()
Check user roles: db.getUser("username")
Create user with proper permissions:
use admin
db . createUser ({
user: "worlduser" ,
pwd: "password" ,
roles: [{ role: "readWrite" , db: "world" }]
})
Problem : mongorestore fails with various errorsSolutions :
Check MongoDB version compatibility
Ensure sufficient disk space
Verify dump file integrity: tar -tzf world-mongodb-dump.tar.gz
Try importing individual collections:
mongorestore --db world --collection countries mongodb-dump/world/countries.bson
Use --drop flag to overwrite existing data
Backup and Maintenance
Backup Strategies
Complete Database Backup
Collection-Specific Backup
#!/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:
Create appropriate indexes for your query patterns
Set up replica sets for high availability
Configure sharding if handling very large datasets
Implement monitoring with MongoDB Compass or third-party tools
Set up automated backups using the provided scripts