Explore Developer Center's New Chatbot! MongoDB AI Chatbot can be accessed at the top of your navigation to answer all your MongoDB questions.

MongoDB Developer
MongoDB
plus
Sign in to follow topics
MongoDB Developer Centerchevron-right
Developer Topicschevron-right
Productschevron-right
MongoDBchevron-right

MongoDB Time Series With C++

Rishabh Bisht6 min read • Published Feb 10, 2023 • Updated Sep 17, 2024
MongoDBTime seriesC++
Facebook Icontwitter iconlinkedin icon
Rate this tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Time series data is a set of data points collected at regular intervals. It’s a common use case in many industries such as finance, IoT, and telecommunications. MongoDB provides powerful features for handling time series data, and in this tutorial, we will show you how to build a C++ console application that uses MongoDB to store time series data, related to the Air Quality Index (AQI) for a given location. We will also take a look at MongoDB Charts to visualize the data saved in the time series.
Libraries used in this tutorial:
This tutorial uses Microsoft Windows 11 and Microsoft Visual Studio 2022 but the code used in this tutorial should work on any operating system and IDE, with minor changes.

Prerequisites

  1. MongoDB Atlas account with a cluster created.
  2. Microsoft Visual Studio setup with MongoDB C and C++ Driver installed. Follow the instructions in Getting Started with MongoDB and C++ to install MongoDB C/C++ drivers and set up the dev environment in Visual Studio.
  3. Your machine’s IP address is whitelisted. Note: You can add 0.0.0.0/0 as the IP address, which should allow access from any machine. This setting is not recommended for production use.
  4. API token is generated using Air Quality Open Data Platform API Token Request Form to fetch AQI for a given location.

Installation: Libraries

Launch powershell/terminal as an administrator and execute commands shared below.
Step 1: Install vcpkg.
1git clone https://github.com/Microsoft/vcpkg.git
2cd vcpkg
3./bootstrap-vcpkg.sh
4./vcpkg integrate install
Step 2: Install libcpr/cpr.
1./vcpkg install cpr:x64-windows
This tutorial assumes we are working with x64 architecture. If you are targeting x86, please use this command:
1./vcpkg install cpr
Note: Below warning (if encountered) can be ignored.
1# this is heuristically generated, and may not be correct
2find_package(cpr CONFIG REQUIRED)
3target_link_libraries(main PRIVATE cpr::cpr)

Building the application

Source code available here
In this tutorial, we will build an Air Quality Index (AQI) monitor that will save the AQI of a given location to a time series collection.
The AQI is a measure of the quality of the air in a particular area, with higher numbers indicating worse air quality. The AQI is based on a scale of 0 to 500 and is calculated based on the levels of several pollutants in the air.
We are going to build a console application from scratch. Follow the steps on how to set up the development environment in Visual Studio from our previous article Getting Started with MongoDB and C++, under the section “Visual Studio: Setting up the dev environment.”

Helper functions

Once we have set up a Visual Studio solution, let’s start with adding the necessary headers and writing the helper functions.
  • Make sure to include <cpr/cpr.h> to access methods provided by the cpr library.
Note: Since we installed the cpr library with vcpkg, it automatically adds the needed include paths and dependencies to Visual Studio.
  • Get the connection string (URI) to the cluster and create a new environment variable with key as “MONGODB_URI” and value as the connection string (URI). It’s a good practice to keep the connection string decoupled from the code. Similarly, save the API token obtained in the Prerequisites section with the key as “AQICN_TOKEN”.
Navigate to the Solution Explorer panel, right-click on the solution name, and click “Properties.” Go to Configuration Properties > Debugging > Environment to add these environment variables as shown below.
Setting environment variables in Microsoft Visual Studio
  • “getAQI” function makes use of the cpr library to make a call to the REST API, fetching the AQI data. The response to the request is then parsed to get the AQI figure.
  • “saveToCollection” function saves the given AQI figure to the time series collection. Please note that adding the “timestamp” key-value pair is mandatory. A missing timestamp will lead to an exception being thrown. Check out different “timeseries” Object Fields in Create and Query a Time Series Collection — MongoDB Manual.
