Courseiva

CCNA CRUD Operations Questions

26 questions · CRUD Operations · All types, answers revealed

1
MCQhard

A MongoDB application stores inventory documents in the 'inventory' collection with fields 'sku', 'on_hand', and 'reserved'. During a flash sale, many concurrent sessions must decrement 'on_hand' by 1 only when on_hand is greater than 0, and each successful decrement must return the resulting document to the client. Which approach guarantees this behavior?

A.db.inventory.findOneAndUpdate({ sku: 'A100', on_hand: { $gt: 0 } }, { $inc: { on_hand: -1 } }, { returnDocument: 'after' })
B.db.inventory.bulkWrite([{ updateOne: { filter: { sku: 'A100', on_hand: { $gt: 0 } }, update: { $inc: { on_hand: -1 } } } }])
C.db.inventory.find({ sku: 'A100', on_hand: { $gt: 0 } }) followed by db.inventory.updateOne({ sku: 'A100' }, { $inc: { on_hand: -1 } })
D.db.inventory.updateOne({ sku: 'A100', on_hand: { $gt: 0 } }, { $inc: { on_hand: -1 } }, { returnDocument: 'after' })
AnswerA

findOneAndUpdate atomically matches the filter, applies the decrement, and returns the document. With returnDocument: 'after' the client receives the post-decrement state, and the on_hand: { $gt: 0 } filter prevents negative stock. This single atomic operation satisfies both the conditional decrement and the requirement to return the updated document.

Why this answer

findOneAndUpdate performs the conditional match, the $inc decrement, and the return of the document in one atomic operation. The on_hand: { $gt: 0 } filter guards against negative inventory under concurrency, and returnDocument: 'after' supplies the resulting state. Separating read and write, or using updateOne or bulkWrite, either introduces races or fails to return the document.

Exam trap

The trap here is assuming updateOne can return the modified document or that a separate find before an update is safe under concurrency.

2
Multi-Selectmedium

A developer is troubleshooting a Python application that uses the MongoDB driver to query the 'products' collection with find({'category': 'tools'}). Which two statements about the returned cursor are correct? (Choose two.)

Select 2 answers
A.The cursor loads all matching documents into client memory immediately when find is called.
B.The cursor returns documents in an order guaranteed by the storage engine, so no explicit sort is needed.
C.The cursor automatically closes when it is exhausted, but must be closed explicitly if iteration stops early.
D.The cursor is invalidated and re-executed automatically whenever the underlying collection is modified by another client.
E.The cursor is lazy; documents are fetched from the server in batches as the application iterates over it.
AnswersC, E

When a cursor is fully iterated, the driver closes it and releases the server-side cursor. If the application stops early, the cursor remains open until it times out server-side or is closed explicitly with close(). Failing to close cursors can leak server resources in long-running applications.

Why this answer

Cursors are lazy and fetch documents in batches during iteration, and they close automatically when exhausted but require explicit close() if iteration stops early. They do not eagerly load all matches, do not automatically re-execute on concurrent writes, and do not guarantee any result order without an explicit sort. These properties affect both memory use and server resource management.

Exam trap

The trap here is assuming find eagerly loads everything or guarantees an ordering, when cursors are lazy and unordered without an explicit sort.

3
MCQmedium

A logistics application stores shipment documents in the 'shipments' collection. Each document has a 'packages' array of embedded subdocuments, each with a 'trackingCode' field. A developer needs to remove only the embedded subdocument whose 'trackingCode' equals 'TRK-9981' from the document with '_id' 42, leaving all other packages untouched. Which update operation should be used?

A.db.shipments.updateOne({ _id: 42 }, { $pull: { packages: { trackingCode: "TRK-9981" } } })
B.db.shipments.updateOne({ _id: 42 }, { $pullAll: { packages: ["TRK-9981"] } })
C.db.shipments.updateOne({ _id: 42, "packages.trackingCode": "TRK-9981" }, { $unset: { "packages.$": "" } })
D.db.shipments.updateOne({ _id: 42 }, { $pop: { packages: 1 } })
AnswerA

The $pull operator removes every array element that matches the supplied condition, so this deletes only the embedded package whose trackingCode equals TRK-9981 while preserving the rest of the array and the parent document. The filter on _id restricts the update to the intended shipment, making this the precise and minimal operation for the scenario.

Why this answer

