Build MongoDB User Profiles

MongoDBBeginner
Practice Now

Introduction

In this lab, you will learn how to create and manage user profiles in MongoDB. You will start by designing a basic schema, then learn how to update documents, work with arrays for user interests, and manage complex nested settings. By the end of this lab, you will have a solid understanding of fundamental MongoDB data modeling concepts for building flexible and scalable user profiles in your applications.

Create a Basic User Profile

In this first step, you will create a new database and insert your first user profile document. This will establish the basic structure for storing user information.

First, open the MongoDB interactive shell from your terminal. This is the primary tool for interacting with your MongoDB database.

mongosh

Once inside the shell, you will see a test> prompt. Let's switch to a new database named userprofiles_db. If the database doesn't exist, MongoDB will create it for you when you first store data.

use userprofiles_db

Now, you will insert a document into a collection called profiles. A document in MongoDB is a BSON (binary JSON-like) structure, and a collection is a group of related documents.

Execute the following command to insert a profile for a user named johndoe.

db.profiles.insertOne({
  username: "johndoe",
  personal_info: {
    first_name: "John",
    last_name: "Doe",
    email: "john.doe@example.com"
  },
  metadata: {
    created_at: new Date(),
    account_status: "active"
  }
});

This command uses the insertOne() method to add a single document. The document contains a username, a nested personal_info object, and a metadata object to track the creation time and account status.

To confirm that the document was created successfully, you can use the find() method to retrieve it.

db.profiles.find({ username: "johndoe" });

You should see the document you just inserted, along with a unique _id field automatically added by MongoDB. The date and ObjectId will differ in your output.

[
  {
    _id: ObjectId('656f1a7b2e3a4c5d6e7f8b9a'),
    username: 'johndoe',
    personal_info: {
      first_name: 'John',
      last_name: 'Doe',
      email: 'john.doe@example.com'
    },
    metadata: {
      created_at: ISODate('2023-12-05T10:30:51.123Z'),
      account_status: 'active'
    }
  }
]

Add and Update Profile Information

In this step, you will learn how to modify an existing document. We will add more detailed contact information to the user profile created in the previous step.

We will use the updateOne() method to update the johndoe profile. This method takes two arguments: a filter to find the document to update, and an update document that specifies the changes.

Let's add a contact_details object. We will use the $set operator, which replaces the value of a field with the specified value. If the field does not exist, $set adds a new field.

db.profiles.updateOne(
  { username: "johndoe" },
  {
    $set: {
      contact_details: {
        phone: "+1-555-1234",
        address: {
          street: "123 Main St",
          city: "San Francisco",
          country: "USA"
        }
      },
      "metadata.last_updated": new Date()
    }
  }
);

In this command, we added a new contact_details object. We also used dot notation ("metadata.last_updated") to add a last_updated field to the existing metadata object without overwriting it. This is a powerful feature for updating nested fields.

Let's retrieve the document again to see the changes.

db.profiles.find({ username: "johndoe" });

The output will now show the newly added contact_details and the last_updated timestamp in the metadata.

[
  {
    _id: ObjectId('656f1a7b2e3a4c5d6e7f8b9a'),
    username: 'johndoe',
    personal_info: {
      first_name: 'John',
      last_name: 'Doe',
      email: 'john.doe@example.com'
    },
    metadata: {
      created_at: ISODate('2023-12-05T10:30:51.123Z'),
      account_status: 'active',
      last_updated: ISODate('2023-12-05T10:35:22.456Z')
    },
    contact_details: {
      phone: '+1-555-1234',
      address: {
        street: '123 Main St',
        city: 'San Francisco',
        country: 'USA'
      }
    }
  }
]

Work with Arrays in Profiles

User profiles often contain lists of items, such as interests, skills, or tags. MongoDB handles this efficiently using arrays. In this step, you will add and modify an array of interests in our user profile.

First, let's add an interests array to the johndoe profile using the $set operator.

db.profiles.updateOne(
  { username: "johndoe" },
  { $set: { interests: ["technology", "travel"] } }
);

Now, suppose the user develops a new interest. Instead of replacing the entire array, we can add a new element to it using the $push operator. This operator appends a specified value to an array and is more efficient for additions.

db.profiles.updateOne(
  { username: "johndoe" },
  { $push: { interests: "photography" } }
);

Let's view the updated profile to see the new interest. We can use projection in the find method to show only the username and interests fields. Setting a field to 1 includes it, and setting _id to 0 excludes it, which keeps the output clean.

db.profiles.find(
  { username: "johndoe" },
  { username: 1, interests: 1, _id: 0 }
);

The output will show the interests array with the newly added element.

[
  {
    "username": "johndoe",
    "interests": ["technology", "travel", "photography"]
  }
]

You can also query for users based on the elements in their arrays. For example, to find all users interested in "technology":

db.profiles.find({ interests: "technology" });

Manage Complex Nested Data

Real-world applications often require storing complex configurations, such as user settings. MongoDB's support for nested documents is ideal for this. In this step, you will add and update a detailed settings object in the profile.

First, let's add a settings object with nested fields for theme, language, and notifications.

db.profiles.updateOne(
  { username: "johndoe" },
  {
    $set: {
      settings: {
        theme: "dark",
        language: "en",
        notifications: {
          email: true,
          sms: false
        }
      }
    }
  }
);

Now, let's update a single nested field without rewriting the entire settings object. We can do this again using dot notation. Let's enable SMS notifications for the user.

db.profiles.updateOne(
  { username: "johndoe" },
  { $set: { "settings.notifications.sms": true } }
);

This command precisely targets the sms field within the nested notifications object and changes its value to true, leaving the rest of the settings object untouched.

To verify the change, let's retrieve just the settings object for our user using projection.

db.profiles.find({ username: "johndoe" }, { settings: 1, _id: 0 });

The output will show the updated settings object with sms now set to true.

[
  {
    "settings": {
      "theme": "dark",
      "language": "en",
      "notifications": { "email": true, "sms": true }
    }
  }
]

You have now completed the practical steps of this lab. To exit the MongoDB shell, you can type exit or press Ctrl+D.

exit;

Summary

In this lab, you have learned the fundamentals of building user profiles in MongoDB. You started by creating a basic user document and then progressed to updating it with new information using the $set operator. You also learned how to manage lists of data using arrays and the $push operator, and how to structure and modify complex configurations with nested documents using dot notation. These skills are essential for designing flexible and scalable schemas for any application that manages user data in MongoDB.