1#pragma once
2
3
4#include <mongocxx/client.hpp>
5#include <bsoncxx/builder/list.hpp>
6#include <bsoncxx/builder/stream/document.hpp>
7#include <bsoncxx/json.hpp>
8#include <mongocxx/uri.hpp>
9#include <mongocxx/instance.hpp>
10
11
12#include <iostream>
13#include <cpr/cpr.h>
14
15
16using namespace std;
17
18
19std::string getEnvironmentVariable(std::string environmentVarKey)
20{
21 char* pBuffer = nullptr;
22 size_t size = 0;
23 auto key = environmentVarKey.c_str();
24
25 // Use the secure version of getenv, ie. _dupenv_s to fetch environment variable.
26 if (_dupenv_s(&pBuffer, &size, key) == 0 && pBuffer != nullptr)
27 {
28 std::string environmentVarValue(pBuffer);
29 free(pBuffer);
30 return environmentVarValue;
31 }
32 else
33 {
34 return "";
35 }
36}
37
38
39int getAQI(std::string city, std::string apiToken)
40{
41 // Call the API to get the air quality index.
42 std::string aqiUrl = "https://api.waqi.info/feed/" + city + "/?token=" + apiToken;
43 auto aqicnResponse = cpr::Get(cpr::Url{ aqiUrl });
44
45
46 // Get the AQI from the response
47 if(aqicnResponse.text.empty())
48 {
49 cout << "Error: Response is empty." << endl;
50 return -1;
51 }
52 bsoncxx::document::value aqicnResponseBson = bsoncxx::from_json(aqicnResponse.text);
53 auto aqi = aqicnResponseBson.view()["data"]["aqi"].get_int32().value;
54 return aqi;
55}
56
57
58void saveToCollection(mongocxx::collection& collection, int aqi)
59{
60 auto timeStamp = bsoncxx::types::b_date(std::chrono::system_clock::now());
61
62
63 bsoncxx::builder::stream::document aqiDoc = bsoncxx::builder::stream::document{};
64 aqiDoc << "timestamp" << timeStamp << "aqi" << aqi;
65 collection.insert_one(aqiDoc.view());
66
67
68 // Log to the console window.
69 cout << " TimeStamp: " << timeStamp << " AQI: " << aqi << endl;
70}

The main() function

With all the helper functions in place, let’s write the main function that will drive this application.
  • The main function creates/gets the time series collection by specifying the “collection_options” to the “create_collection” method. Note: MongoDB creates collections implicitly when you first reference the collection in a command, however a time series collection needs to be created explicitly with “create_collection”.
  • Every 30 minutes, the program gets the AQI figure and updates it into the time series collection. Feel free to modify the time interval as per your liking by changing the value passed to “sleep_for”.