The $pull operator deletes array elements that match a specified condition or value, which is exactly what removing a single embedded subdocument by its trackingCode requires. $pop and $pullAll operate positionally or on exact element values and cannot target a nested field match, while $unset would leave a null placeholder instead of deleting the element.

Exam trap

The trap here is assuming that $unset deletes an array element, when it actually replaces the matched element with null and leaves the array length unchanged.

4
MCQmedium

An inventory collection stores documents with a numeric 'quantity' field. A warehouse system must decrement quantity by 5 on a specific item, and if the field is missing it should be created starting from the decremented value. Which update operator and command achieve this?

A.db.inventory.updateOne({ sku: "A1" }, { $push: { quantity: -5 } })
B.db.inventory.updateOne({ sku: "A1" }, { $mul: { quantity: -5 } })
C.db.inventory.updateOne({ sku: "A1" }, { $inc: { quantity: -5 } })
D.db.inventory.updateOne({ sku: "A1" }, { $set: { quantity: -5 } })
AnswerC

$inc adds the given value to the field, so -5 decrements quantity by five. If the field does not exist, $inc creates it and sets it to the specified negative value, satisfying the requirement. updateOne() targets the single matching item, which is correct for adjusting one SKU's stock.

Why this answer

$inc performs atomic relative addition, so a negative value decrements the field and creates it when absent. $set replaces the value outright, $mul scales instead of subtracting, and $push targets arrays rather than numeric fields, so none of those meet the decrement requirement.

Exam trap

The trap here is confusing relative updates like $inc with absolute assignments like $set, which overwrite rather than adjust.

5
MCQmedium

You are designing an e-commerce catalog where products can have a dynamic array of tags. You need to query for documents where the 'tags' array contains both 'electronics' and 'sale' simultaneously, regardless of their order or other elements. Which query operator should you use?

A.{ tags: { $in: ['electronics', 'sale'] } }
B.{ tags: { $all: ['electronics', 'sale'] } }
C.{ tags: ['$electronics', '$sale'] }
D.{ tags: { $elemMatch: { $eq: 'electronics', $eq: 'sale' } } }
AnswerB

$all matches documents whose tags array contains every listed element, independent of order, duplicates or extra values. That precisely satisfies the requirement for simultaneous presence of both 'electronics' and 'sale', which a simple equality match cannot guarantee.

Why this answer

The $all operator selects the documents where the value of a field is an array that contains all the specified elements. This is essential when searching arrays for multiple matching criteria without enforcing strict positional indexing or exact array equality.

Exam trap

Candidates often mistakenly use the $in operator, which matches documents containing at least one of the values, rather than the $all operator, which requires all specified elements to exist.

6
MCQmedium

A logistics application stores shipment records in the 'shipments' collection. Each document includes a 'status' field and a 'deliveredAt' field (a Date). A developer must set 'deliveredAt' to the current date and time for every shipment whose 'status' is 'in_transit' and whose 'carrier' is 'FastShip'. Which operation satisfies this requirement with a single command?

A.db.shipments.updateOne({ status: 'in_transit', carrier: 'FastShip' }, { $set: { deliveredAt: new Date() } })
B.db.shipments.updateMany({ status: 'in_transit', carrier: 'FastShip' }, { $set: { deliveredAt: new Date() } })
C.db.shipments.replaceMany({ status: 'in_transit', carrier: 'FastShip' }, { deliveredAt: new Date() })
D.db.shipments.findAndModify({ query: { status: 'in_transit', carrier: 'FastShip' }, update: { $set: { deliveredAt: new Date() } }, multi: true })
AnswerB

updateMany applies the $set update operator to every document matching the filter { status: 'in_transit', carrier: 'FastShip' }, writing the current date into deliveredAt. The filter combines both conditions with implicit AND, which matches the requirement exactly and updates all qualifying shipments in one round trip.

Why this answer

The requirement is a filtered, multi-document field update, which maps directly to updateMany with the $set operator. The filter expresses both conditions, and $set preserves the existing document structure while adding or overwriting deliveredAt. The single-document helpers leave other matches untouched, and replacement operations would remove the untouched fields.

Exam trap

The trap here is assuming updateOne updates all matching documents, when it actually modifies only the first match found.

7
MCQhard

