Skip to the content

EXECUTED, WITH ASSERTIONS

This program was run during verification and its results asserted. The runner that does it is tools/run_mongo_labs.py.

The code

Straight from labs/course-10-mongodb/05_update.py, unchanged.

"""Experiment 5 — Update operators."""
from fixtures import fresh_db, names


def set_unset_inc_rename():
    db = fresh_db()

    db.students.update_one({"_id": 21}, {"$set": {"age": 21}})
    assert db.students.find_one({"_id": 21})["age"] == 21

    db.students.update_one({"_id": 21}, {"$set": {"marks.python": 85}})
    assert db.students.find_one({"_id": 21})["marks"]["python"] == 85, \
        "$set creates a nested field"

    r = db.students.update_many({"dept": "DS"}, {"$inc": {"marks.maths": 5}})
    assert r.modified_count == 3
    assert db.students.find_one({"_id": 21})["marks"]["maths"] == 93

    db.students.update_one({"_id": 21}, {"$inc": {"age": -1}})
    assert db.students.find_one({"_id": 21})["age"] == 20, "a negative $inc subtracts"

    db.students.update_one({"_id": 21}, {"$unset": {"active": ""}})
    assert "active" not in db.students.find_one({"_id": 21}), \
        "$unset REMOVES the field; its value is ignored"

    db.students.update_many({}, {"$rename": {"dept": "department"}})
    doc = db.students.find_one({"_id": 22})
    assert "department" in doc and "dept" not in doc

    print("  $set (incl. nested), $inc (incl. negative), $unset, $rename")


def several_operators_at_once():
    db = fresh_db()
    db.students.update_one({"_id": 22}, {
        "$set":   {"grade": "B"},
        "$inc":   {"age": 1},
        "$unset": {"active": ""}})
    d = db.students.find_one({"_id": 22})
    assert d["grade"] == "B" and d["age"] == 22 and "active" not in d
    print("  several operators combine in one update document")


def update_one_changes_exactly_one():
    """The commonest CRUD mistake: silent, and it reports success."""
    db = fresh_db()
    assert db.students.count_documents({"dept": "DS"}) == 3

    r = db.students.update_one({"dept": "DS"}, {"$set": {"flag": True}})
    assert r.modified_count == 1, "ONE, even though three matched"
    assert db.students.count_documents({"flag": True}) == 1

    db2 = fresh_db()
    r2 = db2.students.update_many({"dept": "DS"}, {"$set": {"flag": True}})
    assert r2.modified_count == 3
    assert db2.students.count_documents({"flag": True}) == 3

    print("  updateOne -> modifiedCount 1 of 3 matches; updateMany -> 3")
    print("       the command SUCCEEDS either way -- nothing warns you")


def replace_one_destroys_everything():
    db = fresh_db()
    before = db.students.find_one({"_id": 21})
    assert set(before) >= {"name", "dept", "marks", "subjects", "age", "active"}

    db.students.replace_one({"_id": 21}, {"name": "Asha K"})
    after = db.students.find_one({"_id": 21})

    assert set(after) == {"_id", "name"}, f"only _id and name survive: {set(after)}"
    assert after["name"] == "Asha K"

    # updateOne with $set preserves the rest.
    db2 = fresh_db()
    db2.students.update_one({"_id": 21}, {"$set": {"name": "Asha K"}})
    kept = db2.students.find_one({"_id": 21})
    assert "marks" in kept and "subjects" in kept and kept["name"] == "Asha K"

    print("  replaceOne left only {_id, name}; updateOne+$set kept everything")


def upsert_is_atomic():
    db = fresh_db()

    # First call: inserts.
    r = db.counters.update_one({"_id": "visits"},
                               {"$inc": {"count": 1},
                                "$setOnInsert": {"created": "2026-08-26"}},
                               upsert=True)
    assert r.upserted_id == "visits"
    assert db.counters.find_one({"_id": "visits"})["count"] == 1

    # Later calls: update, and $setOnInsert does NOT re-apply.
    for _ in range(4):
        db.counters.update_one({"_id": "visits"},
                               {"$inc": {"count": 1},
                                "$setOnInsert": {"created": "LATER"}},
                               upsert=True)
    doc = db.counters.find_one({"_id": "visits"})
    assert doc["count"] == 5
    assert doc["created"] == "2026-08-26", "$setOnInsert applies ONLY on insert"

    print("  upsert: inserted then incremented to 5; $setOnInsert applied once")


def find_one_and_update():
    db = fresh_db()
    from pymongo import ReturnDocument

    after = db.students.find_one_and_update(
        {"_id": 21}, {"$set": {"age": 22}},
        return_document=ReturnDocument.AFTER)
    assert after["age"] == 22, "returnDocument: 'after' gives the NEW document"

    db2 = fresh_db()
    before = db2.students.find_one_and_update({"_id": 21}, {"$set": {"age": 22}})
    assert before["age"] == 20, "the default returns the document BEFORE the update"

    print("  findOneAndUpdate returns the OLD document by default, or the new one")


def main():
    print("Experiment 5 -- Updating documents")
    # Step 1: $set, $unset, $inc and $rename
    set_unset_inc_rename()
    # Step 2: Several operators at once
    several_operators_at_once()
    # Step 3: See updateOne change exactly one
    update_one_changes_exactly_one()
    # Step 4: See replaceOne drop every other field
    replace_one_destroys_everything()
    # Step 5: Upsert
    upsert_is_atomic()
    # Step 6: findOneAndUpdate
    find_one_and_update()


if __name__ == "__main__":
    main()

Where this sits

One experiment from the Document Oriented Database lab. The rest of them, and the theory behind this one, are on the lab page.