MongoDB Stitch QueryAnywhere – The AWS re:Invent Stitch Rover Demo

Please note: This article discusses MongoDB Mobile and Sync. Those products are currently being deprecated as we work towards a public beta of MongoDB Realm. To learn more about this, see the MongoDB Realm site.

At AWS re:Invent, we demonstrated how MongoDB Mobile, MongoDB Stitch, and AWS services could be used to build a cloud-controlled Mars rover – read the overview post for the setup. This post focuses on how the mission control app records the user commands in MongoDB Atlas.

Mission Control is a simple web application that we ran on an iPad. The web app takes commands from the user through its UI which displays directions for the rover to travel in. Each command sets the rover off in that direction for a short fixed amount of time.

MongoDB Stitch QueryAnywhere rover Mission Control web app

Rather than sending the command directly to the rover, and as Mars is a long way away and network connections are not always reliable, the app stores the commands in an array within the rover's document in Atlas – in that way, commands can be queued up and sent to the rover as soon as it's back online.

MongoDB Stitch QueryAnywhere

This is what the document looks like after a few commands have been submitted (but not yet acted on by the rover):

{
	"_id" : "5bee1053fdc728f2623e20eb",
	"moves" : [
		{
			"_id" : "5c0e4db5119f6e36c7d06f55",
			"angle" : 90,
			"speed" : 2
		},
		{
			"_id" : "5c0e4dbc119f6e36c7d06f56",
			"angle" : 118,
			"speed" : 3
		},
		{
			"_id" : "5c0e4dc3119f6e36c7d06f57",
			"angle" : 45,
			"speed" : -1
		}
	],
	"__stitch_sync_version" : {
		"spv" : 1,
		"id" : "2f704b04-2338-4c75-a7cf-d555c94cb556",
		"v" : NumberLong(10313)
	}
}

A traditional way of access the database from the frontend app would be to stand up an app server, implement a custom REST API and data access control layer, and then send the commands to it from the frontend app. MongoDB Stitch massively simplifies that workflow by letting a web (or mobile) app execute MongoDB Query Language operations directly – removing the need for thousands of lines of boilerplate code.

When we explained this access model to demo visitors, some were nervous about this approach as we've been taught that the schema and database access should be hidden from the frontend (remember SQL injection attacks?). Fortunately, Stitch QueryAnywhere is made up of two components – the first is the Stitch SDK that enables direct access to the database, the second is the sophisticated, fine-grained user access controls provided by the Stitch service. If that doesn't allay your fears then you have the option to obfuscate the schema by accessing the database through Stitch Functions.

Updating the document from the web app is a cinch with Stitch. The first step is to import the Stitch SDK:

<head>
  <script src="https://s3.amazonaws.com/stitch-sdks/js/bundles/4.0.15-0/stitch.js"></script>
  <script src="https://s3.amazonaws.com/stitch-sdks/bson/bson.bundle.js"></script>
</head>

The second step is to create the object/document for the command and push it onto the moves array within this rover's document in the rover.rovers collection:

function pushMoveToRover(roverId) {
	const client = stitch.Stitch.defaultAppClient;
	const coll = client.getServiceClient(stitch.RemoteMongoClient.factory,
		'mongodb-atlas').db('rover').collection('rovers');
	const angle = parseInt($("#angle").val());
	const speed = parseInt($("#speed").val());
	if (isNaN(angle) || isNaN(speed)) {
  		return;
	}
	const move = {"_id": new BSON.ObjectID().toHexString(), angle, speed};
	coll.updateOne({"_id": roverId}, {"$push": { "moves": move }, 
		"$inc": {"__stitch_sync_version.v": 1}});
}

If you are used to working with the MongoDB Query Language from an app server, that should seem very familiar. The only thing that might catch your eye is that __stitch_sync_version.v. That’s part of how this update will get to the MongoDB Mobile database embedded in the rover. We’ll explain that in the next part.

If you can't wait then you can find all of the code in the Stitch Rover GitHub repo.

In summary, this is what we cover in the five posts:

  • MongoDB Stitch/Mobile Mars Rover Lands at AWS re:Invent describes how MongoDB Stitch, MongoDB Mobile, Atlas, Android Things, a Raspberry Pi, and Amazon Kinesis are used to reliably control our Mars rover.
  • MongoDB Stitch QueryAnywhere focuses on how the Mission Control app records the user commands in MongoDB Atlas by calling the Stitch SDK directly from the frontend code.
  • MongoDB Stitch Mobile Sync shows how Stitch Mobile Sync synchronizes the user commands written to MongoDB Atlas by the Mission Control app with the MongoDB Mobile database embedded in the rover (and how it syncs the data back to Atlas when it's updated in MongoDB Mobile).
  • MongoDB Stitch Functions focuses on how a Stitch Function is used to provide aggregated sensor data such as the average temperature for the last 5 minutes.
  • MongoDB Stitch Triggers & Amazon Kinesis shows how we use MongoDB Stitch Triggers and the Stitch AWS service to push MongoDB database changes to Amazon Kinesis.