An analytics job updates counters in the 'metrics' collection with db.metrics.updateOne({ metric: "visits" }, { $inc: { count: 1 } }). The job runs with write concern w:1 against a three-node replica set, and a failover occurs immediately after the primary acknowledges a write. The developer reports that a counter increment appears to be lost. Which statement best explains this outcome?

A.$inc is not atomic on a replica set, so two nodes can apply the increment independently and produce a divergent count value.
B.The update used an equality filter on 'metric', so the query planner could not use an index and the write was silently skipped under load.
C.With w:1 the primary acknowledged before the update was replicated, so if it stepped down and rolled back, the increment could be undone on the new primary.
D.Because the collection has no unique index on 'metric', the increment was applied to multiple documents and the count became ambiguous.
AnswerC

Write concern w:1 acknowledges after the primary applies the write to its own journal, not after replication to secondaries. If the primary steps down before the operation replicates and the new primary never received it, the old primary rolls the write back when it rejoins. That rollback is exactly how an acknowledged increment can appear lost under failover.

Why this answer

Write concern w:1 confirms the write only on the primary. If that primary fails before the operation reaches any secondary, the new primary never has the change, and the old primary rolls it back upon rejoining, so an acknowledged increment can disappear. Stronger write concern such as majority prevents this by requiring replication before acknowledgement.

Exam trap

The trap here is treating w:1 as durable across failover, when it only guarantees the primary applied the write locally before acknowledging.

8
MCQmedium

A reporting service reads from the 'sensor_readings' collection, which contains millions of documents. The service runs a query that filters on 'deviceId' and returns results sorted by 'recordedAt' descending. The query performs a collection scan and an in-memory sort, causing high memory usage. Which index should you create to allow the query to use an index for both filtering and sorting?

A.db.sensor_readings.createIndex({ recordedAt: -1, deviceId: 1 })
B.db.sensor_readings.createIndex({ deviceId: 1 })
C.db.sensor_readings.createIndex({ deviceId: 1, recordedAt: -1 })
D.db.sensor_readings.createIndex({ recordedAt: 1 })
AnswerC

This index matches the query pattern: an equality field (deviceId) followed by the sort field (recordedAt) in the same direction as the sort. MongoDB can use the index prefix for the equality filter and then return entries already ordered by recordedAt descending, eliminating the in-memory sort and reducing memory pressure for the reporting service.

Why this answer

The optimal index follows the equality-sort-range rule: equality fields first, then the sort field. Because the query filters on deviceId with equality and sorts on recordedAt descending, a compound index { deviceId: 1, recordedAt: -1 } lets MongoDB use the prefix for filtering and read entries in the requested sort order, avoiding the blocking in-memory sort and its memory overhead.

Exam trap

The trap here is assuming the sort field must always be the first key in a compound index, when an equality filter field should precede the sort key for the index to serve both operations.

9
MCQmedium

A sensor platform writes readings to the 'readings' collection. A developer needs to insert three documents in a single operation and have the server process them in the given order, stopping at the first error rather than continuing. Which insert command should be used?

A.db.readings.insertMany([doc1, doc2, doc3], { ordered: true })
B.db.readings.insertMany([doc1, doc2, doc3], { ordered: false })
C.db.readings.insertOne([doc1, doc2, doc3])
D.db.readings.bulkWrite([{ insertOne: { document: doc1 } }, { insertOne: { document: doc2 } }])
AnswerA

insertMany() with ordered set to true inserts documents sequentially and halts on the first failure, leaving subsequent documents unprocessed. Since ordered defaults to true, this explicitly satisfies the requirement to stop at the first error. It is the correct choice when insertion sequence matters and partial success is acceptable only up to the failing document.

Why this answer

An ordered insertMany() writes documents in sequence and stops at the first error, matching the requirement. Unordered insertion continues past failures, insertOne() handles only one document, and bulkWrite() is intended for mixed operations and here omits a document.

Exam trap

The trap here is forgetting that insertMany() is ordered by default and that ordered:false deliberately continues after errors.

10
MCQeasy

A developer needs to insert a single document into the 'inventory' collection and wants the operation to return the generated _id value in the result. Which method should be used?

A.db.inventory.insertOne({ item: 'canvas', qty: 100 })
B.db.inventory.update({ item: 'canvas' }, { qty: 100 }, { upsert: true })
C.db.inventory.insertMany([{ item: 'canvas', qty: 100 }])
D.db.inventory.save({ item: 'canvas', qty: 100 })
AnswerA

