GIANT Stories at MongoDB

Identity management application using Blockchain, MongoDB Stitch & MongoDB Atlas - Part 2

Pavel Duchovny

In part 1, we got started by introducing an application where digital identity is stored in a blockchain, focusing on the use case and the proposed system architecture. In this part, we will cover the implementation details and key takeaways.


Modern and distributed applications require a modern and distributed data platform for streamlined development and rapid scale as the network grows. Storing the data locally is not reliable, performant or scalable enough, and here is where the advantages of the MongoDB Atlas cloud database and the MongoDB Stitch serverless platform really shine, providing the best foundation to build apps with a global reach.

MongoDB Stitch

MongoDB Stitch, MongoDB’s serverless platform, allowed us to utilize several major capabilities to improve our development speed, security, and scale. Here’s how:

  • Authentication models: Various authentication and user management features allow us to easily authenticate decentralized nodes in the blockchain network (using anonymous authentication). On the other hand, consumers of the network would authenticate with advanced security mechanisms to secure their data access. For simplicity our example uses email/password authentication:
    async function handleLogin() {
      const email = loginEmailEl.value;
      const password = loginPasswordEl.value;
      const credential = new UserPasswordCredential(email, password);
      try {
        await stitchClient.auth.loginWithCredential(credential);
        const user = stitchClient.auth.user;
        displaySuccess(`Logged in as: ${}`)
      } catch(e) {
  • Stitch Rules: Flexible and easy to define authorization rules that can be applied on collection, field, and document levels give us the ability to manage data access in very sophisticated and controlled ways. One of the most fascinating abilities is to automatically project fields such as “credit_score” and “assets_range” only if a user has permissions to view them. Stitch roles allow you to filter data based on a user’s preferences:
    "assets_range": {
                        "read": {
                            "%or": [
                                    "%%root.owner_id": ""
                                {                  "%%root.identity_verification_log.transaction_details.assets_shared": "assets_range"
  • Stitch Functions: Implement hosted, server-side logic that can govern process accuracy and validate data used within the data access rules. For example, approvedByMajority verification will return true when the block actually has a majority of votes from participating blockchain nodes:
      // Get collections 
      var nodes ="mongodb-atlas").db("assets").collection("nodes");
      var pending_blocks ="mongodb-atlas").db("transactions").collection("pending_blocks");
      // Retrieve the current block
      var doc = pending_blocks.findOne({index : block.index});
      if (doc)
        // Retrieve approvals vs active nodes
        currentApprovals = doc.approvals;
        var numberOfActiveNodes = nodes.count( {"active" : true});
        var approvedNodes = nodes.count({"owner_id" : {"$in" : currentApprovals}});
        // See if majority has approved
        if (approvedNodes > (numberOfActiveNodes / 2))
          return true;
          return false;
      return false;
  • Stitch Triggers & third-party services: Once a user’s identity has been validated, Stitch Triggers we notify parties about offers and promotions based on the data in the blockchain.

    With third-party service integrations, we can integrate information and security gathering services easily into the process.

Trigger pushOffer.

MongoDB Atlas

Note: The Atlas cluster must be of version 3.6 and above.

MongoDB Stitch is backed with an Atlas cluster which provides us with 4 key abilities:

  • Atlas provides data access and management with scalability, resilience, and worldwide distribution to conform with privacy regulations such as GDPR and HIPAA.
  • Rich query and analytical language with a built-in Stitch hybrid connection string. In particular, we have utilized MongoDB views built on top of the $graphLookup aggregation stage, which is a key capability to traverse and validate data structures such as Blockchains.
                [    {
                        "$match" : {
                            "index" : 0
                        "$graphLookup" : {
                            "from" : "pending_blocks",
                            "startWith" : "$previousHash",
                            "connectFromField" : "hash",
                            "connectToField" : "previousHash",
                            "as" : "chain"
                        "$unwind" : "$chain"
                        "$sort" : {
                            "chain.index" : 1
                        "$group" : {
                            "_id" : "$_id",
                            "chain" : {
                                "$push" : "$chain"
                        "$project" : {
                            "chain" : 1,
                            "_id" : 0
    db.pending_blocks.createIndex({index : 1},{unique : true});
  • Change Streams features are a tremendous game changer for event-driven applications. Any data changing events can be filtered within Atlas when only relevant notifications to the application watcher. One main use case for this is when nodes receive a notification about a new block generated by one of the network workers:
    // Configure change pipeline
    const pipeline = [
                   { $match: {'fullDocument.owner_id'  : {  "$ne" : client.authedId() },
                   "operationType" : "insert" } }
            // Get collection and set a change stream
             var db = atlasConn.db('transactions');
             const changeStream = db.collection('pending_blocks').watch(pipeline);
    MongoDB Stitch Triggers make events even simpler to process.
  • Built-in TLS and enterprise security features allow us to enforce additional levels of access control, auditing, and encryption, layering upon the governance features of MongoDB Stitch and the Blockchain itself.

Conclusions & Key Takeaways

The world of blockchain in digital systems has a tremendous potential and I believe we are going to see some extremely innovative ideas that will thrive outside of the cryptocurrency space. MongoDB enables rapid innovation, developer productivity, and scale-out for applications like this one and many others – which all benefit from decentralized data control, trust and immutability.

Identity management application using Blockchain, MongoDB Stitch & MongoDB Atlas - Part 1

Pavel Duchovny

Our physical and digital identities intersect in a million ways in today's world. Sharing and gathering information with partners and third-party vendors to streamline business processes while keeping the information secure and genuine is challenging.

Last year was big for blockchain technology. Among its many use cases, blockchain unlocks opportunities to leverage its trust, distribution, and immutability to publish identity information among various entities while maintaining a clear cryptographic ledger. Sensitive information goes through a strict approval process and is encrypted to be accessed only by specific parties. Blockchain core concepts are out of scope for this blog post. If you wish to learn more about blockchains, please refer to the resources section at the end of this blog.

Use Case

As a proof of concept, we built a blockchain identity management application. We used the blockchain structure and concepts to save and publish digital identities for a fictional bank network. Using NodeJS we have built a network of nodes which are run by the various partners in the network, pushing and governing the production of blocks within the chain.

Figure 1 : Bank-side application which shows a login verification through the blockchain ( transparent to the user)
Figure 2. Identity information is published to the blockchain.
Figure 3. Nodes on the blockchain network approve the information/encryption signatures. Other approved parties can consume the information once it is approved.

The main idea is that data can be pushed to the blockchain network by Bank A (Figure 2), consumed and approved by the majority of the network, and appear as trusted information for Bank B or C (Figure 3). Whether the information is encrypted or in the clear depends on Entity A. Using this information, Banks B and C can push offers and promotions for those customers based on the blockchain network information without the need for a centralized registration authority.

Next Steps

That’s a wrap for Part 1 of this blog series. In Part 2 we’ll cover the implementation details and key takeaways.

Learn how we built a distributed identity management application on blockchain using the MongoDB Stitch serverless platform and MongoDB Atlas cloud database service for a financial services use case.

Visualizing Your Data With MongoDB Charts

Having data stored in a database is practically a given for today’s businesses. Customer information, order history, product pricing, IoT sensor data, and much more is being recorded for future use. However, just having the data stored isn’t enough to form a competitive market advantage. We must be able to analyze the data as well. There are many options to do so and in a variety of ways. If you have data that needs to be visually analyzed in MongoDB, MongoDB Charts is a terrific option.

Prior to MongoDB Charts, there were really three ways to visualize your MongoDB Data.

  1. Leverage the MongoDB Business Intelligence (BI) Connector in conjunction with third-party BI tools,
  2. Perform Extract-Transform-Load (ETL) operations and leverage third-party tools, or
  3. Write custom code and use charting libraries such as D3.js or Bokeh.

MongoDB Charts, currently in Beta, provides an easy way to visualize your data living in MongoDB. You don’t need to move your data to a different repository, write your own code, or purchase third-party tools. MongoDB Charts knows and understands the richness of the Document Data Model and allows for easy data visualization.

Further, MongoDB Charts allows for a secure way to create and share visualization dashboards with everyone, or just targeted team members. Similarly, the data source being used behind the scenes can be shared securely as well. For example, data for the Sales Department doesn’t have to be made available to Marketing unless needed. Very powerful and follows MongoDB’s design of security being a top priority.

After downloading the MongoDB Charts Docker image and following the installation instructions, we’re able to connect to a data source stored in MongoDB Atlas and start making visualization dashboards. Once connected to the MongoDB Charts server, there are three steps we need to take:

  1. Add a data source
  2. Create a dashboard
  3. Create our charts

Analyzing Airbnb Data with MongoDB Charts

I have set up a database with some Airbnb data from various cities. We’ll be exploring the dataset from Seattle, WA here, but feel free to explore others on your own. We need to get the connection string from the Atlas Cluster that has our data and connect to it in Charts.

Get URI from MongoDB Atlas

Add a Data Source

With our MongoDB Charts server running on localhost:80, we can log in and head to the Data Sources tab. We use the URI from Atlas (mongodb+srv:// and select Connect. We’re next asked which data source we want to use from that cluster, I’ll select the seattleListingAndReviews from the airbnb database for this example. For permissions, I just want to keep everything private so I’ll accept the defaults and select Publish Data Source. Once published I can add an alias to the data source. I’ll call it Airbnb Seattle.

Note: The URI above contains a sample URI. You should connect to your own Atlas Cluster and use an authorized username and password.

Create a Dashboard

Next up is to create an actual dashboard to house our visualizations. In the Dashboards section choose New Dashboard and give it a name and description, like Ken’s Airbnb Dashboard. This will take me to where I can add charts to my dashboard.

Create a Chart

After clicking on the Add Chart button we can start building our visualization. We’ll want to choose the Airbnb Seattle data source from the drop-down. MongoDB Charts automatically determines which fields are available for exploration. For this exercise, I’d like to see which neighborhoods in Seattle have the most Airbnb properties and split them by property type. We’ll use the Stacked Bar chart for the type.

  1. For the X-Axis then, we’ll want the id field, aggregated by count.
  2. Assign X-Axis value to a MongoDB Chart
  3. Along the Y-Axis we’ll look at the address and the suburb. Notice that address is a subdocument here and that MongoDB Charts natively knows how to handle this type of data. I’d like to sort the suburb by aggregated value, in descending order, and limit our results to the top 20 suburbs.
  4. Assign Y-Axis value to a Stacked Bar chart
  5. Let’s add the property_type field as our series
  6. Assign a Series value to a Stacked Bar chart

Now we can name our chart, Properties by Location and save it. We’re then taken back to our dashboard where we can add other visualizations for further exploration.

Have a look at this short video to see some other visualizations being created from this same data source.


MongoDB Charts is an excellent new tool to visually explore your data. It has some great features for specific use cases, such as:

  • Ad hoc analysis of your data
  • Natively understands the benefits of the Document Data Model
  • Collaboration on projects is easy with user-based sharing and permissions
  • It’s intuitive enough for non-developers to use allowing for self-service data analysis

MongoDB Charts is the fastest way to build visualizations over your MongoDB data. I’d encourage you to download it and try it out today. Let me know what visualizations you come up with from the Airbnb dataset. I always enjoy seeing how people explore their data.

New to MongoDB Atlas — Get Started with Free Fully Automated Databases on Microsoft Azure

Leo Zheng

Release Notes, Cloud

We’re excited to announce that teams can now use MongoDB Atlas — the global cloud database for MongoDB — for free on Microsoft Azure. The newly available free tier on Azure Cloud, known as the M0, grants users 512 MB of storage and is ideal for learning MongoDB, prototyping, and early development.

The Atlas free tier will run MongoDB 4.0 and grant users access to some of the latest database features, including multi-document transactions, which make it even easier to address a complete range of use cases with MongoDB; type conversions, which allow teams to perform sophisticated transformations natively in the database without costly and fragile ETL; and updated security defaults (SHA-256 and TLS 1.1+).

Like larger MongoDB Atlas cluster types, M0 clusters grant users optimal security with end to end encryption, high availability, and fully managed upgrades. M0 clusters also enable faster development by allowing teams to perform CRUD operations against their data right from their browsers via the built-in Data Explorer.

Finally, free tier clusters on Azure can be paired with MongoDB Stitch — a powerful suite of serverless platform services for apps using MongoDB — to simplify the handling of backend logic, database triggers, and integrations with the wider Azure ecosystem.

At launch, the MongoDB Atlas free tier will be available in 3 Azure regions:

  • East US (Virginia)
  • East Asia (Hong Kong)
  • West Europe (Netherlands)

Creating a free tier is easy. When building a new Atlas cluster, select Azure as your cloud of choice and one of the regions above.

Next, select M0 in the “Cluster Tier” dropdown.

Then, give the cluster a name and hit the “Create Cluster” button. Your free MongoDB Atlas cluster will be deployed in minutes.

New to MongoDB Atlas? Deploy a free cluster in minutes.

MongoDB Hackathon Guide

Michael Lynn


This guide was created to help you through the process of leveraging MongoDB as part of your hackathon project.

Mitigating the "fat-finger delete" with Queryable Backups

When a user accidentally deletes data sometimes the only way to retrieve that data is through a full database restore. In MongoDB Ops Manager and MongoDB Atlas, it is easy to make a client connection to a backup and perform read-only queries. No need to restore the backup either!

PyMongo Monday - Episode 3 - Update

This is part 4 of PyMongo Monday. Previously we have covered:

We are now into Update, the U in CRUD. The key aspect of update is the ability to change a document in place. In order for this to happen we must have some way to select the document and change parts of that document. In the pymongo driver this is achieved with two functions:

Each update operation can take a range of update operators that define how we can mutate a document during update.

Lets get a copy of the zipcode database hosted on MongoDB Atlas. As our copy hosted in Atlas is not writable we can't test update directly on it.

However, we can create a local copy with this simple script:

 $ mongodump --host demodata-shard-0/,, --ssl --username readonly --password readonly --authenticationDatabase admin --db demo
2018-10-22T01:18:35.330+0100    writing demo.zipcodes to
2018-10-22T01:18:36.097+0100    done dumping demo.zipcodes (29353 documents)

This will create a backup of the data in a dump directory in the current working directory.

to restore the data to a local mongod make sure you are running mongod locally and just run mongorestore in the same directory as you ran mongodump.

$ mongorestore
2018-10-22T01:19:19.064+0100    using default 'dump' directory
2018-10-22T01:19:19.064+0100    preparing collections to restore from
2018-10-22T01:19:19.066+0100    reading metadata for demo.zipcodes from dump/demo/zipcodes.metadata.json
2018-10-22T01:19:19.211+0100    restoring demo.zipcodes from dump/demo/zipcodes.bson
2018-10-22T01:19:19.943+0100    restoring indexes for collection demo.zipcodes from metadata
2018-10-22T01:19:20.364+0100    finished restoring demo.zipcodes (29353 documents)
2018-10-22T01:19:20.364+0100    done

You will now have a demo database on your local mongod with a single collection called zipcodes.

$ python
Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 03:03:55)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pymongo
>>> client = pymongo.MongoClient()
>>> database=client['demo']
>>> zipcodes=database["zipcodes"]
>>> zipcodes.find_one()
{'_id': '01001', 'city': 'AGAWAM', 'loc': [-72.622739, 42.070206], 'pop': 15338, 'state': 'MA'}

Each document in this database has the same format:

 '_id': '01001',                  # ZIP code
 'city': 'AGAWAM',                # City name
 'loc': [-72.622739, 42.070206],  # Geo Spatial Coordinates
 'pop': 15338,                    # Population of within zip code        
 'state': 'MA',                   # Two letter state code (MA = Massachusetts)

Let's say we want to change the population to reflect the most current value. Today the population of 01001 is approximately 16769. To change the value we would execute the following update.

>>> zipcodes.update( {"_id" : "01001"}, {"$set" : { "pop" : 16769}})
{'n': 1, 'nModified': 1, 'ok': 1.0, 'updatedExisting': True}
>>> zipcodes.find_one({"_id" : "01001"})
{'_id': '01001', 'city': 'AGAWAM', 'loc': [-72.622739, 42.070206], 'pop': 16769, 'state': 'MA'}

Here we see the $set operator in action. The $set operator will set a field to a new value or create that field if it doesn't exist in the document. We add a new field by doing:

>>> zipcodes.update_one( {"_id" : "01001"}, {"$set" : { "population_record" : []}})
<pymongo.results.UpdateResult object at 0x1042dc488>
>>> zipcodes.find_one({"_id" : "01001"})
{'_id': '01001', 'city': 'AGAWAM', 'loc': [-72.622739, 42.070206], 'pop': 16769, 'state': 'MA', 'population_record': []}

Here we are adding a new field called population_record. This field is an array field and has been set to the empty array for now. Now we can update the array with a history of the population for the ZIP Code area.

>>> zipcodes.update_one({"_id" : "01001"}, { "$push" : { "population_record" : { "pop" : 15338, "timestamp": None }}})
<pymongo.results.UpdateResult object at 0x106c210c8>
>>> zipcodes.find_one({"_id" : "01001"})
{'_id': '01001', 'city': 'AGAWAM', 'loc': [-72.622739, 42.070206], 'pop': 16769, 'state': 'MA', 'population_record': [{'pop': 15338, 'timestamp': None}]}
>>> from datetime import datetime
>>> zipcodes.update_one({"_id" : "01001"}, { "$push" : { "population_record" : { "pop" : 16769, "timestamp": datetime.utcnow() }}})
<pymongo.results.UpdateResult object at 0x106c21908>
>>> zipcodes.find_one({"_id" : "01001"})                                                                 
{'_id': '01001', 'city': 'AGAWAM', 'loc': [-72.622739, 42.070206], 'pop': 16769, 'state': 'MA', 'population_record': [{'pop': 15338, 'timestamp': None}, {'pop': 16769, 'timestamp': datetime.datetime(2018, 10, 22, 11, 37, 5, 60000)}]}
>>> x=zipcodes.find_one({"_id" : "01001"})
>>> x
{'_id': '01001', 'city': 'AGAWAM', 'loc': [-72.622739, 42.070206], 'pop': 16769, 'state': 'MA', 'population_record': [{'pop': 15338, 'timestamp': None}, {'pop': 16769, 'timestamp': datetime.datetime(2018, 10, 22, 11, 37, 5, 60000)}]}
>>> import pprint
>>> pprint.pprint(x)
{'_id': '01001',
 'city': 'AGAWAM',
 'loc': [-72.622739, 42.070206],
 'pop': 16769,
 'population_record': [{'pop': 15338, 'timestamp': None},
                       {'pop': 16769,
                        'timestamp': datetime.datetime(2018, 10, 22, 11, 37, 5, 60000)}],
 'state': 'MA'}

Here we have appended two documents to the array so that we have a history of the changes in population. The original value of 15338 was captured at an unknown time in the past so we set that timestamp to None. We updated the other value today so we can set that timestamp to the current time. In both cases we use the $push operator to push new elements onto the end of the array population_record.

You can see how we use pprint to produce the output in a slightly more readable format.

If we want to apply updates to more than one record we use update_many to apply changes to more than one document. Now if the filter applies to more than one document the changes will be applied to each document. So imagine we wanted to add the city sales tax to each city. First, we want to add the city sales tax to all the ZIP Code regions in New York.

>>> zipcodes.update_many( {'city': "NEW YORK"}, { "$set" : { "sales tax" : 4.5 }})
<pymongo.results.UpdateResult object at 0x1042dcd88>
>>> zipcodes.find( {"city": "NEW YORK"})
<pymongo.cursor.Cursor object at 0x101e09410>
>>> cursor=zipcodes.find( {"city": "NEW YORK"})
{u'city': u'NEW YORK', u'loc': [-73.996705, 40.74838], u'sales tax': 4.5, u'state': u'NY', u'pop': 18913, u'_id': u'10001'}
{u'city': u'NEW YORK', u'loc': [-73.987681, 40.715231], u'sales tax': 4.5, u'state': u'NY', u'pop': 84143, u'_id': u'10002'}
{u'city': u'NEW YORK', u'loc': [-73.989223, 40.731253], u'sales tax': 4.5, u'state': u'NY', u'pop': 51224, u'_id': u'10003'}

The final kind of update operation we want to talk about is upsert. We can add the upsert flag to any update operation to do an insert of the target document even when it doesn't match. When is this useful?

Imagine we have a read-only collection of ZIP Code data and we want to create a new collection (call it zipcodes_new) that contains updates to the ZIP Codes that contain changes in population.

As we collect new population stats ZIP Code by ZIP Code we want to update the zipcodes_new collection with new documents containing the updated ZIP Code data. In order to simplify this process we can do the updates as an upsert.

Below is a fragment of code from

zip_doc = zipcodes.find_one({"_id": args.zipcode})
zip_doc["pop"] = {"pop": args.pop, "timestamp":}
zipcodes_new.update({"_id":args.zipcode}, zip_doc, upsert=True)
print("New zipcode data: " + zip_doc["_id"])

The upsert=True flag ensures that if we don't match the initial clause {"_id":args.zipcode} we will still insert the zip_doc doc. This is a common pattern for upsert usage: Initially we insert based on a unique key. As the the number of inserts grows the likelihood that we will be updating an existing key as opposed to inserting a new key grows. the upsert=True flag allows us to handle both situations in a single update statement.

There is a lot more to update and I will return to update later in the series. For now just remember that update is generally used for mutating existing documents using a range of update operators.

Next time we will complete our first pass over CRUD operations with the final function, delete.

Using AWS Rekognition to Analyse and Tag Uploaded Images Using Stitch

Aydrian Howard

mongodb, aws

Computers can now look at a video or image and know what’s going on and, sometimes, who’s in it. Amazon Web Service Rekognition gives your applications the eyes it needs to label visual content. In the following, you can see how to use Rekognition along with MongoDB Stitch to supplement new content with information as it is inserted into the database.

You can easily detect labels or faces in images or videos in your MongoDB Stitch application using the built-in AWS service. Just add the AWS service and use the Stitch client to execute the AWS SES request right from your React.js application or create a Stitch function and Trigger. In a recent Stitchcraft live coding session on my Twitch channel, I wanted to tag an image using label detection. I set up a trigger that executed a function after an image was uploaded to my S3 bucket and its metadata was inserted into a collection.

exports = function(changeEvent) {
  const aws ='AWS');
  const mongodb ="mongodb-atlas");
  const insertedPic = changeEvent.fullDocument;

  const args = {
    Image: {
      S3Object: {
        Bucket: insertedPic.s3.bucket,
        Name: insertedPic.s3.key
    MaxLabels: 10,
    MinConfidence: 75.0

  return aws.rekognition()
    .then(result => {
      return mongodb
        .updateOne({_id: insertedPic._id}, {$set: {tags: result.Labels}});

With just a couple of service calls, I was able to take an image, stored in S3, analyse it with Rekognition, and add the tags to its document. Want to see how it all came together? Watch the recording on YouTube with the Github repo in the description. Follow me on Twitch to join me and ask questions live.

-Aydrian Howard
Developer Advocate

How to Integrate Azure Functions with MongoDB

MongoDB Atlas, the database as a service provided by the creators of MongoDB, is available on all the major cloud providers including Microsoft Azure. In this tutorial, I’ll cover the integration of Microsoft Azure Functions with MongoDB Atlas from a developer standpoint.

Attending PyGotham 2018

John Yu

John Yu, Software Engineer at MongoDB shares his experience attending PyGotham in October of 2018