Database Reference
In-Depth Information
6.4.4
Deletes
You'll be relieved to learn that removing documents poses few challenges. You can
remove an entire collection or you can pass a query selector to the remove method to
delete only a subset of a collection. Deleting all reviews is simple:
db.reviews.remove({})
But it's much more common to delete only the reviews of a particular user:
db.reviews.remove({user_id: ObjectId('4c4b1476238d3b4dd5000001')})
Thus, all calls to remove take an optional query specifier for selecting exactly which
documents to delete. As far as the API goes, that's all there is to say. But you'll have a
few questions surrounding the concurrency and atomicity of these operations. I'll
explain that in the next section.
6.4.5
Concurrency, atomicity, and isolation
It's important to understand how concurrency works in MongoDB. As of MongoDB
v2.0, the locking strategy is rather coarse; a single global reader-writer lock reigns over
the entire mongod instance. What this means is that at any moment in time, the data-
base permits either one writer or multiple readers (but not both). This sounds a lot
worse than it is in practice because there exist quite a few concurrency optimizations
around this lock. One is that the database keeps an internal map of which document
are in RAM . For requests to read or write documents not residing in RAM , the database
yields to other operations until the document can be paged into memory.
A second optimization is the yielding of write locks. The issue is that if any one
write takes a long time to complete, all other read and write operations will be
blocked for the duration of the original write. All inserts, updates, and removes take a
write lock. Inserts rarely take a long time to complete. But updates that affect, say, an
entire collection, as well as deletes that affect a lot of documents, can run long. The
current solution to this is to allow these long-running ops to yield periodically for
other readers and writers. When an operation yields, it pauses itself, releases its lock,
and resumes later. 9
But when updating and removing documents, this yielding behavior can be a
mixed blessing. It's easy to imagine situations where you'd want all documents
updated or removed before any other operation takes place. For these cases, you can
use a special option called $atomic to keep the operation from yielding. You simply
add the $atomic operator to the query selector like so:
db.reviews.remove({user_id: ObjectId('4c4b1476238d3b4dd5000001'),
{$atomic: true}})
9
Granted, the yielding and resuming generally happen within the space of a few of milliseconds. So we're not
necessarily talking about an egregious interruption here.
Search WWH ::




Custom Search