insertOne inserts a single document and returns an InsertOneResult object that includes the acknowledged flag and the insertedId field. This gives the developer immediate access to the generated _id without an extra query, which is exactly what the scenario requires for a single-document insert.

Why this answer

insertOne is the purpose-built method for adding a single document and returns an InsertOneResult whose insertedId field exposes the generated or supplied _id. This satisfies the requirement to obtain the identifier immediately, without a follow-up find or relying on deprecated methods such as save or update.

Exam trap

The trap here is choosing a bulk or deprecated write method for a single-document insert, overlooking that insertOne returns the insertedId directly in its result object.

11
Multi-Selectmedium

A developer is querying the 'events' collection to retrieve documents and needs to control which fields are returned to reduce network payload. Which two statements about projection in MongoDB find() operations are correct? (Choose two.)

Select 2 answers
A.A projection cannot exclude the _id field under any circumstance because it is mandatory in every query result.
B.Setting _id to 0 in an inclusion projection removes the _id field from the returned documents while still returning the other included fields.
C.A projection may freely mix inclusion and exclusion fields as long as at least one field is set to 1 and at least one is set to 0.
D.A projection can include specific fields by setting them to 1 and exclude others by setting them to 0, but inclusion and exclusion cannot be mixed in the same projection, with the exception of the _id field.
E.Projection reduces the size of documents written to disk, so it permanently shrinks the stored data for the collection.
AnswersB, D

The _id field is special: it is returned by default, but setting _id: 0 explicitly excludes it even when other fields are included. This lets applications drop the identifier while keeping selected fields. It is the documented exception to the mixing rule for projections.

Why this answer

Projection operates in either inclusion or exclusion mode, never both, with _id as the sole exception that can be suppressed alongside included fields. Projection only shapes query results and does not alter stored documents, and _id can indeed be excluded.

Exam trap

The trap here is believing inclusion and exclusion fields can be mixed freely or that projection changes stored data.

12
MCQmedium

A logistics MongoDB deployment has a 'shipments' collection. A nightly job must remove the 'tracking_history' array element whose 'status' is 'cancelled' from every document where 'carrier' is 'DHL', without deleting the documents themselves. Which update operation should the developer run?

A.db.shipments.updateMany({ carrier: 'DHL' }, { $pop: { tracking_history: { status: 'cancelled' } } })
B.db.shipments.deleteMany({ carrier: 'DHL', 'tracking_history.status': 'cancelled' })
C.db.shipments.updateMany({ carrier: 'DHL' }, { $pull: { tracking_history: { status: 'cancelled' } } })
D.db.shipments.updateMany({ carrier: 'DHL' }, { $unset: { 'tracking_history.status': 'cancelled' } })
AnswerC

The $pull operator removes all array elements matching a condition, so specifying { status: 'cancelled' } strips only those entries from tracking_history. Combining it with updateMany and a carrier filter applies the change to every matching document. This satisfies the requirement to delete array elements without removing documents.

Why this answer

The $pull operator is designed to remove array elements that match a specified condition, so using it with updateMany and a carrier filter deletes only the cancelled tracking_history entries from every DHL shipment. Operations like deleteMany or $pop either remove whole documents or the wrong array elements, and $unset cannot filter by element values.

Exam trap

The trap here is confusing $unset, which drops a field, with $pull, which removes array elements matching a condition.

13
MCQhard

A banking application must atomically transfer funds between two account documents in the 'accounts' collection. The transfer decreases the balance of the source account and increases the balance of the destination account, and both changes must succeed or neither should be applied. The deployment is a replica set. Which approach guarantees this atomicity?

A.Embed both account balances in a single document and use updateOne with $inc on both fields.
B.Use a session and start a transaction with session.startTransaction(), update both accounts within the session, then commitTransaction().
C.Perform two sequential updateOne calls, first on the source and then on the destination, and check the result of each.
D.Use updateMany with a filter matching both account _id values and apply $inc to the balance field.
AnswerB

Multi-document transactions in MongoDB provide atomicity across operations in the same session. By starting a transaction, performing both updates with the session, and committing, either all changes are applied or the transaction aborts and none are. This is the supported mechanism for atomic cross-document updates on a replica set.

Why this answer

