Sling Academy
Home/Python/MongoEngine: How to update embedded documents

MongoEngine: How to update embedded documents

Last updated: February 10, 2024

Introduction

When working with MongoDB through the MongoEngine ORM in Python, managing embedded documents efficiently becomes crucial for the integrity and performance of your database operations. Embedded documents are non-primitive data, such as dictionaries or lists, stored inside a MongoDB document. These documents provide a nested structure that can complicate updates if not handled properly. This tutorial will guide you through various methods of updating embedded documents using MongoEngine, progressing from basic techniques to more advanced practices.

Prerequisites

Before we dive into updating embedded documents, ensure you have the following setup:

  • MongoDB installed and running on your local machine or remote server.
  • Python and pip installed.
  • MongoEngine installed in your Python environment (`pip install mongoengine`).

Understanding the Document Structure

Let’s consider a blog application where each BlogPost document contains an embedded Author document.

from mongoengine import Document, EmbeddedDocument, fields

class Author(EmbeddedDocument):
    name = fields.StringField(required=True)
    email = fields.EmailField(required=True)

class BlogPost(Document):
    title = fields.StringField(required=True)
    content = fields.StringField()
    published_at = fields.DateTimeField()
    author = fields.EmbeddedDocumentField(Author)

Basic Updates

Updating embedded documents can be as simple as modifying an attribute and saving the document:

post = BlogPost.objects(title="Introduction to MongoEngine").first()
post.author.name = "New Author Name"
post.save()

This will update the author‘s name of the first post matching the title “Introduction to MongoEngine”.

Updating Multiple Fields at Once

Sometimes, you might want to update several fields of an embedded document simultaneously. MongoEngine’s update_one method along with the set__ operator allow you to do this:

BlogPost.objects(title="Introduction to MongoEngine").update_one(
    set__author__name="Jane Doe",
    set__author__email="[email protected]"
)

This updates both the name and email of the author embedded document.

Advanced Techniques

For more complex scenarios, such as updating an embedded document within an array, you can use a combination of MongoEngine queries and atomic updates:

class Comment(EmbeddedDocument):
    content = fields.StringField(required=True)
    author = fields.EmbeddedDocumentField(Author)

class BlogPost(Document):
    comments = fields.ListField(fields.EmbeddedDocumentField(Comment))

# Adding a comment
post = BlogPost.objects(title="Advanced MongoEngine").first()
post.comments.append(Comment(content="Great post!", author=Author(name="John Doe", email="[email protected]")))
post.save()

# Updating a comment's author
BlogPost.objects(comments__content="Great post!").update_one(
    set__comments__S__author__name="Jane Doe"
)

Updating Deeply Nested Documents

When dealing with deeply nested documents, you may need to use the positional $ operator combined with MongoEngine’s update methods to target the correct element for update:

Conclusion

Updating embedded documents in MongoEngine requires understanding of both the document structure and the available methods for manipulating these documents. From simple attribute changes to complex updates within nested arrays, MongoEngine provides a flexible interface for managing your MongoDB data. As you become more familiar with these techniques, you’ll find that managing embedded documents is both powerful and efficient.

Next Article: MongoEngine: How to convert a document to JSON

Previous Article: MongoEngine: Filter Documents by Multiple Fields

Series: Data Persistence in Python – Tutorials & Examples

Python

You May Also Like

  • Python Warning: Secure coding is not enabled for restorable state
  • Python TypeError: write() argument must be str, not bytes
  • 4 ways to install Python modules on Windows without admin rights
  • Python TypeError: object of type ‘NoneType’ has no len()
  • Python: How to access command-line arguments (3 approaches)
  • Understanding ‘Never’ type in Python 3.11+ (5 examples)
  • Python: 3 Ways to Retrieve City/Country from IP Address
  • Using Type Aliases in Python: A Practical Guide (with Examples)
  • Python: Defining distinct types using NewType class
  • Using Optional Type in Python (explained with examples)
  • Python: How to Override Methods in Classes
  • Python: Define Generic Types for Lists of Nested Dictionaries
  • Python: Defining type for a list that can contain both numbers and strings
  • Using TypeGuard in Python (Python 3.10+)
  • Python: Using ‘NoReturn’ type with functions
  • Type Casting in Python: The Ultimate Guide (with Examples)
  • Python: Using type hints with class methods and properties
  • Python: Typing a function with default parameters
  • Python: Typing a function that can return multiple types