Our website is made possible by displaying online advertisements to our visitors. Please consider supporting us by disabling your ad blocker.

Randomizing MongoDB Document Fields on a Repeating Timer with Node.js

TwitterFacebookRedditLinkedInHacker News

About a year ago I created a game with MongoDB and Unity and wrote about it in a previous tutorial. The idea was to demonstrate how features within the game could be synchronized to each player in near real-time. At the time, synchronization happened through a web dashboard where the player could select features to sync and they would then sync to the game client, wherever in the world it might be.

Recently, the game was adopted to be a demo at several conferences. The problem was that switching between the game and the web dashboard to demonstrate features being synchronized was a hassle. As a result, I decided to write a script that did this automatically on a timer.

In this quick tutorial, we’re going to see how to update documents within MongoDB on a timer, something that might be useful to you for demos and other potential use-cases.

The Requirements

Before you continue through the rest of this tutorial, you should be aware of certain requirements that must be met to be successful.

  • You should already have access to a MongoDB instance or a MongoDB Atlas cluster. This instance or cluster should already be configured with the appropriate network and user rules.
  • You should have a modern version of Node.js, although most versions should work fine.

You don’t need to have Unity available to you and you don’t even need to have seen the previous tutorial where I talked about the game. While this example will be inspired from the game, it will work fine as a stand-alone example.

Installing and Configuring the Node.js Project Dependencies, Including MongoDB

We’re going to start with a blank slate to keep this project simple and easy to understand.

From the command line, execute the following:

mkdir MongoExample
cd MongoExample
npm init -y
npm install mongodb dotenv
touch main.js .env.local

We’re doing a few things in the above snippet, many of which can be done outside of the command line if that is your preference.

First we’re creating a new project directory and we’re initializing a package.json file within it. Next we’re installing the MongoDB driver for Node.js as well as a package that will allow us to use an environment variable file. Finally we are creating a file to hold our code and a file to hold our environment variables.

Within the .env.local file, you’ll want to add the following:

MONGODB_ATLAS_URI=
MONGODB_ATLAS_DATABASE=
MONGODB_ATLAS_COLLECTION=

In my example above, I’m using MongoDB Atlas. If you’re using MongoDB Atlas as well, fill each of the above variables with the appropriate information. If you’re using an on-premise version of MongoDB, make changes where necessary.

Next we need to open the project’s main.js file and add the following:

const { MongoClient } = require("mongodb");

require("dotenv").config();

const mongoClient = new MongoClient(process.env.MONGODB_ATLAS_URI);
var database, collection;

(async () => {
    try {
        // Code in here ...
    } catch(e) {
        console.error(e);
    }
})();

In the above code we are including each of our project dependencies as well as creating a MongoDB client using the information found in the environment variable file.

At the point we’re ready to establish a connection to MongoDB and execute what we’ve initially set out to accomplish.

Randomizing Values within MongoDB Documents on a Timer

Going back to what I had originally set out to do, the goal was to change certain documents, but not all documents. For this reason, we have to specify which documents should be a part of this timer.

Before the function block in the main.js file, add the following line:

const demoUsers = ["player@example.com"];

Every user in the above array should have their values altered. If they don’t appear in the array, they should be excluded from the changes.

With that in mind, let’s explore our function block:

(async () => {
    try {
        await mongoClient.connect();
        database = mongoClient.db(process.env.MONGODB_ATLAS_DATABASE);
        collection = database.collection(process.env.MONGODB_ATLAS_COLLECTION);
        setInterval(async () => {
            let results = await collection.find(
                {
                    "email": {
                        "$in": demoUsers
                    }
                }
            ).toArray();
            results.forEach(user => {
                console.log(`updating ${user.email}...`);
                switch(Math.floor(Math.random() * 2)) {
                    case 0:
                        user.cross_blaster_enabled = !user.cross_blaster_enabled;
                        break;
                    case 1:
                        user.spark_blaster_enabled = !user.spark_blaster_enabled;
                        break;
                }
                collection.updateOne(
                    {
                        "email": user.email
                    },
                    {
                        "$set": {
                            "cross_blaster_enabled": user.cross_blaster_enabled,
                            "spark_blaster_enabled": user.spark_blaster_enabled
                        }
                    }
                )
            });
        }, 10000);
    } catch(e) {
        console.error(e);
    }
})();

In the above code we are using our previously established client to connect to MongoDB. Once connected, we are obtaining a reference to the database and collection defined in our environment variables file.

The real magic happens in the setInterval function which repeats its code every ten seconds.

Every new interval results in us first finding all documents where the email field exists in our demoUsers list. Once we have all those documents, we can loop through them and run randomization logic on the fields we want to change. After the field has been changed, we update each document one at a time based on the email address. This will prevent all documents from being updated and restrict it to only the document in question.

Not bad right?

Conclusion

You just saw how to work with MongoDB from a Node.js script! The gist of the example demonstrates how to find documents and update documents, even though it was inspired by the game I had made previously.

If you haven’t already seen my game, I recommend you check it out in the tutorial I wrote titled, Building a Space Shooter Game that Syncs with Unity and MongoDB Realm.

Nic Raboy

Nic Raboy

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in C#, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Unity. Nic writes about his development experiences related to making web and mobile development easier to understand.