Multi-document transactions are the correct tool when atomicity must span more than one document. Starting a transaction on a session, performing the debit and credit updates with that session, and committing ensures the operations either all commit or all abort. On a replica set this provides the all-or-nothing behavior the banking scenario demands.

Exam trap

The trap here is assuming that two sequential updates are effectively atomic because each is individually atomic, when atomicity does not extend across separate write operations.

14
MCQeasy

A logistics application stores shipment records in the 'shipments' collection. A developer must delete all shipment documents whose 'status' field equals 'cancelled'. Which command correctly performs this operation?

A.db.shipments.deleteOne({ status: "cancelled" })
B.db.shipments.deleteMany({ status: "cancelled" })
C.db.shipments.remove({ status: "cancelled" })
D.db.shipments.drop({ status: "cancelled" })
AnswerB

deleteMany() removes every document matching the filter, so passing the equality filter { status: "cancelled" } deletes all cancelled shipments in one operation. It returns a result document with the deletedCount, confirming how many records were removed. This is the direct, idiomatic way to purge a subset of documents based on a field value.

Why this answer

Deleting a subset of documents based on field equality requires deleteMany() with the filter, which removes all matches and reports deletedCount. deleteOne() would remove only one record, the deprecated remove() is unavailable on current servers, and drop() eliminates the entire collection rather than matching documents.

Exam trap

The trap here is assuming the legacy remove() method still works or that deleteOne() deletes all matches.

15
MCQhard

A document in the 'profiles' collection has an embedded array 'contacts' of subdocuments, each with 'type' and 'value' fields. A developer must change the 'value' of the subdocument whose 'type' is 'email' without altering any other array element. Which update is correct?

A.db.profiles.updateOne({ _id: 1 }, { $set: { "contacts.$[elem].value": "new@x.com" } }, { arrayFilters: [{ "elem.type": "email" }] })
B.db.profiles.updateOne({ _id: 1 }, { $set: { "contacts.$.value": "new@x.com" } })
C.db.profiles.updateOne({ _id: 1 }, { $set: { contacts: [{ type: "email", value: "new@x.com" }] } })
D.db.profiles.updateOne({ _id: 1 }, { $set: { "contacts.0.value": "new@x.com" } })
AnswerA

The positional filtered operator $[elem] combined with arrayFilters updates only array elements matching the filter, so just the email subdocument's value changes. This is the precise tool when an array contains mixed element types and only some should be modified. It avoids touching phone or other entries.

Why this answer

The filtered positional operator with arrayFilters matches subdocuments by condition, so only the email element changes. A hardcoded index may hit the wrong entry, the plain positional operator needs an array condition in the query, and replacing the whole array deletes other contacts.

Exam trap

The trap here is using the plain positional operator or a numeric index when the element must be selected by a field condition.

16
MCQmedium

A developer is writing a Python application using the official MongoDB driver to insert a single document into the 'inventory' collection. They call `inventory.insert_one({'sku': 'A100', 'qty': 5})`. Which statement accurately describes what happens?

A.The driver performs an upsert automatically, so if a document with the same sku exists it replaces it.
B.The server rejects the insert because the document lacks an explicit _id field, requiring the application to supply one.
C.The document is written only to the driver's local buffer and flushed to the server when the client closes the connection.
D.The driver sends an insert command; MongoDB adds the document with a generated _id and returns an InsertOneResult containing the inserted_id.
AnswerD

insert_one() sends an insert command to the server, which generates an _id if omitted and stores the document. The driver returns an InsertOneResult object whose inserted_id attribute holds the generated ObjectId, letting the application reference the new document later. This is the documented behavior of the PyMongo insert_one method for a single-document write acknowledged by the server.

Why this answer

The insert_one method inserts a single document and returns an InsertOneResult whose inserted_id exposes the generated identifier. It does not upsert, does not defer writes to connection close, and does not require the application to provide _id. Understanding this return object matters because applications commonly need the generated _id to link related documents or respond to clients.

Exam trap

The trap here is assuming insert_one performs an upsert or requires an explicit _id, when it is a plain insert with a driver-generated identifier.

17
MCQmedium

An application needs to update a user document in the 'users' collection. If the document does not exist, a new document must be inserted using fields from both the filter and the update document. Which parameter accomplishes this behavior in MongoDB?

