Data Collection and DBMS

MongoDB Documents, CRUD, Queries and Language Bindings

PGCP-BDA

MongoDB document and collection

MongoDB stores BSON documents containing fields and nested values in collections, with flexible document structure and indexable paths.

BSON

BSON is MongoDB's binary document representation with explicit types such as date, decimal, binary data, array and embedded document.

MongoDB CRUD

MongoDB CRUD operations insert, find, update and delete documents, with filters selecting documents and update operators changing chosen fields.

query filter

A predicate that retains only rows or documents satisfying specified conditions.

projection

Projection selects required attributes or computes output expressions while excluding unneeded fields.

Projection controls returned fields:

db.products.find( {status: "ACTIVE"}, {name: 1, price: 1} )

In inclusion projection, _id remains included unless explicitly excluded:

{name: 1, price: 1, _id: 0}

Except for _id, inclusion and exclusion styles generally should not be mixed. Projection reduces network transfer and can support covered queries when an index contains all required filter and result fields.

update operator

A MongoDB operator such as $set or $inc that changes selected fields without replacing the entire document.

embedded document

A nested document stored inside another MongoDB document to keep data commonly read and updated together.

reference

A stored identifier that relates one document or row to another object maintained separately.

MongoDB language driver

A client library that lets an application connect to MongoDB, issue operations, handle BSON and manage sessions or transactions.

write concern

A MongoDB requirement for how many acknowledgements and what durability conditions must be met before a write succeeds.

MongoDB

MongoDB is a document database. It stores records as BSON documents grouped into collections. A database contains collections and a deployment can contain several databases.

The document model supports nested objects, arrays and varied fields. Design should still define required structure, types, identifiers, relationships and evolution rules.

MongoDB provides a query language, aggregation pipeline, indexes, replication, sharding, validation and transactions. Behavior depends on server version, topology, read concern, write concern and session options.

Reliable MongoDB Design

Model documents around bounded aggregates and required queries. Store consistent BSON types, validate important fields and use unique indexes for identity. Choose embedding for owned data read and changed together; choose references for independently shared or unbounded data.

For every update, verify whether one or many documents may match. Use atomic operators rather than read-modify-write cycles. Define deterministic sorting and keyset pagination. Inspect explain output and account for index write cost.

MongoDB's flexible document structure is valuable when paired with explicit contracts. Flexibility without validation, type consistency, bounded growth or migration rules merely moves schema problems into every application.

Update Operators

Common operators include:

db.products.updateOne( {sku: "BK-100", stock: {$gte: 2}}, {$inc: {stock: -2}} )

The combined filter and increment form an atomic conditional update on one document, preventing a separate read-then-write stock race.

Atomicity and Transactions

An update to one MongoDB document is atomic, even when it changes several fields or embedded values. This is one reason to embed data that forms one consistency unit.

MongoDB also supports multi-document transactions in supported replica-set and sharded configurations. They add coordination cost and should not compensate for a poor aggregate model.

Use conditional filters and inspect matched counts to detect concurrent conflicts. Configure read and write concerns according to durability and consistency needs.

Positional Array Updates

MongoDB supplies positional operators for matched array elements. The exact operator depends on whether the update targets the first match, all elements or elements satisfying array filters.

db.orders.updateOne( {_id: orderId}, {$set: {"items.$[item].status": "BACKORDERED"}}, {arrayFilters: [{"item.productId": productId}]} )

Test filters carefully so the intended elements are changed. Complex arrays often signal that aggregate boundaries need review.

Databases, Collections, Shell and Compass

In mongosh:

use training

The command selects a database context. A database or collection may be created lazily on the first write or a collection can be created explicitly with options:

db.createCollection("products")

MongoDB Compass is a graphical tool for connecting, browsing documents, constructing queries and aggregation pipelines, inspecting schema patterns and managing indexes.

Shell and Compass are clients. Authentication and server authorization govern what each connected account can do.

JSON and BSON

MongoDB interfaces display documents in a JSON-like syntax, while the stored binary representation is BSON.

BSON supports types beyond plain JSON, including ObjectId, Date, binary data, Decimal128, regular expression and multiple numeric types.

Type choice matters:

  • use Date for temporal instants rather than formatted strings;
  • use Decimal128 when exact decimal behavior is required;
  • distinguish integer and floating representations;
  • store identifiers consistently so queries and indexes compare matching types.

Two visually similar values of different BSON types may not compare as expected.

Equality and Comparison Filters

Direct field equality:

db.products.find({status: "ACTIVE"})

Comparison operators include:

  • $eq and $ne;
  • $gt and $gte;
  • $lt and $lte;
  • $in and $nin.

db.products.find({ price: {$gte: NumberDecimal("100.00"), $lte: NumberDecimal("500.00")} })

$in compares against a list:

{status: {$in: ["NEW", "PAID"]}}

Use consistent BSON types in both stored data and query values.