1int main()
2{
3 // Get the required parameters from environment variable.
4 auto mongoURIStr = getEnvironmentVariable("MONGODB_URI");
5 auto apiToken = getEnvironmentVariable("AQICN_TOKEN");
6 std::string city = "Delhi";
7 static const mongocxx::uri mongoURI = mongocxx::uri{ mongoURIStr };
8
9
10 if (mongoURI.to_string().empty() || apiToken.empty())
11 {
12 cout << "Invalid URI or API token. Please check the environment variables." << endl;
13 return 0;
14 }
15
16
17 // Create an instance.
18 mongocxx::instance inst{};
19 mongocxx::options::client client_options;
20 auto api = mongocxx::options::server_api{ mongocxx::options::server_api::version::k_version_1 };
21 client_options.server_api_opts(api);
22 mongocxx::client conn{ mongoURI, client_options };
23
24
25 // Setup Database and Collection.
26 const string dbName = "AQIMonitor";
27 const string timeSeriesCollectionName = "AQIMonitorCollection";
28
29
30 // Setup Time Series collection options.
31 bsoncxx::builder::document timeSeriesCollectionOptions =
32 {
33 "timeseries",
34 {
35 "timeField", "timestamp",
36 "granularity", "minutes"
37 }
38 };
39
40
41 auto aqiMonitorDB = conn[dbName];
42 auto aqiMonitorCollection = aqiMonitorDB.has_collection(timeSeriesCollectionName)
43 ? aqiMonitorDB[timeSeriesCollectionName]
44 : aqiMonitorDB.create_collection(timeSeriesCollectionName, timeSeriesCollectionOptions.view().get_document().value);
45
46
47 // Fetch and update AQI every 30 minutes.
48 while (true)
49 {
50 auto aqi = getAQI(city, apiToken);
51 saveToCollection(aqiMonitorCollection, aqi);
52 std::this_thread::sleep_for(std::chrono::minutes(30));
53 }
54
55
56 return 0;
57}
When this application is executed, you can see the below activity in the console window.
AQI Monitor application in C++ with MongoDB time series
You can also see the time series collection in Atlas reflecting any change made via the console application.
MongoDB time series in MongoDB Atlas

Visualizing the data with MongoDB Charts

We can make use of MongoDB Charts to visualize the AQI data and run aggregation on top of it.
Step 1: Go to MongoDB Charts and click on “Add Dashboard” to create a new dashboard — name it “AQI Monitor”.
Step 2: Click on “Add Chart”.
Step 3: In the “Select Data Source” dialog, go to the “Project” tab and navigate to the time series collection created by our code.
Selecting data source for MongoDB Charts
Step 4: Change the chart type to “Continuous Line”. We will use this chart to display the AQI trends over time.
Step 5: Drag and drop the “timestamp” and “aqi” fields into the X axis and Y axis respectively. You can customize the look and feel (like labels, color, and data format) in the “Customize” tab. Click “Save and close” to save the chart.
MongoDB Charts with time series
Step 6: Let’s add another chart to display the maximum AQI — click on “Add Chart” and select the same data source as before.
Step 7: Change the chart type to “Number”.
Step 8: Drag and drop the “aqi” field into “Aggregation” and change Aggregate to “MAX”.
MongoDB Charts with time series
Step 9: We can customize the chart text to change color based on the AQI values. Let’s make the text green if AQI is less than or equal to 100, and red otherwise. We can perform this action with the conditional formatting option under Customize tab.
Formatting options in MongoDB Charts
Step 10: Similarly, we can add charts for minimum and average AQI. The dashboard should finally look something like this:
MongoDB Charts dashboard
Tip: Change the dashboard’s auto refresh settings from “Refresh settings” button to choose a refresh time interval of your choice for the charts.
MongoDB Charts refresh settings

Conclusion

With this article, we covered creating an application in C++ that writes data to a MongoDB time series collection, and used it further to create a MongoDB Charts dashboard to visualize the data in a meaningful way. The application can be further expanded to save other parameters like PM2.5 and temperature.
Now that you've learned how to create an application using the MongoDB C++ driver and MongoDB time series, put your new skills to the test by building your own unique application. Share your creation with the community and let us know how it turned out!

Facebook Icontwitter iconlinkedin icon
Rate this tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Related
Tutorial

Getting Started With Server-side Kotlin and MongoDB


Oct 08, 2024 | 6 min read
Tutorial

Real-Time Location Tracking With Change Streams and Socket.io


Aug 13, 2024 | 8 min read
Quickstart

Getting Started With MongoDB and Sanic


Jul 12, 2024 | 5 min read
Tutorial

Create a Data Pipeline for MongoDB Change Stream Using Pub/Sub BigQuery Subscription


Apr 02, 2024 | 5 min read
Table of Contents