A.Setting the { writeConcern: { w: 'majority' } } option during the update operation.
B.Setting the { returnDocument: 'after' } option in the findOneAndUpdate method.
C.Setting the { upsert: true } option in updateOne or findOneAndUpdate.
D.Setting the { multi: true } option to force updates across multiple matching records.
AnswerC

Upsert combines update and insert semantics in one atomic operation: when no document matches the filter, MongoDB inserts a new document built from the filter equality fields plus the update operators. This exactly meets the requirement to insert using fields from both documents.

Why this answer

The upsert option instructs MongoDB to insert a new document if no existing document matches the query filter. When combined with update operators, the final document is constructed by merging the query filter with the update operators, which is crucial for idempotent bootstrapping patterns.

Exam trap

Candidates often forget that an upsert merges the query filter and the update document, sometimes incorrectly assuming it only inserts the update document when a match is not found.

18
MCQmedium

A logistics application stores shipment events in the 'shipments' collection. Each document contains a field 'events' that is an array of subdocuments with fields 'status' and 'timestamp'. You need to remove the subdocument where 'status' equals 'cancelled' from all documents in the collection, without affecting other array elements. Which update operation should you use?

A.db.shipments.updateMany({}, { $pull: { events: { status: 'cancelled' } } })
B.db.shipments.updateMany({}, { $pullAll: { events: [{ status: 'cancelled' }] } })
C.db.shipments.updateMany({}, { $unset: { events: { status: 'cancelled' } } })
D.db.shipments.updateMany({}, { $pop: { events: { status: 'cancelled' } } })
AnswerA

The $pull operator removes all array elements that match a specified condition. Here, it removes subdocuments where status equals 'cancelled' from the 'events' array in every document. It does not affect other array elements, and updateMany applies the change to all matching documents. This is the correct tool for removing specific array elements based on a field value.

Why this answer

The $pull operator is designed to remove array elements that match a specified condition, making it ideal for removing subdocuments based on a field value. It works with updateMany to affect all documents. Other operators like $unset, $pop, and $pullAll do not support conditional removal of subdocuments based on a field, so they would not achieve the desired result.

Exam trap

The trap here is confusing $pull with $pullAll, assuming that $pullAll can remove subdocuments by a single field match, but it requires exact element matches.

19
MCQeasy

A developer is exploring a 'reviews' collection and wants to retrieve only the 'author' and 'rating' fields from every review document, without the _id field, to reduce the payload sent to the application. Which query accomplishes this?

A.db.reviews.find({}, { author: true, rating: true })
B.db.reviews.aggregate([{ $project: { author: 0, rating: 0, _id: 0 } }])
C.db.reviews.find({ author: 1, rating: 1, _id: 0 })
D.db.reviews.find({}, { author: 1, rating: 1, _id: 0 })
AnswerD

The second argument of find is the projection document. Setting author and rating to 1 includes only those fields, and _id: 0 explicitly suppresses the default inclusion of _id, producing exactly the reduced payload the developer wants.

Why this answer

Projection is the second parameter of find, and mixing inclusion values with _id: 0 is the standard way to return a subset of fields without the identifier. Passing fields as the first argument turns them into a filter, and using exclusion values in a projection drops the very fields the developer needs.

Exam trap

The trap here is confusing the query filter argument with the projection argument, since both are plain documents.

20
MCQmedium

A support ticketing system stores documents in the 'tickets' collection. An operator wants to add a new field 'priority' set to 'high' only for tickets whose 'status' is 'open' and that do not already have a 'priority' field. The update must not create any new documents and must not modify tickets that already have a 'priority' field. Which update operation should be used?

A.db.tickets.updateMany({ status: 'open' }, { $set: { priority: 'high' } }, { upsert: true })
B.db.tickets.replaceOne({ status: 'open', priority: { $exists: false } }, { status: 'open', priority: 'high' })
C.db.tickets.updateMany({ status: 'open', priority: { $exists: false } }, { $set: { priority: 'high' } })
D.db.tickets.updateMany({ status: 'open', priority: { $exists: false } }, { $setOnInsert: { priority: 'high' } })
AnswerC

This operation uses updateMany with a filter that matches only open tickets lacking a priority field, and $set adds the field without inserting new documents. Because the filter includes $exists: false, tickets that already have priority are untouched, and updateMany never performs an upsert unless explicitly requested, so no new documents are created.

Why this answer