Deleting Documents

deleteOne removes at most one match:

db.products.deleteOne({sku: "BK-100"})

deleteMany removes all matches:

db.session.deleteMany({expiresAt: {$lt: new Date()}})

An empty deleteMany filter removes every document in the collection. Verify filters and deleted counts. Dropping a collection additionally removes its indexes and metadata and is not the same as deleting documents.

Logical Operators

Multiple fields in one filter are implicitly combined with AND:

{status: "ACTIVE", stock: {$gt: 0}}

Explicit operators include $and, $or, $nor and $not:

{ $or: [ {category: "BOOK"}, {price: {$lt: NumberDecimal("100.00")}} ] }

Use $and explicitly when the same field needs conditions that cannot be combined in one object or when generated query structure requires it.

Documents and the _id Field

Every standard collection document has a unique _id field. If an inserted document omits it, the driver or server normally generates an ObjectId.

{ _id: ObjectId("..."), sku: "BK-100", name: "Database Design", price: NumberDecimal("599.00"), tags: ["database", "design"], publisher: { name: "Example Press", city: "Pune" } }

MongoDB automatically creates a unique index on _id. Choose a custom _id only when its uniqueness, immutability, size and distribution suit the workload.

Inserting Documents

Insert one:

db.products.insertOne({ sku: "BK-100", name: "Database Design", price: NumberDecimal("599.00"), stock: 20 })

Insert several:

db.products.insertMany([ {sku: "BK-101", name: "SQL", stock: 10}, {sku: "BK-102", name: "MongoDB", stock: 15} ])

The result reports acknowledged status and inserted identifiers according to write concern. Ordered and unordered bulk behavior determines whether later operations continue after an error.

Array Updates

$push appends an array element:

{$push: {tags: "featured"}}

$addToSet adds only when an equal element is absent. $pull removes matching elements. $pop removes one end.

Modifiers with $push can add several values, limit length, sort and position insertion:

{ $push: { scores: { $each: [90, 95], $sort: -1, $slice: 10 } } }

Arrays that grow without a bound can make documents large and contentious. Move unbounded events to another collection.

Nested Fields

Dot notation addresses nested paths:

db.products.find({"publisher.city": "Pune"})

An exact equality comparison against an embedded document is sensitive to its complete value and field order. Dot-path predicates are usually better for individual nested properties.

Updates use the same path:

{$set: {"publisher.city": "Mumbai"}}

Without dot notation, setting publisher would replace the entire embedded object.

Upsert

An upsert updates a matching document or inserts a document when no match exists:

db.products.updateOne( {sku: "BK-103"}, { $set: {name: "Algorithms", price: NumberDecimal("499.00")}, $setOnInsert: {createdAt: new Date()} }, {upsert: true} )

The filter contributes equality fields to the inserted document under defined rules. Use a unique index on the logical identity to prevent concurrent upserts from creating duplicates.

$setOnInsert applies only to the insert branch.

Updating Documents

updateOne changes the first matching document, while updateMany changes all matches:

db.products.updateOne( {sku: "BK-100"}, {$set: {status: "ACTIVE"}} )

The result distinguishes matched and modified counts. A document can match even when the requested value already equals the stored value, producing a matched count without a modification.

Use a unique filter for updateOne when one known entity is intended. Otherwise “first” is not a stable identity rule.

Relational and MongoDB Vocabulary

Approximate analogies are:

Relational conceptMongoDB concept
databasedatabase
tablecollection
rowdocument
columnfield
primary identifier_id
indexindex

These are learning aids, not exact equivalences. Documents can nest arrays and objects, while relational rows are organized into declared columns and relationships.

Reading with find and findOne

find returns a cursor over matching documents:

db.products.find({stock: {$gt: 0}})

findOne returns one matching document or null:

db.products.findOne({sku: "BK-100"})

Without a sort, which matching document findOne returns is not a stable business rule. Use a unique filter or an explicit ordered query when identity matters.

An empty filter matches all documents:

db.products.find({})

Unique, Partial and TTL Indexes

A unique index enforces uniqueness:

db.products.createIndex({sku: 1}, {unique: true})

Missing and null behavior needs careful testing, particularly with sparse or partial options.

A partial index contains documents satisfying a filter and can reduce size when queries use the same condition.

A TTL index allows background expiration based on a date field. Deletion is asynchronous rather than exactly at the expiration instant, so it should not be used as a precise scheduler.

Replacement

replaceOne substitutes an entire document except for immutable _id:

db.products.replaceOne( {sku: "BK-100"}, { sku: "BK-100", name: "Database Design", price: NumberDecimal("649.00"), stock: 20 } )

Fields omitted from the replacement disappear. Use update operators for partial changes and replacement only when the caller intentionally supplies the complete new document.

Continue learning

Related notes

Put this topic into timed practice

Open mock tests when you want full-exam pacing, or keep drilling in practice mode.