The correct operation must update multiple open tickets that lack a priority field, add the field without overwriting existing values, and avoid creating new documents. Using updateMany with a filter that includes $exists: false and a $set modifier satisfies all conditions. Operators like $setOnInsert or upsert options are designed for insert scenarios and would either do nothing or risk unintended inserts, while replaceOne would remove other fields.

Exam trap

The trap here is assuming that $setOnInsert updates existing documents or that upsert: true is needed to add a new field, when in fact $set with a precise filter is sufficient and safer.

21
MCQeasy

A reporting service reads from the 'sensors' collection, which holds millions of documents each containing an 'active' boolean field. The service queries only for documents where 'active' is true and reads a handful of fields. A developer wants the query to avoid scanning documents that are inactive. Which index should be created to support this access pattern most directly?

A.db.sensors.createIndex({ active: 1 }, { sparse: true })
B.db.sensors.createIndex({ _id: 1, active: 1 })
C.db.sensors.createIndex({ active: 1 })
D.db.sensors.createIndex({ active: "text" })
AnswerC

A single-field ascending index on 'active' lets the query planner satisfy the equality predicate on that field by scanning only the matching index entries and fetching the corresponding documents. Because the filter is a simple equality on one field, this index directly narrows the candidate set and avoids a full collection scan for the inactive documents.

Why this answer

An equality filter on a single boolean field is best served by a single-field index on that field, which allows the planner to seek directly to the matching entries and fetch only relevant documents. A compound index led by _id, a text index, or a sparse variant cannot provide that access path, because the query does not supply a usable prefix or field type for those structures.

Exam trap

The trap here is believing a sparse index reduces work when the field is present in every document, when sparse only excludes documents that omit the field.

22
MCQhard

A developer queries the 'events' collection with db.events.find({ tags: { $in: ["sports", "music"] } }) and observes a COLLSCAN in explain output even though an index exists on the 'tags' array field. The collection holds a few hundred documents. Which explanation best accounts for the planner choosing a collection scan?

A.COLLSCAN appears whenever a query returns more than one document, because index scans are limited to single-document lookups.
B.A multikey index cannot answer $in queries, so the planner ignores the tags index and falls back to a collection scan.
C.The index on 'tags' is invalid because arrays cannot be indexed directly, so it must be rebuilt as a compound index with _id first.
D.The query planner may prefer a collection scan when the collection is small, because the estimated cost of scanning is lower than the overhead of using a multikey index.
AnswerD

The planner compares candidate plans by cost. For a very small collection, the estimated work of a full scan can be lower than traversing a multikey index and performing the associated fetches, so the planner legitimately selects COLLSCAN. The index is usable, but not chosen because it is not cheaper for this data size.

Why this answer

Query plan selection is cost-based. With a few hundred documents, the estimated cost of a full collection scan can be lower than the cost of using a multikey index plus document fetches, so the planner may reasonably choose COLLSCAN. As the collection grows, or with a more selective predicate, the same index is likely to be selected.

Exam trap

The trap here is concluding the index is unusable or invalid from a COLLSCAN, when the planner may simply judge a full scan cheaper on a small collection.

23
MCQhard

A blog platform stores posts in the 'posts' collection. Each document has an array field 'comments' containing subdocuments with fields 'author' and 'text'. You need to add a new comment to the 'comments' array of a specific post identified by its '_id'. The new comment should be appended to the end of the array. Which update operation should you use?

A.db.posts.updateOne({ _id: postId }, { $set: { comments: { author: 'user1', text: 'Great post!' } } })
B.db.posts.updateOne({ _id: postId }, { $push: { comments: { author: 'user1', text: 'Great post!' } } })
C.db.posts.updateOne({ _id: postId }, { $addToSet: { comments: { author: 'user1', text: 'Great post!' } } })
D.db.posts.updateOne({ _id: postId }, { $concat: { comments: { author: 'user1', text: 'Great post!' } } })
AnswerB

The $push operator appends a specified value to an array. Here, it adds the new comment subdocument to the 'comments' array. This is the correct and efficient way to add an element to an array without needing to read and rewrite the entire document. It works atomically.

Why this answer

The $push operator is specifically designed to append values to an array. It adds the new comment subdocument to the 'comments' array without affecting existing elements. The other options either prevent duplicates, overwrite the array, or use an invalid operator. $push is the standard and correct choice for this scenario.

Exam trap

The trap here is confusing $push with $addToSet, which only adds if the element is not already present, but comments can be duplicated.

24
MCQeasy

A developer wants to remove all documents from the 'logs' collection where the 'level' field equals 'debug'. The collection has an index on level. Which operation should be used, and what does it return?

A.deleteMany({ level: 'debug' }) returns a result whose deletedCount is the number of documents removed.
B.drop() removes the collection and its index, which is the recommended way to clear matching documents.
C.deleteOne({ level: 'debug' }) returns the number of documents removed.
D.remove({ level: 'debug' }) is the modern method and returns a cursor of deleted documents.
AnswerA

deleteMany removes every document matching the filter and returns a DeleteResult with deletedCount set to the number removed. Because the collection has an index on level, the filter can be served efficiently. This matches the requirement to remove all debug-level logs while preserving other documents and the collection's indexes.

Why this answer

deleteMany with a filter removes all matching documents and reports how many were deleted via deletedCount. deleteOne only removes the first match, drop destroys the whole collection, and remove is deprecated. When a selective deletion is needed and the filter is indexed, deleteMany preserves unrelated documents and existing indexes.

Exam trap

The trap here is choosing deleteOne or drop when the requirement is to remove every document matching a predicate while keeping the collection intact.

25
Multi-Selecthard

A financial application stores transactions in the 'transactions' collection. Each document has fields: 'accountId', 'amount', 'timestamp', and 'status'. You need to find all transactions for account 'A123' that have an amount greater than 1000 and a status of either 'pending' or 'review'. Which two query documents correctly retrieve these transactions? (Choose two.)

Select 2 answers
A.{ accountId: 'A123', $and: [ { amount: { $gt: 1000 } }, { status: { $in: ['pending', 'review'] } } ] }
B.{ accountId: 'A123', amount: { $gt: 1000 }, status: { $in: ['pending', 'review'] } }
C.{ accountId: 'A123', amount: { $gt: 1000 }, status: { $or: ['pending', 'review'] } }
D.{ accountId: 'A123', amount: { $gte: 1000 }, status: { $in: ['pending', 'review'] } }
E.{ accountId: 'A123', $or: [ { amount: { $gt: 1000 } }, { status: { $in: ['pending', 'review'] } } ] }
AnswersA, B

This query uses the $and operator to explicitly combine the amount and status conditions, while accountId is specified at the top level. It is functionally equivalent to the implicit AND version and correctly retrieves the desired transactions. It is more verbose but valid and clear.

Why this answer

The correct queries must combine accountId, amount greater than 1000, and status in a list using logical AND. The implicit AND version and the explicit $and version both achieve this. The other options either use invalid syntax, combine conditions with OR instead of AND, or use the wrong comparison operator, leading to incorrect results.

Exam trap

The trap here is mixing up $in and $or, or using $or at the top level instead of within a field, which changes the logic to OR instead of AND.

26
MCQhard

A developer must update a document in the 'accounts' collection by incrementing the 'balance' field by 25 and simultaneously setting the 'lastUpdated' field to the current date. The update must apply only if the account is active. Which update statement satisfies all conditions?

A.replaceOne({ active: true }, { $inc: { balance: 25 }, $set: { lastUpdated: new Date() } })
B.updateOne({ active: true }, { $inc: { balance: 25 }, $set: { lastUpdated: new Date() } })
C.updateMany({ active: true }, { $inc: { balance: 25 }, $set: { lastUpdated: new Date() } })
D.updateOne({ active: true }, { balance: 25, lastUpdated: new Date() })
AnswerB

This updateOne call filters for active accounts, uses $inc to add 25 to balance, and $set to write the current date. Both update operators are applied atomically to the matched document, satisfying all three requirements in a single round trip. It is the idiomatic way to combine multiple field modifications with a conditional filter.

Why this answer

The correct approach is updateOne with a filter on active, $inc for the numeric change, and $set for the timestamp. Using update operators applies atomic field-level changes to one matched document. Omitting operators triggers replacement semantics, updateMany affects too many documents, and replaceOne forbids modifier keys, so each alternative violates part of the requirement.

Exam trap

The trap here is forgetting that a document without update operators is treated as a full replacement, silently dropping other fields instead of incrementing.

Ready to test yourself?

Try a timed practice session using only CRUD Operations questions.