100% found this document useful (1 vote)
765 views82 pages

MongoDB Crud Guide PDF

This document provides an overview of MongoDB CRUD (Create, Read, Update, Delete) operations. It describes database operations like querying and data modification. It also covers related features like indexes, read preference, write concern and aggregation. The document then defines concepts for read and write operations and provides tutorials for performing CRUD operations in MongoDB.

Uploaded by

Dante Llimpe
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
765 views82 pages

MongoDB Crud Guide PDF

This document provides an overview of MongoDB CRUD (Create, Read, Update, Delete) operations. It describes database operations like querying and data modification. It also covers related features like indexes, read preference, write concern and aggregation. The document then defines concepts for read and write operations and provides tutorials for performing CRUD operations in MongoDB.

Uploaded by

Dante Llimpe
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 82

MongoDB CRUD Operations

Release 2.6.4
MongoDB Documentation Project
September 16, 2014
Contents
1 MongoDB CRUD Introduction 3
1.1 Database Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Data Modication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2 Related Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Indexes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Replica Set Read Preference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Write Concern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Aggregation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2 MongoDB CRUD Concepts 6
2.1 Read Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Read Operations Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Cursors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Query Optimization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Query Plans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Distributed Queries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.2 Write Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Write Operations Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Write Concern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Distributed Write Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Write Operation Performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Bulk Inserts in MongoDB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3 MongoDB CRUD Tutorials 35
3.1 Insert Documents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Insert a Document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Insert an Array of Documents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Insert Multiple Documents with Bulk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Additional Examples and Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.2 Query Documents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Select All Documents in a Collection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Specify Equality Condition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Specify Conditions Using Query Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Specify AND Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Specify OR Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Specify AND as well as OR Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Embedded Documents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.3 Limit Fields to Return from a Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Return All Fields in Matching Documents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Return the Specied Fields and the _id Field Only . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Return Specied Fields Only . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Return All But the Excluded Field . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Projection for Array Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
3.4 Iterate a Cursor in the mongo Shell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Manually Iterate the Cursor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Iterator Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
3.5 Analyze Query Performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Evaluate the Performance of a Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Compare Performance of Indexes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
3.6 Modify Documents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Update Specic Fields in a Document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Replace the Document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
upsert Option . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Additional Examples and Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
3.7 Remove Documents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Remove All Documents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Remove Documents that Match a Condition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Remove a Single Document that Matches a Condition . . . . . . . . . . . . . . . . . . . . . . . . . . 53
3.8 Perform Two Phase Commits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Synopsis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Background . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Recovering from Failure Scenarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
Multiple Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Using Two-Phase Commits in Production Applications . . . . . . . . . . . . . . . . . . . . . . . . . 60
3.9 Create Tailable Cursor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
C++ Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
3.10 Isolate Sequence of Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Update if Current . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
3.11 Create an Auto-Incrementing Sequence Field . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Synopsis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
3.12 Limit Number of Elements in an Array after an Update . . . . . . . . . . . . . . . . . . . . . . . . . 67
Synopsis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
4 MongoDB CRUD Reference 69
4.1 Query Cursor Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
4.2 Query and Data Manipulation Collection Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
4.3 MongoDB CRUD Reference Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Write Concern Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
SQL to MongoDB Mapping Chart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
The bios Example Collection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
2
Index 82
MongoDB provides rich semantics for reading and manipulating data. CRUD stands for create, read, update, and
delete. These terms are the foundation for all interactions with the database.
MongoDB CRUD Introduction (page 3) An introduction to the MongoDB data model as well as queries and data
manipulations.
MongoDB CRUD Concepts (page 6) The core documentation of query and data manipulation.
MongoDB CRUD Tutorials (page 35) Examples of basic query and data modication operations.
MongoDB CRUD Reference (page 69) Reference material for the query and data manipulation interfaces.
1 MongoDB CRUD Introduction
MongoDB stores data in the form of documents, which are JSON-like eld and value pairs. Documents are
analogous to structures in programming languages that associate keys with values (e.g. dictionaries, hashes,
maps, and associative arrays). Formally, MongoDB documents are BSON documents. BSON is a binary rep-
resentation of JSON with additional type information. In the documents, the value of a eld can be any of
the BSON data types, including other documents, arrays, and arrays of documents. For more information, see
http://docs.mongodb.org/manualcore/document.
Figure 1: A MongoDB document.
MongoDB stores all documents in collections. A collection is a group of related documents that have a set of shared
common indexes. Collections are analogous to a table in relational databases.
1.1 Database Operations
Query
In MongoDB a query targets a specic collection of documents. Queries specify criteria, or conditions, that identify
the documents that MongoDB returns to the clients. A query may include a projection that species the elds from
the matching documents to return. You can optionally modify queries to impose limits, skips, and sort orders.
In the following diagram, the query process species a query criteria and a sort modier:
See Read Operations Overview (page 7) for more information.
3
Figure 2: A collection of MongoDB documents.
Figure 3: The stages of a MongoDB query with a query criteria and a sort modier.
4
Data Modication
Data modication refers to operations that create, update, or delete data. In MongoDB, these operations modify the
data of a single collection. For the update and delete operations, you can specify the criteria to select the documents
to update or remove.
In the following diagram, the insert operation adds a new document to the users collection.
Figure 4: The stages of a MongoDB insert operation.
See Write Operations Overview (page 19) for more information.
1.2 Related Features
Indexes
To enhance the performance of common queries and updates, MongoDB has full support for secondary indexes. These
indexes allow applications to store a view of a portion of the collection in an efcient data structure. Most indexes
store an ordered representation of all values of a eld or a group of elds. Indexes may also enforce uniqueness, store
objects in a geospatial representation, and facilitate text search.
5
Replica Set Read Preference
For replica sets and sharded clusters with replica set components, applications specify read preferences. A read
preference determines how the client direct read operations to the set.
Write Concern
Applications can also control the behavior of write operations using write concern (page 23). Particularly useful
for deployments with replica sets, the write concern semantics allow clients to specify the assurance that MongoDB
provides when reporting on the success of a write operation.
Aggregation
In addition to the basic queries, MongoDB provides several data aggregation features. For example, MongoDB can
return counts of the number of documents that match a query, or return the number of distinct values for a eld, or
process a collection of documents using a versatile stage-based data processing pipeline or map-reduce operations.
2 MongoDB CRUD Concepts
The Read Operations (page 6) and Write Operations (page 18) documents introduce the behavior and operations of
read and write operations for MongoDB deployments.
Read Operations (page 6) Introduces all operations that select and return documents to clients, including the query
specications.
Cursors (page 10) Queries return iterable objects, called cursors, that hold the full result set.
Query Optimization (page 12) Analyze and improve query performance.
Distributed Queries (page 15) Describes how sharded clusters and replica sets affect the performance of read
operations.
Write Operations (page 18) Introduces data create and modify operations, their behavior, and performances.
Write Concern (page 23) Describes the kind of guarantee MongoDB provides when reporting on the success
of a write operation.
Distributed Write Operations (page 25) Describes how MongoDB directs write operations on sharded clusters
and replica sets and the performance characteristics of these operations.
Continue reading from Write Operations (page 18) for additional background on the behavior of data modica-
tion operations in MongoDB.
2.1 Read Operations
The following documents describe read operations:
Read Operations Overview (page 7) A high level overview of queries and projections in MongoDB, including a dis-
cussion of syntax and behavior.
Cursors (page 10) Queries return iterable objects, called cursors, that hold the full result set.
Query Optimization (page 12) Analyze and improve query performance.
Query Plans (page 13) MongoDB executes queries using optimal plans.
6
Distributed Queries (page 15) Describes how sharded clusters and replica sets affect the performance of read opera-
tions.
Read Operations Overview
Read operations, or queries, retrieve data stored in the database. In MongoDB, queries select documents from a single
collection.
Queries specify criteria, or conditions, that identify the documents that MongoDB returns to the clients. A query may
include a projection that species the elds from the matching documents to return. The projection limits the amount
of data that MongoDB returns to the client over the network.
Query Interface
For query operations, MongoDB provides a db.collection.find() method. The method accepts both the
query criteria and projections and returns a cursor (page 10) to the matching documents. You can optionally modify
the query to impose limits, skips, and sort orders.
The following diagram highlights the components of a MongoDB query operation:
Figure 5: The components of a MongoDB nd operation.
The next diagram shows the same query in SQL:
Figure 6: The components of a SQL SELECT statement.
Example
db.users.find( { age: { $gt: 18 } }, { name: 1, address: 1 } ).limit(5)
This query selects the documents in the users collection that match the condition age is greater than 18. To specify
the greater than condition, query criteria uses the greater than (i.e. $gt) query selection operator. The query returns
at most 5 matching documents (or more precisely, a cursor to those documents). The matching documents will return
with only the _id, name and address elds. See Projections (page 9) for details.
7
See
SQL to MongoDB Mapping Chart (page 71) for additional examples of MongoDB queries and the corresponding SQL
statements.
Query Behavior
MongoDB queries exhibit the following behavior:
All queries in MongoDB address a single collection.
You can modify the query to impose limits, skips, and sort orders.
The order of documents returned by a query is not dened unless you specify a sort().
Operations that modify existing documents (page 49) (i.e. updates) use the same query syntax as queries to select
documents to update.
In aggregation pipeline, the $match pipeline stage provides access to MongoDB queries.
MongoDB provides a db.collection.findOne() method as a special case of find() that returns a single
document.
Query Statements
Consider the following diagram of the query process that species a query criteria and a sort modier:
Figure 7: The stages of a MongoDB query with a query criteria and a sort modier.
In the diagram, the query selects documents from the users collection. Using a query selection operator
to dene the conditions for matching documents, the query selects documents that have age greater than (i.e. $gt)
18. Then the sort() modier sorts the results by age in ascending order.
For additional examples of queries, see Query Documents (page 39).
8
Projections
Queries in MongoDB return all elds in all matching documents by default. To limit the amount of data that MongoDB
sends to applications, include a projection in the queries. By projecting results with a subset of elds, applications
reduce their network overhead and processing requirements.
Projections, which are the second argument to the find() method, may either specify a list of elds to return or list
elds to exclude in the result documents.
Important: Except for excluding the _id eld in inclusive projections, you cannot mix exclusive and inclusive
projections.
Consider the following diagram of the query process that species a query criteria and a projection:
Figure 8: The stages of a MongoDB query with a query criteria and projection. MongoDB only transmits the projected
data to the clients.
In the diagram, the query selects from the users collection. The criteria matches the documents that have age equal
to 18. Then the projection species that only the name eld should return in the matching documents.
Projection Examples
Exclude One Field From a Result Set
db.records.find( { "user_id": { $lt: 42 } }, { "history": 0 } )
This query selects documents in the records collection that match the condition { "user_id": { $lt: 42
} }, and uses the projection { "history": 0 } to exclude the history eld from the documents in the result
set.
9
Return Two elds and the _id Field
db.records.find( { "user_id": { $lt: 42 } }, { "name": 1, "email": 1 } )
This query selects documents in the records collection that match the query { "user_id": { $lt: 42 }
} and uses the projection { "name": 1, "email": 1 } to return just the _id eld (implicitly included),
name eld, and the email eld in the documents in the result set.
Return Two Fields and Exclude _id
db.records.find( { "user_id": { $lt: 42} }, { "_id": 0, "name": 1 , "email": 1 } )
This query selects documents in the records collection that match the query { "user_id": { $lt: 42}
}, and only returns the name and email elds in the documents in the result set.
See
Limit Fields to Return from a Query (page 45) for more examples of queries with projection statements.
Projection Behavior MongoDB projections have the following properties:
By default, the _id eld is included in the results. To suppress the _id eld from the result set, specify _id:
0 in the projection document.
For elds that contain arrays, MongoDB provides the following projection operators: $elemMatch, $slice,
and $.
For related projection functionality in the aggregation framework pipeline, use the $project pipeline
stage.
Cursors
In the mongo shell, the primary method for the read operation is the db.collection.find() method. This
method queries a collection and returns a cursor to the returning documents.
To access the documents, you need to iterate the cursor. However, in the mongo shell, if the returned cursor is not
assigned to a variable using the var keyword, then the cursor is automatically iterated up to 20 times
1
to print up to
the rst 20 documents in the results.
For example, in the mongo shell, the following read operation queries the inventory collection for documents that
have type equal to food and automatically print up to the rst 20 matching documents:
db.inventory.find( { type: 'food' } );
To manually iterate the cursor to access the documents, see Iterate a Cursor in the mongo Shell (page 47).
Cursor Behaviors
Closure of Inactive Cursors By default, the server will automatically close the cursor after 10 minutes of inactivity
or if client has exhausted the cursor. To override this behavior, you can specify the noTimeout wire protocol ag
2
in your query; however, you should either close the cursor manually or exhaust the cursor. In the mongo shell, you
can set the noTimeout ag:
1
You can use the DBQuery.shellBatchSize to change the number of iteration from the default value 20. See mongo-shell-executing-
queries for more information.
2
http://docs.mongodb.org/meta-driver/latest/legacy/mongodb-wire-protocol
10
var myCursor = db.inventory.find().addOption(DBQuery.Option.noTimeout);
See your driver documentation for information on setting the noTimeout ag. For the mongo shell, see
cursor.addOption() for a complete list of available cursor ags.
Cursor Isolation Because the cursor is not isolated during its lifetime, intervening write operations on a document
may result in a cursor that returns a document more than once if that document has changed. To handle this situation,
see the information on snapshot mode.
Cursor Batches The MongoDB server returns the query results in batches. Batch size will not exceed the maximum
BSON document size. For most queries, the rst batch returns 101 documents or just enough documents to exceed 1
megabyte. Subsequent batch size is 4 megabytes. To override the default size of the batch, see batchSize() and
limit().
For queries that include a sort operation without an index, the server must load all the documents in memory to perform
the sort and will return all documents in the rst batch.
As you iterate through the cursor and reach the end of the returned batch, if there are more results, cursor.next()
will perform a getmore operation to retrieve the next batch. To see how many documents remain in the batch
as you iterate the cursor, you can use the objsLeftInBatch() method, as in the following example:
var myCursor = db.inventory.find();
var myFirstDocument = myCursor.hasNext() ? myCursor.next() : null;
myCursor.objsLeftInBatch();
Cursor Information
The db.serverStatus() method returns a document that includes a metrics eld. The metrics eld con-
tains a cursor eld with the following information:
number of timed out cursors since the last server restart
number of open cursors with the option DBQuery.Option.noTimeout set to prevent timeout after a period
of inactivity
number of pinned open cursors
total number of open cursors
Consider the following example which calls the db.serverStatus() method and accesses the metrics eld
from the results and then the cursor eld from the metrics eld:
db.serverStatus().metrics.cursor
The result is the following document:
{
"timedOut" : <number>
"open" : {
"noTimeout" : <number>,
"pinned" : <number>,
"total" : <number>
}
}
11
See also:
db.serverStatus()
Query Optimization
Indexes improve the efciency of read operations by reducing the amount of data that query operations need to process.
This simplies the work associated with fullling queries within MongoDB.
Create an Index to Support Read Operations
If your application queries a collection on a particular eld or elds, then an index on the queried eld or elds can
prevent the query from scanning the whole collection to nd and return the query results. For more information about
indexes, see the complete documentation of indexes in MongoDB.
Example
An application queries the inventory collection on the type eld. The value of the type eld is user-driven.
var typeValue = <someUserInput>;
db.inventory.find( { type: typeValue } );
To improve the performance of this query, add an ascending, or a descending, index to the inventory collection
on the type eld.
3
In the mongo shell, you can create indexes using the db.collection.ensureIndex()
method:
db.inventory.ensureIndex( { type: 1 } )
This index can prevent the above query on type from scanning the whole collection to return the results.
To analyze the performance of the query with an index, see Analyze Query Performance (page 48).
In addition to optimizing read operations, indexes can support sort operations and al-
low for a more efcient storage utilization. See db.collection.ensureIndex() and
http://docs.mongodb.org/manualadministration/indexes for more information about index
creation.
Query Selectivity
Some query operations are not selective. These operations cannot use indexes effectively or cannot use indexes at all.
The inequality operators $nin and $ne are not very selective, as they often match a large portion of the index. As a
result, in most cases, a $nin or $ne query with an index may perform no better than a $nin or $ne query that must
scan all documents in a collection.
Queries that specify regular expressions, with inline JavaScript regular expressions or $regex operator expressions,
cannot use an index with one exception. Queries that specify regular expression with anchors at the beginning of a
string can use an index.
3
For single-eld indexes, the selection between ascending and descending order is immaterial. For compound indexes, the selection is important.
See indexing order for more details.
12
Covering a Query
An index covers a query, a covered query, when:
all the elds in the query (page 39) are part of that index, and
all the elds returned in the documents that match the query are in the same index.
For these queries, MongoDB does not need to inspect documents outside of the index. This is often more efcient
than inspecting entire documents.
Example
Given a collection inventory with the following index on the type and item elds:
{ type: 1, item: 1 }
This index will cover the following query on the type and item elds, which returns only the item eld:
db.inventory.find( { type: "food", item:/^c/ },
{ item: 1, _id: 0 } )
However, the index will not cover the following query, which returns the item eld and the _id eld:
db.inventory.find( { type: "food", item:/^c/ },
{ item: 1 } )
See indexes-covered-queries for more information on the behavior and use of covered queries.
Query Plans
The MongoDB query optimizer processes queries and chooses the most efcient query plan for a query given the
available indexes. The query system then uses this query plan each time the query runs.
The query optimizer only caches the plans for those query shapes that can have more than one viable plan.
The query optimizer occasionally reevaluates query plans as the content of the collection changes to ensure optimal
query plans. You can also specify which indexes the optimizer evaluates with Index Filters (page 14).
You can use the explain() method to view statistics about the query plan for a given query. This information can
help as you develop indexing strategies.
Query Optimization
To create a new query plan, the query optimizer:
1. runs the query against several candidate indexes in parallel.
2. records the matches in a common results buffer or buffers.
If the candidate plans include only ordered query plans, there is a single common results buffer.
If the candidate plans include only unordered query plans, there is a single common results buffer.
If the candidate plans include both ordered query plans and unordered query plans, there are two common
results buffers, one for the ordered plans and the other for the unordered plans.
If an index returns a result already returned by another index, the optimizer skips the duplicate match. In the
case of the two buffers, both buffers are de-duped.
13
3. stops the testing of candidate plans and selects an index when one of the following events occur:
An unordered query plan has returned all the matching results; or
An ordered query plan has returned all the matching results; or
An ordered query plan has returned a threshold number of matching results:
Version 2.0: Threshold is the query batch size. The default batch size is 101.
Version 2.2: Threshold is 101.
The selected index becomes the index specied in the query plan; future iterations of this query or queries with the
same query pattern will use this index. Query pattern refers to query select conditions that differ only in the values, as
in the following two queries with the same query pattern:
db.inventory.find( { type: 'food' } )
db.inventory.find( { type: 'utensil' } )
Query Plan Revision
As collections change over time, the query optimizer deletes the query plan and re-evaluates after any of the following
events:
The collection receives 1,000 write operations.
The reIndex rebuilds the index.
You add or drop an index.
The mongod process restarts.
Cached Query Plan Interface
New in version 2.6.
MongoDB provides http://docs.mongodb.org/manualreference/method/js-plan-cache to
view and modify the cached query plans.
Index Filters
New in version 2.6.
Index lters determine which indexes the optimizer evaluates for a query shape. A query shape consists of a combi-
nation of query, sort, and projection specications. If an index lter exists for a given query shape, the optimizer only
considers those indexes specied in the lter.
When an index lter exists for the query shape, MongoDB ignores the hint(). To see whether MongoDB applied
an index lter for a query, check the explain.filterSet eld of the explain() output.
Index lters only affects which indexes the optimizer evaluates; the optimizer may still select the collection scan as
the winning plan for a given query shape.
Index lters exist for the duration of the server process and do not persist after shutdown. MongoDB also provides a
command to manually remove lters.
Because index lters overrides the expected behavior of the optimizer as well as the hint() method, use index lters
sparingly.
See planCacheListFilters, planCacheClearFilters, and planCacheSetFilter.
14
Distributed Queries
Read Operations to Sharded Clusters
Sharded clusters allow you to partition a data set among a cluster of mongod instances in a
way that is nearly transparent to the application. For an overview of sharded clusters, see the
http://docs.mongodb.org/manualsharding section of this manual.
For a sharded cluster, applications issue operations to one of the mongos instances associated with the cluster.
Figure 9: Diagram of a sharded cluster.
Read operations on sharded clusters are most efcient when directed to a specic shard. Queries to sharded collections
should include the collections shard key. When a query includes a shard key, the mongos can use cluster metadata
from the cong database to route the queries to shards.
If a query does not include the shard key, the mongos must direct the query to all shards in the cluster. These scatter
gather queries can be inefcient. On larger clusters, scatter gather queries are unfeasible for routine operations.
For more information on read operations in sharded clusters, see the http://docs.mongodb.org/manualcore/sharded-cluster-query-router
and sharding-shard-key sections.
15
Figure 10: Read operations to a sharded cluster. Query criteria includes the shard key. The query router mongos can
target the query to the appropriate shard or shards.
16
Figure 11: Read operations to a sharded cluster. Query criteria does not include the shard key. The query router
mongos must broadcast query to all shards for the collection.
17
Read Operations to Replica Sets
Replica sets use read preferences to determine where and how to route read operations to members of the replica set.
By default, MongoDB always reads data from a replica sets primary. You can modify that behavior by changing the
read preference mode.
You can congure the read preference mode on a per-connection or per-operation basis to allowreads fromsecondaries
to:
reduce latency in multi-data-center deployments,
improve read throughput by distributing high read-volumes (relative to write volume),
for backup operations, and/or
to allow reads during failover situations.
Figure 12: Read operations to a replica set. Default read preference routes the read to the primary. Read preference of
nearest routes the read to the nearest member.
Read operations from secondary members of replica sets are not guaranteed to reect the current state of the primary,
and the state of secondaries will trail the primary by some amount of time. Often, applications dont rely on this kind
of strict consistency, but application developers should always consider the needs of their application before setting
read preference.
For more information on read preference or on the read preference modes, see
http://docs.mongodb.org/manualcore/read-preference and replica-set-read-preference-modes.
2.2 Write Operations
The following documents describe write operations:
18
Write Operations Overview (page 19) Provides an overview of MongoDBs data insertion and modication opera-
tions, including aspects of the syntax, and behavior.
Write Concern (page 23) Describes the kind of guarantee MongoDB provides when reporting on the success of a
write operation.
Distributed Write Operations (page 25) Describes how MongoDB directs write operations on sharded clusters and
replica sets and the performance characteristics of these operations.
Write Operation Performance (page 31) Introduces the performance constraints and factors for writing data to Mon-
goDB deployments.
Bulk Inserts in MongoDB (page 32) Describe behaviors associated with inserting an array of documents.
Storage (page 33) Introduces the storage allocation strategies available for MongoDB collections.
Write Operations Overview
A write operation is any operation that creates or modies data in the MongoDB instance. In MongoDB, write
operations target a single collection. All write operations in MongoDB are atomic on the level of a single document.
There are three classes of write operations in MongoDB: insert (page 19), update (page 20), and remove (page 22).
Insert operations add new data to a collection. Update operations modify existing data, and remove operations delete
data from a collection. No insert, update, or remove can affect more than one document atomically.
For the update and remove operations, you can specify criteria, or conditions, that identify the documents to update or
remove. These operations use the same query syntax to specify the criteria as read operations (page 6).
MongoDB allows applications to determine the acceptable level of acknowledgement required of write operations.
See Write Concern (page 23) for more information.
Insert
In MongoDB, the db.collection.insert() method adds new documents to a collection.
The following diagram highlights the components of a MongoDB insert operation:
Figure 13: The components of a MongoDB insert operations.
The following diagram shows the same query in SQL:
Example
19
Figure 14: The components of a SQL INSERT statement.
The following operation inserts a new documents into the users collection. The new document has four elds name,
age, and status, and an _id eld. MongoDB always adds the _id eld to the new document if that eld does not
exist.
db.users.insert(
{
name: "sue",
age: 26,
status: "A"
}
)
For more information and examples, see db.collection.insert().
Insert Behavior If you add a new document without the _id eld, the client library or the mongod instance adds an
_id eld and populates the eld with a unique ObjectId.
If you specify the _id eld, the value must be unique within the collection. For operations with write concern
(page 23), if you try to create a document with a duplicate _id value, mongod returns a duplicate key exception.
Other Methods to Add Documents You can also add new documents to a collection using methods that have an
upsert (page 21) option. If the option is set to true, these methods will either modify existing documents or add a
new document when no matching documents exist for the query. For more information, see Update Behavior with the
upsert Option (page 21).
Update
In MongoDB, the db.collection.update() method modies existing documents in a collection. The
db.collection.update() method can accept query criteria to determine which documents to update as well as
an options document that affects its behavior, such as the multi option to update multiple documents.
The following diagram highlights the components of a MongoDB update operation:
The following diagram shows the same query in SQL:
Example
db.users.update(
{ age: { $gt: 18 } },
{ $set: { status: "A" } },
{ multi: true }
)
20
Figure 15: The components of a MongoDB update operation.
Figure 16: The components of a SQL UPDATE statement.
This update operation on the users collection sets the status eld to A for the documents that match the criteria
of age greater than 18.
For more information, see db.collection.update() and update() Examples.
Default Update Behavior By default, the db.collection.update() method updates a single document.
However, with the multi option, update() can update all documents in a collection that match a query.
The db.collection.update() method either updates specic elds in the existing document or replaces the
document. See db.collection.update() for details as well as examples.
When performing update operations that increase the document size beyond the allocated space for that document, the
update operation relocates the document on disk.
MongoDB preserves the order of the document elds following write operations except for the following cases:
The _id eld is always the rst eld in the document.
Updates that include renaming of eld names may result in the reordering of elds in the document.
Changed in version 2.6: Starting in version 2.6, MongoDB actively attempts to preserve the eld order in a document.
Before version 2.6, MongoDB did not actively preserve the order of the elds in a document.
Update Behavior with the upsert Option If the update() method includes upsert: true and no documents
match the query portion of the update operation, then the update operation creates a new document. If there are
matching documents, then the update operation with the upsert: true modies the matching document or documents.
By specifying upsert: true, applications can indicate, in a single operation, that if no matching documents are found
for the update, an insert should be performed. See update() for details on performing an upsert.
Changed in version 2.6: In 2.6, the newBulk() methods and the underlying update command allow you to perform
many updates with upsert: true operations in a single call.
21
Remove
In MongoDB, the db.collection.remove() method deletes documents from a collection. The
db.collection.remove() method accepts a query criteria to determine which documents to remove.
The following diagram highlights the components of a MongoDB remove operation:
Figure 17: The components of a MongoDB remove operation.
The following diagram shows the same query in SQL:
Figure 18: The components of a SQL DELETE statement.
Example
db.users.remove(
{ status: "D" }
)
This delete operation on the users collection removes all documents that match the criteria of status equal to D.
For more information, see db.collection.remove() method and Remove Documents (page 53).
Remove Behavior By default, db.collection.remove() method removes all documents that match its query.
However, the method can accept a ag to limit the delete operation to a single document.
Isolation of Write Operations
The modication of a single document is always atomic, even if the write operation modies multiple sub-documents
within that document. For write operations that modify multiple documents, the operation as a whole is not atomic,
and other operations may interleave.
No other operations are atomic. You can, however, attempt to isolate a write operation that affects multiple documents
using the isolation operator.
To isolate a sequence of write operations from other read and write operations, see Perform Two Phase Commits
(page 54).
22
Additional Methods
The db.collection.save() method can either update an existing document or an insert a document if the
document cannot be found by the _id eld. See db.collection.save() for more information and examples.
MongoDB also provides methods to perform write operations in bulk. See Bulk() for more information.
Write Concern
Write concern describes the guarantee that MongoDB provides when reporting on the success of a write operation.
The strength of the write concerns determine the level of guarantee. When inserts, updates and deletes have a weak
write concern, write operations return quickly. In some failure cases, write operations issued with weak write concerns
may not persist. With stronger write concerns, clients wait after sending a write operation for MongoDB to conrm
the write operations.
MongoDB provides different levels of write concern to better address the specic needs of applications. Clients
may adjust write concern to ensure that the most important operations persist successfully to an entire MongoDB
deployment. For other less critical operations, clients can adjust the write concern to ensure faster performance rather
than ensure persistence to the entire deployment.
Changed in version 2.6: A new protocol for write operations integrates write concern with the write operations.
For details on write concern congurations, see Write Concern Reference (page 69).
Considerations
Default Write Concern The mongo shell and the MongoDB drivers use Acknowledged (page 24) as the default
write concern.
See Acknowledged (page 24) for more information, including when this write concern became the default.
Read Isolation MongoDB allows clients to read documents inserted or modied before it commits these modica-
tions to disk, regardless of write concern level or journaling conguration. As a result, applications may observe two
classes of behaviors:
For systems with multiple concurrent readers and writers, MongoDB will allow clients to read the results of a
write operation before the write operation returns.
If the mongod terminates before the journal commits, even if a write returns successfully, queries may have
read data that will not exist after the mongod restarts.
Other database systems refer to these isolation semantics as read uncommitted. For all inserts and updates, Mon-
goDB modies each document in isolation: clients never see documents in intermediate states. For multi-document
operations, MongoDB does not provide any multi-document transactions or isolation.
When mongod returns a successful journaled write concern, the data is fully committed to disk and will be available
after mongod restarts.
For replica sets, write operations are durable only after a write replicates and commits to the journal of a majority of
the members of the set. MongoDB regularly commits data to the journal regardless of journaled write concern: use
the commitIntervalMs to control how often a mongod commits the journal.
Timeouts Clients can set a wtimeout (page 71) value as part of a replica acknowledged (page 25) write concern. If
the write concern is not satised in the specied interval, the operation returns an error, even if the write concern will
eventually succeed.
23
MongoDB does not rollback or undo modications made before the wtimeout interval expired.
Write Concern Levels
MongoDB has the following levels of conceptual write concern, listed from weakest to strongest:
Unacknowledged With an unacknowledged write concern, MongoDB does not acknowledge the receipt of write
operations. Unacknowledged is similar to errors ignored; however, drivers will attempt to receive and handle network
errors when possible. The drivers ability to detect network errors depends on the systems networking conguration.
Before the releases outlined in driver-write-concern-change, this was the default write concern.
Figure 19: Write operation to a mongod instance with write concern of unacknowledged. The client does not
wait for any acknowledgment.
Acknowledged With a receipt acknowledged write concern, the mongod conrms the receipt of the write operation.
Acknowledged write concern allows clients to catch network, duplicate key, and other errors.
MongoDB uses the acknowledged write concern by default starting in the driver releases outlined in write-concern-
change-releases.
Changed in version 2.6: The mongo shell write methods now incorporates the write concern (page 23) in the
write methods and provide the default write concern whether run interactively or in a script. See write-methods-
incompatibility for details.
Journaled With a journaled write concern, the MongoDB acknowledges the write operation only after committing
the data to the journal. This write concern ensures that MongoDB can recover the data following a shutdown or power
interruption.
You must have journaling enabled to use this write concern.
24
Figure 20: Write operation to a mongod instance with write concern of acknowledged. The client waits for
acknowledgment of success or exception.
With a journaled write concern, write operations must wait for the next journal commit. To reduce latency for these op-
erations, MongoDB also increases the frequency that it commits operations to the journal. See commitIntervalMs
for more information.
Note: Requiring journaled write concern in a replica set only requires a journal commit of the write operation to the
primary of the set regardless of the level of replica acknowledged write concern.
Replica Acknowledged Replica sets present additional considerations with regards to write concern.. The default
write concern only requires acknowledgement from the primary.
With replica acknowledged write concern, you can guarantee that the write operation propagates to additional members
of the replica set. See Write Concern for Replica Sets for more information.
Note: Requiring journaled write concern in a replica set only requires a journal commit of the write operation to the
primary of the set regardless of the level of replica acknowledged write concern.
See also:
Write Concern Reference (page 69)
Distributed Write Operations
Write Operations on Sharded Clusters
For sharded collections in a sharded cluster, the mongos directs write operations from applications to the shards that
are responsible for the specic portion of the data set. The mongos uses the cluster metadata from the cong database
25
Figure 21: Write operation to a mongod instance with write concern of journaled. The mongod sends acknowl-
edgment after it commits the write operation to the journal.
to route the write operation to the appropriate shards.
MongoDB partitions data in a sharded collection into ranges based on the values of the shard key. Then, MongoDB
distributes these chunks to shards. The shard key determines the distribution of chunks to shards. This can affect the
performance of write operations in the cluster.
Important: Update operations that affect a single document must include the shard key or the _id eld. Updates
that affect multiple documents are more efcient in some situations if they have the shard key, but can be broadcast to
all shards.
If the value of the shard key increases or decreases with every insert, all insert operations target a single shard. As a
result, the capacity of a single shard becomes the limit for the insert capacity of the sharded cluster.
For more information, see http://docs.mongodb.org/manualadministration/sharded-clusters
and Bulk Inserts in MongoDB (page 32).
Write Operations on Replica Sets
In replica sets, all write operations go to the sets primary, which applies the write operation then records the oper-
ations on the primarys operation log or oplog. The oplog is a reproducible sequence of operations to the data set.
Secondary members of the set are continuously replicating the oplog and applying the operations to themselves in an
asynchronous process.
Large volumes of write operations, particularly bulk operations, may create situations where the secondary mem-
bers have difculty applying the replicating operations from the primary at a sufcient rate: this can cause the sec-
ondarys state to fall behind that of the primary. Secondaries that are signicantly behind the primary present prob-
lems for normal operation of the replica set, particularly failover in the form of rollbacks as well as general read
consistency.
26
Figure 22: Write operation to a replica set with write concern level of w:2 or write to the primary and at least one
secondary.
27
Figure 23: Diagram of a sharded cluster.
Figure 24: Diagram of the shard key value space segmented into smaller ranges or chunks.
28
Figure 25: Diagram of default routing of reads and writes to the primary.
29
To help avoid this issue, you can customize the write concern (page 23) to return conrmation of the write operation
to another member
4
of the replica set every 100 or 1,000 operations. This provides an opportunity for secondaries
to catch up with the primary. Write concern can slow the overall progress of write operations but ensure that the
secondaries can maintain a largely current state with respect to the primary.
Figure 26: Write operation to a replica set with write concern level of w:2 or write to the primary and at least one
secondary.
For more information on replica sets and write operations, see Replica Acknowledged (page 25), replica-set-oplog-
sizing, and http://docs.mongodb.org/manualtutorial/change-oplog-size.
4
Intermittently issuing a write concern with a w value of 2 or majority will slow the throughput of write trafc; however, this practice will
allow the secondaries to remain current with the state of the primary.
Changed in version 2.6: In Master/Slave deployments, MongoDB treats w: "majority" as equivalent to w: 1. In earlier versions of
MongoDB, w: "majority" produces an error in master/slave deployments.
30
Write Operation Performance
Indexes
After every insert, update, or delete operation, MongoDB must update every index associated with the collection in
addition to the data itself. Therefore, every index on a collection adds some amount of overhead for the performance
of write operations.
5
In general, the performance gains that indexes provide for read operations are worth the insertion penalty. However,
in order to optimize write performance when possible, be careful when creating new indexes and evaluate the existing
indexes to ensure that your queries actually use these indexes.
For indexes and queries, see Query Optimization (page 12). For more in-
formation on indexes, see http://docs.mongodb.org/manualindexes and
http://docs.mongodb.org/manualapplications/indexes.
Document Growth
If an update operation causes a document to exceed the currently allocated record size, MongoDB relocates the docu-
ment on disk with enough contiguous space to hold the document. These relocations take longer than in-place updates,
particularly if the collection has indexes. If a collection has indexes, MongoDB must update all index entries. Thus,
for a collection with many indexes, the move will impact the write throughput.
Some update operations, such as the $inc operation, do not cause an increase in document size. For these update
operations, MongoDB can apply the updates in-place. Other update operations, such as the $push operation, change
the size of the document.
In-place-updates are signicantly more efcient than updates that cause document growth. When possible, use data
models that minimize the need for document growth.
See Storage (page 33) for more information.
Storage Performance
Hardware The capability of the storage system creates some important physical limits for the performance of Mon-
goDBs write operations. Many unique factors related to the storage system of the drive affect write performance,
including random access patterns, disk caches, disk readahead and RAID congurations.
Solid state drives (SSDs) can outperform spinning hard disks (HDDs) by 100 times or more for random workloads.
See
http://docs.mongodb.org/manualadministration/production-notes for recommendations re-
garding additional hardware and conguration options.
Journaling MongoDB uses write ahead logging to an on-disk journal to guarantee write operation (page 18) dura-
bility and to provide crash resiliency. Before applying a change to the data les, MongoDB writes the change operation
to the journal.
While the durability assurance provided by the journal typically outweigh the performance costs of the additional write
operations, consider the following interactions between the journal and performance:
5
For inserts and updates to un-indexed elds, the overhead for sparse indexes is less than for non-sparse indexes. Also for non-sparse indexes,
updates that do not change the record size have less indexing overhead.
31
if the journal and the data le reside on the same block device, the data les and the journal may have to contend
for a nite number of available write operations. Moving the journal to a separate device may increase the
capacity for write operations.
if applications specify write concern (page 23) that includes journaled (page 24), mongod will decrease the
duration between journal commits, which can increases the overall write load.
the duration between journal commits is congurable using the commitIntervalMs run-time option. De-
creasing the period between journal commits will increase the number of write operations, which can limit
MongoDBs capacity for write operations. Increasing the amount of time between commits may decrease the
total number of write operation, but also increases the chance that the journal will not record a write operation
in the event of a failure.
For additional information on journaling, see http://docs.mongodb.org/manualcore/journaling.
Bulk Inserts in MongoDB
In some situations you may need to insert or ingest a large amount of data into a MongoDB database. These bulk
inserts have some special considerations that are different from other write operations.
Use the insert() Method
The insert() method, when passed an array of documents, performs a bulk insert, and inserts each document
atomically. Bulk inserts can signicantly increase performance by amortizing write concern (page 23) costs.
New in version 2.2: insert() in the mongo shell gained support for bulk inserts in version 2.2.
In the drivers, you can congure write concern for batches rather than on a per-document level.
Drivers have a ContinueOnError option in their insert operation, so that the bulk operation will continue to insert
remaining documents in a batch even if an insert fails.
Note: If multiple errors occur during a bulk insert, clients only receive the last error generated.
See also:
Driver documentation for details on performing bulk inserts in your application. Also see
http://docs.mongodb.org/manualcore/import-export.
Bulk Inserts on Sharded Clusters
While ContinueOnError is optional on unsharded clusters, all bulk operations to a sharded collection run with
ContinueOnError, which cannot be disabled.
Large bulk insert operations, including initial data inserts or routine data import, can affect sharded cluster perfor-
mance. For bulk inserts, consider the following strategies:
Pre-Split the Collection If the sharded collection is empty, then the collection has only one initial chunk, which
resides on a single shard. MongoDB must then take time to receive data, create splits, and distribute the split
chunks to the available shards. To avoid this performance cost, you can pre-split the collection, as described in
http://docs.mongodb.org/manualtutorial/split-chunks-in-sharded-cluster.
32
Insert to Multiple mongos To parallelize import processes, send insert operations to
more than one mongos instance. Pre-split empty collections rst as described in
http://docs.mongodb.org/manualtutorial/split-chunks-in-sharded-cluster.
Avoid Monotonic Throttling If your shard key increases monotonically during an insert, then all inserted data goes
to the last chunk in the collection, which will always end up on a single shard. Therefore, the insert capacity of the
cluster will never exceed the insert capacity of that single shard.
If your insert volume is larger than what a single shard can process, and if you cannot avoid a monotonically increasing
shard key, then consider the following modications to your application:
Reverse the binary bits of the shard key. This preserves the information and avoids correlating insertion order
with increasing sequence of values.
Swap the rst and last 16-bit words to shufe the inserts.
Example
The following example, in C++, swaps the leading and trailing 16-bit word of BSON ObjectIds generated so that they
are no longer monotonically increasing.
using namespace mongo;
OID make_an_id() {
OID x = OID::gen();
const unsigned char
*
p = x.getData();
swap( (unsigned short&) p[0], (unsigned short&) p[10] );
return x;
}
void foo() {
// create an object
BSONObj o = BSON( "_id" << make_an_id() << "x" << 3 << "name" << "jane" );
// now we may insert o into a sharded collection
}
See also:
sharding-shard-key for information on choosing a sharded key. Also see Shard Key Internals (in particular, sharding-
internals-operations-and-reliability).
Storage
Data Model
MongoDB stores data in the form of BSON documents, which are rich mappings of keys, or eld names, to values.
BSON supports a rich collection of types, and elds in BSON documents may hold arrays of values or embedded
documents. All documents in MongoDB must be less than 16MB, which is the BSON document size.
Every document in MongoDB is stored in a record which contains the document itself and extra space, or padding,
which allows the document to grow as the result of updates.
All records are contiguously located on disk, and when a document becomes larger than the allocated record, Mon-
goDB must allocate a new record. New allocations require MongoDB to move a document and update all indexes that
refer to the document, which takes more time than in-place updates and leads to storage fragmentation.
All records are part of a collection, which is a logical grouping of documents in a MongoDB database. The documents
in a collection share a set of indexes, and typically these documents share common elds and structure.
33
In MongoDB the database construct is a group of related collections. Each database has a distinct set of data les and
can contain a large number of collections. Also, each database has one distinct write lock, that blocks operations to
the database during write operations. A single MongoDB deployment may have many databases.
Journal
In order to ensure that all modications to a MongoDB data set are durably written to disk, MongoDB records all
modications to a journal that it writes to disk more frequently than it writes the data les. The journal allows
MongoDB to successfully recover data from data les after a mongod instance exits without ushing all changes.
See http://docs.mongodb.org/manualcore/journaling for more information about the journal in
MongoDB.
Record Allocation Strategies
MongoDB supports multiple record allocation strategies that determine how mongod adds padding to a document
when creating a record. Because documents in MongoDB may grow after insertion and all records are contiguous on
disk, the padding can reduce the need to relocate documents on disk following updates. Relocations are less efcient
than in-place updates, and can lead to storage fragmentation. As a result, all padding strategies trade additional space
for increased efciency and decreased fragmentation.
Different allocation strategies support different kinds of workloads: the power of 2 allocations (page 34) are more
efcient for insert/update/delete workloads; while exact t allocations (page 34) is ideal for collections without update
and delete workloads.
Power of 2 Sized Allocations Changed in version 2.6: For all new collections, usePowerOf2Sizes
became the default allocation strategy. To change the default allocation strategy, use the
newCollectionsUsePowerOf2Sizes parameter.
mongod uses an allocation strategy called usePowerOf2Sizes where each record has a size in bytes that is a
power of 2 (e.g. 32, 64, 128, 256, 512...16777216.) The smallest allocation for a document is 32 bytes. The power of
2 sizes allocation strategy has two key properties:
there are a limited number of record allocation sizes, which makes it easier for mongod to reuse existing
allocations, which will reduce fragmentation in some cases.
in many cases, the record allocations are signicantly larger than the documents they hold. This allows docu-
ments to grow while minimizing or eliminating the chance that the mongod will need to allocate a new record
if the document grows.
The usePowerOf2Sizes strategy does not eliminate document reallocation as a result of document growth, but it
minimizes its occurrence in many common operations.
Exact Fit Allocation The exact t allocation strategy allocates record sizes based on the size of the document and
an additional padding factor. Each collection has its own padding factor, which defaults to 1 when you insert the rst
document in a collection. MongoDB dynamically adjusts the padding factor up to 2 depending on the rate of growth
of the documents over the life of the collection.
To estimate total record size, compute the product of the padding factor and the size of the document. That is:
record size = paddingFactor
*
<document size>
The size of each record in a collection reects the size of the padding factor at the time of allocation. See the
paddingFactor eld in the output of db.collection.stats() to see the current padding factor for a collec-
tion.
34
On average, this exact t allocation strategy uses less storage space than the usePowerOf2Sizes strategy but will
result in higher levels of storage fragmentation if documents grow beyond the size of their initial allocation.
The compact and repairDatabase operations remove padding by default, as do the mongodump and
mongorestore. compact does allow you to specify a padding for records during compaction.
Capped Collections
Capped collections are xed-size collections that support high-throughput operations that store records in insertion
order. Capped collections work like circular buffers: once a collection lls its allocated space, it makes room for new
documents by overwriting the oldest documents in the collection.
See http://docs.mongodb.org/manualcore/capped-collections for more information.
3 MongoDB CRUD Tutorials
The following tutorials provide instructions for querying and modifying data. For a higher-level overview of these
operations, see MongoDB CRUD Operations (page 3).
Insert Documents (page 35) Insert new documents into a collection.
Query Documents (page 39) Find documents in a collection using search criteria.
Limit Fields to Return from a Query (page 45) Limit which elds are returned by a query.
Iterate a Cursor in the mongo Shell (page 47) Access documents returned by a find query by iterating the cursor,
either manually or using the iterator index.
Analyze Query Performance (page 48) Analyze the efciency of queries and determine how a query uses available
indexes.
Modify Documents (page 49) Modify documents in a collection
Remove Documents (page 53) Remove documents from a collection.
Perform Two Phase Commits (page 54) Use two-phase commits when writing data to multiple documents.
Create Tailable Cursor (page 60) Create tailable cursors for use in capped collections with high numbers of write
operations for which an index would be too expensive.
Isolate Sequence of Operations (page 62) Use the <isolation> isolated operator to isolate a single write
operation that affects multiple documents, preventing other operations from interrupting the sequence of write
operations.
Create an Auto-Incrementing Sequence Field (page 64) Describes how to create an incrementing sequence number
for the _id eld using a Counters Collection or an Optimistic Loop.
Limit Number of Elements in an Array after an Update (page 67) Use $push with various modiers to sort and
maintain an array of xed size after update
3.1 Insert Documents
In MongoDB, the db.collection.insert() method adds new documents into a collection.
35
Insert a Document
Step 1: Insert a document into a collection.
Insert a document into a collection named inventory. The operation will create the collection if the collection does
not currently exist.
db.inventory.insert(
{
item: "ABC1",
details: {
model: "14Q3",
manufacturer: "XYZ Company"
},
stock: [ { size: "S", qty: 25 }, { size: "M", qty: 50 } ],
category: "clothing"
}
)
The operation returns a WriteResult object with the status of the operation. A successful insert of the document
returns the following object:
WriteResult({ "nInserted" : 1 })
The nInserted eld species the number of documents inserted. If the operation encounters an error, the
WriteResult object will contain the error information.
Step 2: Review the inserted document.
If the insert operation is successful, verify the insertion by querying the collection.
db.inventory.find()
The document you inserted should return.
{ "_id" : ObjectId("53d98f133bb604791249ca99"), "item" : "ABC1", "details" : { "model" : "14Q3", "manufacturer" : "XYZ Company" }, "stock" : [ { "size" : "S", "qty" : 25 }, { "size" : "M", "qty" : 50 } ], "category" : "clothing" }
The returned document shows that MongoDB added an _id eld to the document. If a client inserts a document that
does not contain the _id eld, MongoDB adds the eld with the value set to a generated ObjectId
6
. The ObjectId
7
values in your documents will differ from the ones shown.
Insert an Array of Documents
You can pass an array of documents to the db.collection.insert() method to insert multiple documents.
Step 1: Create an array of documents.
Dene a variable mydocuments that holds an array of documents to insert.
var mydocuments =
[
{
6
http://docs.mongodb.org/manual/reference/object-id
7
http://docs.mongodb.org/manual/reference/object-id
36
item: "ABC2",
details: { model: "14Q3", manufacturer: "M1 Corporation" },
stock: [ { size: "M", qty: 50 } ],
category: "clothing"
},
{
item: "MNO2",
details: { model: "14Q3", manufacturer: "ABC Company" },
stock: [ { size: "S", qty: 5 }, { size: "M", qty: 5 }, { size: "L", qty: 1 } ],
category: "clothing"
},
{
item: "IJK2",
details: { model: "14Q2", manufacturer: "M5 Corporation" },
stock: [ { size: "S", qty: 5 }, { size: "L", qty: 1 } ],
category: "houseware"
}
];
Step 2: Insert the documents.
Pass the mydocuments array to the db.collection.insert() to perform a bulk insert.
db.inventory.insert( mydocuments );
The method returns a BulkWriteResult object with the status of the operation. A successful insert of the docu-
ments returns the following object:
BulkWriteResult({
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 3,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
The nInserted eld species the number of documents inserted. If the operation encounters an error, the
BulkWriteResult object will contain information regarding the error.
The inserted documents will each have an _id eld added by MongoDB.
Insert Multiple Documents with Bulk
New in version 2.6.
MongoDB provides a Bulk() API that you can use to perform multiple write operations in bulk. The following
sequence of operations describes how you would use the Bulk() API to insert a group of documents into a MongoDB
collection.
Step 1: Initialize a Bulk operations builder.
Initialize a Bulk operations builder for the collection inventory.
37
var bulk = db.inventory.initializeUnorderedBulkOp();
The operation returns an unordered operations builder which maintains a list of operations to perform. Unordered
operations means that MongoDB can execute in parallel as well as in nondeterministic order. If an error occurs during
the processing of one of the write operations, MongoDB will continue to process remaining write operations in the
list.
You can also initialize an ordered operations builder; see db.collection.initializeOrderedBulkOp()
for details.
Step 2: Add insert operations to the bulk object.
Add two insert operations to the bulk object using the Bulk.insert() method.
bulk.insert(
{
item: "BE10",
details: { model: "14Q2", manufacturer: "XYZ Company" },
stock: [ { size: "L", qty: 5 } ],
category: "clothing"
}
);
bulk.insert(
{
item: "ZYT1",
details: { model: "14Q1", manufacturer: "ABC Company" },
stock: [ { size: "S", qty: 5 }, { size: "M", qty: 5 } ],
category: "houseware"
}
);
Step 3: Execute the bulk operation.
Call the execute() method on the bulk object to execute the operations in its list.
bulk.execute();
The method returns a BulkWriteResult object with the status of the operation. A successful insert of the docu-
ments returns the following object:
BulkWriteResult({
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 2,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
The nInserted eld species the number of documents inserted. If the operation encounters an error, the
BulkWriteResult object will contain information regarding the error.
38
Additional Examples and Methods
For more examples, see db.collection.insert().
The db.collection.update() method, the db.collection.findAndModify(), and the
db.collection.save() method can also add new documents. See the individual reference pages for the
methods for more information and examples.
3.2 Query Documents
In MongoDB, the db.collection.find() method retrieves documents from a collection.
8
The
db.collection.find() method returns a cursor (page 10) to the retrieved documents.
This tutorial provides examples of read operations using the db.collection.find() method in the mongo
shell. In these examples, the retrieved documents contain all their elds. To restrict the elds to return in the retrieved
documents, see Limit Fields to Return from a Query (page 45).
Select All Documents in a Collection
An empty query document ({}) selects all documents in the collection:
db.inventory.find( {} )
Not specifying a query document to the find() is equivalent to specifying an empty query document. Therefore the
following operation is equivalent to the previous operation:
db.inventory.find()
Specify Equality Condition
To specify equality condition, use the query document { <field>: <value> } to select all documents that
contain the <field> with the specied <value>.
The following example retrieves from the inventory collection all documents where the type eld has the value
snacks:
db.inventory.find( { type: "snacks" } )
Specify Conditions Using Query Operators
A query document can use the query operators to specify conditions in a MongoDB query.
The following example selects all documents in the inventory collection where the value of the type eld is either
food or snacks:
db.inventory.find( { type: { $in: [ 'food', 'snacks' ] } } )
Although you can express this query using the $or operator, use the $in operator rather than the $or operator when
performing equality checks on the same eld.
Refer to the http://docs.mongodb.org/manualreference/operator document for the complete list
of query operators.
8
The db.collection.findOne() method also performs a read operation to return a single document. Internally, the
db.collection.findOne() method is the db.collection.find() method with a limit of 1.
39
Specify AND Conditions
A compound query can specify conditions for more than one eld in the collections documents. Implicitly, a logical
AND conjunction connects the clauses of a compound query so that the query selects the documents in the collection
that match all the conditions.
In the following example, the query document species an equality match on the eld type and a less than ($lt)
comparison match on the eld price:
db.inventory.find( { type: 'food', price: { $lt: 9.95 } } )
This query selects all documents where the type eld has the value food and the value of the price eld is less
than 9.95. See comparison operators for other comparison operators.
Specify OR Conditions
Using the $or operator, you can specify a compound query that joins each clause with a logical OR conjunction so
that the query selects the documents in the collection that match at least one condition.
In the following example, the query document selects all documents in the collection where the eld qty has a value
greater than ($gt) 100 or the value of the price eld is less than ($lt) 9.95:
db.inventory.find(
{
$or: [ { qty: { $gt: 100 } }, { price: { $lt: 9.95 } } ]
}
)
Specify AND as well as OR Conditions
With additional clauses, you can specify precise conditions for matching documents.
In the following example, the compound query document selects all documents in the collection where the value of
the type eld is food and either the qty has a value greater than ($gt) 100 or the value of the price eld is
less than ($lt) 9.95:
db.inventory.find(
{
type: 'food',
$or: [ { qty: { $gt: 100 } }, { price: { $lt: 9.95 } } ]
}
)
Embedded Documents
When the eld holds an embedded document, a query can either specify an exact match on the embedded document
or specify a match by individual elds in the embedded document using the dot notation.
Exact Match on the Embedded Document
To specify an equality match on the whole embedded document, use the query document { <field>: <value>
} where <value> is the document to match. Equality matches on an embedded document require an exact match of
the specied <value>, including the eld order.
40
In the following example, the query matches all documents where the value of the eld producer is an embedded
document that contains only the eld company with the value ABC123 and the eld address with the value
123 Street, in the exact order:
db.inventory.find(
{
producer:
{
company: 'ABC123',
address: '123 Street'
}
}
)
Equality Match on Fields within an Embedded Document
Use the dot notation to match by specic elds in an embedded document. Equality matches for specic elds in
an embedded document will select documents in the collection where the embedded document contains the specied
elds with the specied values. The embedded document can contain additional elds.
In the following example, the query uses the dot notation to match all documents where the value of the eld
producer is an embedded document that contains a eld company with the value ABC123 and may contain
other elds:
db.inventory.find( { 'producer.company': 'ABC123' } )
Arrays
When the eld holds an array, you can query for an exact array match or for specic values in the array. If the array
holds embedded documents, you can query for specic elds in the embedded documents using dot notation.
If you specify multiple conditions using the $elemMatch operator, the array must contain at least one element that
satises all the conditions. See Single Element Satises the Criteria (page 42).
If you specify multiple conditions without using the $elemMatch operator, then some combination of the array
elements, not necessarily a single element, must satisfy all the conditions; i.e. different elements in the array can
satisfy different parts of the conditions. See Combination of Elements Satises the Criteria (page 42).
Consider an inventory collection that contains the following documents:
{ _id: 5, type: "food", item: "aaa", ratings: [ 5, 8, 9 ] }
{ _id: 6, type: "food", item: "bbb", ratings: [ 5, 9 ] }
{ _id: 7, type: "food", item: "ccc", ratings: [ 9, 5, 8 ] }
Exact Match on an Array
To specify equality match on an array, use the query document { <field>: <value> } where <value> is
the array to match. Equality matches on the array require that the array eld match exactly the specied <value>,
including the element order.
The following example queries for all documents where the eld ratings is an array that holds exactly three ele-
ments, 5, 8, and 9, in this order:
db.inventory.find( { ratings: [ 5, 8, 9 ] } )
41
The operation returns the following document:
{ "_id" : 5, "type" : "food", "item" : "aaa", "ratings" : [ 5, 8, 9 ] }
Match an Array Element
Equality matches can specify a single element in the array to match. These specications match if the array contains
at least one element with the specied value.
The following example queries for all documents where ratings is an array that contains 5 as one of its elements:
db.inventory.find( { ratings: 5 } )
The operation returns the following documents:
{ "_id" : 5, "type" : "food", "item" : "aaa", "ratings" : [ 5, 8, 9 ] }
{ "_id" : 6, "type" : "food", "item" : "bbb", "ratings" : [ 5, 9 ] }
{ "_id" : 7, "type" : "food", "item" : "ccc", "ratings" : [ 9, 5, 8 ] }
Match a Specic Element of an Array
Equality matches can specify equality matches for an element at a particular index or position of the array using the
dot notation.
In the following example, the query uses the dot notation to match all documents where the ratings array contains
5 as the rst element:
db.inventory.find( { 'ratings.0': 5 } )
The operation returns the following documents:
{ "_id" : 5, "type" : "food", "item" : "aaa", "ratings" : [ 5, 8, 9 ] }
{ "_id" : 6, "type" : "food", "item" : "bbb", "ratings" : [ 5, 9 ] }
Specify Multiple Criteria for Array Elements
Single Element Satises the Criteria Use $elemMatch operator to specify multiple criteria on the elements of
an array such that at least one array element satises all the specied criteria.
The following example queries for documents where the ratings array contains at least one element that is greater
than ($gt) 5 and less than ($lt) 9:
db.inventory.find( { ratings: { $elemMatch: { $gt: 5, $lt: 9 } } } )
The operation returns the following documents, whose ratings array contains the element 8 which meets the crite-
ria:
{ "_id" : 5, "type" : "food", "item" : "aaa", "ratings" : [ 5, 8, 9 ] }
{ "_id" : 7, "type" : "food", "item" : "ccc", "ratings" : [ 9, 5, 8 ] }
Combination of Elements Satises the Criteria The following example queries for documents where the
ratings array contains elements that in some combination satisfy the query conditions; e.g., one element can satisfy
the greater than 5 condition and another element can satisfy the less than 9 condition, or a single element can satisfy
both:
42
db.inventory.find( { ratings: { $gt: 5, $lt: 9 } } )
The operation returns the following documents:
{ "_id" : 5, "type" : "food", "item" : "aaa", "ratings" : [ 5, 8, 9 ] }
{ "_id" : 6, "type" : "food", "item" : "bbb", "ratings" : [ 5, 9 ] }
{ "_id" : 7, "type" : "food", "item" : "ccc", "ratings" : [ 9, 5, 8 ] }
The document with the "ratings" : [ 5, 9 ] matches the query since the element 9 is greater than 5 (the
rst condition) and the element 5 is less than 9 (the second condition).
Array of Embedded Documents
Consider that the inventory collection includes the following documents:
{
_id: 100,
type: "food",
item: "xyz",
qty: 25,
price: 2.5,
ratings: [ 5, 8, 9 ],
memos: [ { memo: "on time", by: "shipping" }, { memo: "approved", by: "billing" } ]
}
{
_id: 101,
type: "fruit",
item: "jkl",
qty: 10,
price: 4.25,
ratings: [ 5, 9 ],
memos: [ { memo: "on time", by: "payment" }, { memo: "delayed", by: "shipping" } ]
}
Match a Field in the Embedded Document Using the Array Index If you know the array index of the embedded
document, you can specify the document using the subdocuments position using the dot notation.
The following example selects all documents where the memos contains an array whose rst element (i.e. index is 0)
is a document that contains the eld by whose value is shipping:
db.inventory.find( { 'memos.0.by': 'shipping' } )
The operation returns the following document:
{
_id: 100,
type: "food",
item: "xyz",
qty: 25,
price: 2.5,
ratings: [ 5, 8, 9 ],
memos: [ { memo: "on time", by: "shipping" }, { memo: "approved", by: "billing" } ]
}
43
Match a Field Without Specifying Array Index If you do not know the index position of the document in the array,
concatenate the name of the eld that contains the array, with a dot (.) and the name of the eld in the subdocument.
The following example selects all documents where the memos eld contains an array that contains at least one
embedded document that contains the eld by with the value shipping:
db.inventory.find( { 'memos.by': 'shipping' } )
The operation returns the following documents:
{
_id: 100,
type: "food",
item: "xyz",
qty: 25,
price: 2.5,
ratings: [ 5, 8, 9 ],
memos: [ { memo: "on time", by: "shipping" }, { memo: "approved", by: "billing" } ]
}
{
_id: 101,
type: "fruit",
item: "jkl",
qty: 10,
price: 4.25,
ratings: [ 5, 9 ],
memos: [ { memo: "on time", by: "payment" }, { memo: "delayed", by: "shipping" } ]
}
Specify Multiple Criteria for Array of Documents
Single Element Satises the Criteria Use $elemMatch operator to specify multiple criteria on an array of em-
bedded documents such that at least one embedded document satises all the specied criteria.
The following example queries for documents where the memos array has at least one embedded document that
contains both the eld memo equal to on time and the eld by equal to shipping:
db.inventory.find(
{
memos:
{
$elemMatch:
{
memo: 'on time',
by: 'shipping'
}
}
}
)
The operation returns the following document:
{
_id: 100,
type: "food",
item: "xyz",
qty: 25,
price: 2.5,
44
ratings: [ 5, 8, 9 ],
memos: [ { memo: "on time", by: "shipping" }, { memo: "approved", by: "billing" } ]
}
Combination of Elements Satises the Criteria The following example queries for documents where the memos
array contains elements that in some combination satisfy the query conditions; e.g. one element satises the eld
memo equal to on time condition and another element satises the eld by equal to shipping condition, or
a single element can satisfy both criteria:
db.inventory.find(
{
'memos.memo': 'on time',
'memos.by': 'shipping'
}
)
The query returns the following documents:
{
_id: 100,
type: "food",
item: "xyz",
qty: 25,
price: 2.5,
ratings: [ 5, 8, 9 ],
memos: [ { memo: "on time", by: "shipping" }, { memo: "approved", by: "billing" } ]
}
{
_id: 101,
type: "fruit",
item: "jkl",
qty: 10,
price: 4.25,
ratings: [ 5, 9 ],
memos: [ { memo: "on time", by: "payment" }, { memo: "delayed", by: "shipping" } ]
}
3.3 Limit Fields to Return from a Query
The projection document limits the elds to return for all matching documents. The projection document can specify
the inclusion of elds or the exclusion of elds.
The specications have the following forms:
Syntax Description
<field>: <1 or true> Specify the inclusion of a eld.
<field>: <0 or false> Specify the suppression of the eld.
Important: The _id eld is, by default, included in the result set. To suppress the _id eld from the result set,
specify _id: 0 in the projection document.
You cannot combine inclusion and exclusion semantics in a single projection with the exception of the _id eld.
This tutorial offers various query examples that limit the elds to return for all matching documents. The examples in
this tutorial use a collection inventory and use the db.collection.find() method in the mongo shell. The
45
db.collection.find() method returns a cursor (page 10) to the retrieved documents. For examples on query
selection criteria, see Query Documents (page 39).
Return All Fields in Matching Documents
If you specify no projection, the find() method returns all elds of all documents that match the query.
db.inventory.find( { type: 'food' } )
This operation will return all documents in the inventory collection where the value of the type eld is food.
The returned documents contain all its elds.
Return the Specied Fields and the _id Field Only
A projection can explicitly include several elds. In the following operation, find() method returns all documents
that match the query. In the result set, only the item and qty elds and, by default, the _id eld return in the
matching documents.
db.inventory.find( { type: 'food' }, { item: 1, qty: 1 } )
Return Specied Fields Only
You can remove the _id eld from the results by specifying its exclusion in the projection, as in the following
example:
db.inventory.find( { type: 'food' }, { item: 1, qty: 1, _id:0 } )
This operation returns all documents that match the query. In the result set, only the item and qty elds return in
the matching documents.
Return All But the Excluded Field
To exclude a single eld or group of elds you can use a projection in the following form:
db.inventory.find( { type: 'food' }, { type:0 } )
This operation returns all documents where the value of the type eld is food. In the result set, the type eld does
not return in the matching documents.
With the exception of the _id eld you cannot combine inclusion and exclusion statements in projection documents.
Projection for Array Fields
For elds that contain arrays, MongoDB provides the following projection operators: $elemMatch, $slice, and
$.
For example, the inventory collection contains the following document:
{ "_id" : 5, "type" : "food", "item" : "aaa", "ratings" : [ 5, 8, 9 ] }
Then the following operation uses the $slice projection operator to return just the rst two elements in the ratings
array.
46
db.inventory.find( { _id: 5 }, { ratings: { $slice: 2 } } )
$elemMatch, $slice, and $ are the only way to project portions of an array. For instance, you cannot project a
portion of an array using the array index; e.g. { "ratings.0": 1 } projection will not project the array with
the rst element.
3.4 Iterate a Cursor in the mongo Shell
The db.collection.find() method returns a cursor. To access the documents, you need to iterate the cursor.
However, in the mongo shell, if the returned cursor is not assigned to a variable using the var keyword, then the
cursor is automatically iterated up to 20 times to print up to the rst 20 documents in the results. The following
describes ways to manually iterate the cursor to access the documents or to use the iterator index.
Manually Iterate the Cursor
In the mongo shell, when you assign the cursor returned from the find() method to a variable using the var
keyword, the cursor does not automatically iterate.
You can call the cursor variable in the shell to iterate up to 20 times
9
and print the matching documents, as in the
following example:
var myCursor = db.inventory.find( { type: 'food' } );
myCursor
You can also use the cursor method next() to access the documents, as in the following example:
var myCursor = db.inventory.find( { type: 'food' } );
while (myCursor.hasNext()) {
print(tojson(myCursor.next()));
}
As an alternative print operation, consider the printjson() helper method to replace print(tojson()):
var myCursor = db.inventory.find( { type: 'food' } );
while (myCursor.hasNext()) {
printjson(myCursor.next());
}
You can use the cursor method forEach() to iterate the cursor and access the documents, as in the following
example:
var myCursor = db.inventory.find( { type: 'food' } );
myCursor.forEach(printjson);
See JavaScript cursor methods and your driver documentation for more information on cursor methods.
Iterator Index
In the mongo shell, you can use the toArray() method to iterate the cursor and return the documents in an array,
as in the following:
9
You can use the DBQuery.shellBatchSize to change the number of iteration from the default value 20. See mongo-shell-executing-
queries for more information.
47
var myCursor = db.inventory.find( { type: 'food' } );
var documentArray = myCursor.toArray();
var myDocument = documentArray[3];
The toArray() method loads into RAM all documents returned by the cursor; the toArray() method exhausts
the cursor.
Additionally, some drivers provide access to the documents by using an index on the cursor (i.e.
cursor[index]). This is a shortcut for rst calling the toArray() method and then using an index on the
resulting array.
Consider the following example:
var myCursor = db.inventory.find( { type: 'food' } );
var myDocument = myCursor[3];
The myCursor[3] is equivalent to the following example:
myCursor.toArray() [3];
3.5 Analyze Query Performance
The explain() cursor method allows you to inspect the operation of the query system. This method is useful for
analyzing the efciency of queries, and for determining how the query uses the index. The explain() method tests
the query operation, and not the timing of query performance. Because explain() attempts multiple query plans,
it does not reect an accurate timing of query performance.
Evaluate the Performance of a Query
To use the explain() method, call the method on a cursor returned by find().
Example
Evaluate a query on the type eld on the collection inventory that has an index on the type eld.
db.inventory.find( { type: 'food' } ).explain()
Consider the results:
{
"cursor" : "BtreeCursor type_1",
"isMultiKey" : false,
"n" : 5,
"nscannedObjects" : 5,
"nscanned" : 5,
"nscannedObjectsAllPlans" : 5,
"nscannedAllPlans" : 5,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : { "type" : [
[ "food",
"food" ]
] },
"server" : "mongodbo0.example.net:27017" }
48
The BtreeCursor value of the cursor eld indicates that the query used an index.
This query returned 5 documents, as indicated by the n eld.
To return these 5 documents, the query scanned 5 documents from the index, as indicated by the nscanned eld,
and then read 5 full documents from the collection, as indicated by the nscannedObjects eld.
Without the index, the query would have scanned the whole collection to return the 5 documents.
See explain-results method for full details on the output.
Compare Performance of Indexes
To manually compare the performance of a query using more than one index, you can use the hint() and
explain() methods in conjunction.
Example
Evaluate a query using different indexes:
db.inventory.find( { type: 'food' } ).hint( { type: 1 } ).explain()
db.inventory.find( { type: 'food' } ).hint( { type: 1, name: 1 } ).explain()
These return the statistics regarding the execution of the query using the respective index.
Note: If you run explain() without including hint(), the query optimizer reevaluates the query and runs against
multiple indexes before returning the query statistics.
For more detail on the explain output, see explain-results.
3.6 Modify Documents
MongoDB provides the update() method to update the documents of a collection. The method accepts as its
parameters:
an update conditions document to match the documents to update,
an update operations document to specify the modication to perform, and
an options document.
To specify the update condition, use the same structure and syntax as the query conditions.
By default, update() updates a single document. To update multiple documents, use the multi option.
Update Specic Fields in a Document
To change a eld value, MongoDB provides update operators
10
, such as $set to modify values.
Some update operators, such as $set, will create the eld if the eld does not exist. See the individual update
operator
11
reference.
10
http://docs.mongodb.org/manual/reference/operator/update
11
http://docs.mongodb.org/manual/reference/operator/update
49
Step 1: Use update operators to change eld values.
For the document with item equal to "MNO2", use the $set operator to update the category eld and the
details eld to the specied values and the $currentDate operator to update the eld lastModified with
the current date.
db.inventory.update(
{ item: "MNO2" },
{
$set: {
category: "apparel",
details: { model: "14Q3", manufacturer: "XYZ Company" }
},
$currentDate: { lastModified: true }
}
)
The update operation returns a WriteResult object which contains the status of the operation. A successful update
of the document returns the following object:
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
The nMatched eld species the number of existing documents matched for the update, and nModified species
the number of existing documents modied.
Step 2: Update an embedded eld.
To update a eld within an embedded document, use the dot notation. When using the dot notation, enclose the whole
dotted eld name in quotes.
The following updates the model eld within the embedded details document.
db.inventory.update(
{ item: "ABC1" },
{ $set: { "details.model": "14Q2" } }
)
The update operation returns a WriteResult object which contains the status of the operation. A successful update
of the document returns the following object:
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Step 3: Update multiple documents.
By default, the update() method updates a single document. To update multiple documents, use the multi option
in the update() method.
Update the category eld to "apparel" and update the lastModified eld to the current date for all docu-
ments that have category eld equal to "clothing".
db.inventory.update(
{ category: "clothing" },
{
$set: { category: "apparel" },
$currentDate: { lastModified: true }
},
50
{ multi: true }
)
The update operation returns a WriteResult object which contains the status of the operation. A successful update
of the document returns the following object:
WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 3 })
Replace the Document
To replace the entire content of a document except for the _id eld, pass an entirely new document as the second
argument to update().
The replacement document can have different elds from the original document. In the replacement document, you
can omit the _id eld since the _id eld is immutable. If you do include the _id eld, it must be the same value as
the existing value.
Step 1: Replace a document.
The following operation replaces the document with item equal to "BE10". The newly replaced document will only
contain the the _id eld and the elds in the replacement document.
db.inventory.update(
{ item: "BE10" },
{
item: "BE05",
stock: [ { size: "S", qty: 20 }, { size: "M", qty: 5 } ],
category: "apparel"
}
)
The update operation returns a WriteResult object which contains the status of the operation. A successful update
of the document returns the following object:
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
upsert Option
By default, if no document matches the update query, the update() method does nothing.
However, by specifying upsert: true, the update() method either updates matching document or documents, or
inserts a new document using the update specication if no matching document exists.
Step 1: Specify upsert: true for the update replacement operation.
When you specify upsert: true for an update operation to replace a document and no matching documents
are found, MongoDB creates a new document using the equality conditions in the update conditions document, and
replaces this document, except for the _id eld if specied, with the update document.
The following operation either updates a matching document by replacing it with a new document or adds a new
document if no matching document exists.
51
db.inventory.update(
{ item: "TBD1" },
{
item: "TBD1",
details: { "model" : "14Q4", "manufacturer" : "ABC Company" },
stock: [ { "size" : "S", "qty" : 25 } ],
category: "houseware"
},
{ upsert: true }
)
The update operation returns a WriteResult object which contains the status of the operation, including whether
the db.collection.update() method modied an existing document or added a new document.
WriteResult({
"nMatched" : 0,
"nUpserted" : 1,
"nModified" : 0,
"_id" : ObjectId("53dbd684babeaec6342ed6c7")
})
The nMatched eld shows that the operation matched 0 documents.
The nUpserted of 1 shows that the update added a document.
The nModified of 0 species that no existing documents were updated.
The _id eld shows the generated _id eld for the added document.
Step 2: Specify an upsert: true for the update specic elds operation.
When you specify an upsert: true for an update operation that modies specic elds and no matching docu-
ments are found, MongoDB creates a new document using the equality conditions in the update conditions document,
and applies the modication as specied in the update document.
The following update operation either updates specic elds of a matching document or adds a new document if no
matching document exists.
db.inventory.update(
{ item: "TBD2" },
{
$set: {
details: { "model" : "14Q3", "manufacturer" : "IJK Co." },
category: "houseware"
}
},
{ upsert: true }
)
The update operation returns a WriteResult object which contains the status of the operation, including whether
the db.collection.update() method modied an existing document or added a new document.
WriteResult({
"nMatched" : 0,
"nUpserted" : 1,
"nModified" : 0,
"_id" : ObjectId("53dbd7c8babeaec6342ed6c8")
})
52
The nMatched eld shows that the operation matched 0 documents.
The nUpserted of 1 shows that the update added a document.
The nModified of 0 species that no existing documents were updated.
The _id eld shows the generated _id eld for the added document.
Additional Examples and Methods
For more examples, see Update examples in the db.collection.update() reference page.
The db.collection.findAndModify() and the db.collection.save() method can also modify exist-
ing documents or insert a new one. See the individual reference pages for the methods for more information and
examples.
3.7 Remove Documents
In MongoDB, the db.collection.remove() method removes documents from a collection. You can remove
all documents from a collection, remove all documents that match a condition, or limit the operation to remove just a
single document.
This tutorial provides examples of remove operations using the db.collection.remove() method in the mongo
shell.
Remove All Documents
To remove all documents from a collection, pass an empty query document {} to the remove() method. The
remove() method does not remove the indexes.
The following example removes all documents from the inventory collection:
db.inventory.remove({})
To remove all documents from a collection, it may be more efcient to use the drop() method to drop the entire
collection, including the indexes, and then recreate the collection and rebuild the indexes.
Remove Documents that Match a Condition
To remove the documents that match a deletion criteria, call the remove() method with the <query> parameter.
The following example removes all documents from the inventory collection where the type eld equals food:
db.inventory.remove( { type : "food" } )
For large deletion operations, it may be more efcient to copy the documents that you want to keep to a new collection
and then use drop() on the original collection.
Remove a Single Document that Matches a Condition
To remove a single document, call the remove() method with the justOne parameter set to true or 1.
The following example removes one document from the inventory collection where the type eld equals food:
db.inventory.remove( { type : "food" }, 1 )
To delete a single document sorted by some specied order, use the ndAndModify() method.
53
3.8 Perform Two Phase Commits
Synopsis
This document provides a pattern for doing multi-document updates or multi-document transactions using a two-
phase commit approach for writing data to multiple documents. Additionally, you can extend this process to provide
a rollback-like (page 58) functionality.
Background
Operations on a single document are always atomic with MongoDB databases; however, operations that involve multi-
ple documents, which are often referred to as multi-document transactions, are not atomic. Since documents can be
fairly complex and contain multiple nested documents, single-document atomicity provides necessary support for
many practical use cases.
Despite the power of single-document atomic operations, there are cases that require multi-document transactions.
When executing a transaction composed of sequential operations, certain issues arise, such as:
Atomicity: if one operation fails, the previous operation within the transaction must rollback to the previous
state (i.e. the nothing, in all or nothing).
Consistency: if a major failure (i.e. network, hardware) interrupts the transaction, the database must be able to
recover a consistent state.
For situations that require multi-document transactions, you can implement two-phase commit in your application to
provide support for these kinds of multi-document updates. Using two-phase commit ensures that data is consistent
and, in case of an error, the state that preceded the transaction is recoverable (page 58). During the procedure, however,
documents can represent pending data and states.
Note: Because only single-document operations are atomic with MongoDB, two-phase commits can only offer
transaction-like semantics. It is possible for applications to return intermediate data at intermediate points during the
two-phase commit or rollback.
Pattern
Overview
Consider a scenario where you want to transfer funds from account A to account B. In a relational database system,
you can subtract the funds from A and add the funds to B in a single multi-statement transaction. In MongoDB, you
can emulate a two-phase commit to achieve a comparable result.
The examples in this tutorial use the following two collections:
1. A collection named accounts to store account information.
2. A collection named transactions to store information on the fund transfer transactions.
Initialize Source and Destination Accounts
Insert into the accounts collection a document for account A and a document for account B.
db.accounts.insert(
[
{ _id: "A", balance: 1000, pendingTransactions: [] },
54
{ _id: "B", balance: 1000, pendingTransactions: [] }
]
)
The operation returns a BulkWriteResult() object with the status of the operation. Upon successful insert, the
BulkWriteResult() has nInserted set to 2 .
Initialize Transfer Record
For each fund transfer to perform, insert into the transactions collection a document with the transfer information.
The document contains the following elds:
source and destination elds, which refer to the _id elds from the accounts collection,
value eld, which species the amount of transfer affecting the balance of the source and
destination accounts,
state eld, which reects the current state of the transfer. The state eld can have the value of initial,
pending, applied, done, canceling, and canceled.
lastModified eld, which reects last modication date.
To initialize the transfer of 100 from account A to account B, insert into the transactions collection a document
with the transfer information, the transaction state of "initial", and the lastModified eld set to the current
date:
db.transactions.insert(
{ _id: 1, source: "A", destination: "B", value: 100, state: "initial", lastModified: new Date() }
)
The operation returns a WriteResult() object with the status of the operation. Upon successful insert, the
WriteResult() object has nInserted set to 1.
Transfer Funds Between Accounts Using Two-Phase Commit
Step 1: Retrieve the transaction to start. Fromthe transactions collection, nd a transaction in the initial
state. Currently the transactions collection has only one document, namely the one added in the Initialize
Transfer Record (page 55) step. If the collection contains additional documents, the query will return any transaction
with an initial state unless you specify additional query conditions.
var t = db.transactions.findOne( { state: "initial" } )
Type the variable t in the mongo shell to print the contents of the variable. The operation should print a document
similar to the following except the lastModified eld should reect date of your insert operation:
{ "_id" : 1, "source" : "A", "destination" : "B", "value" : 100, "state" : "initial", "lastModified" : ISODate("2014-07-11T20:39:26.345Z") }
Step 2: Update transaction state to pending. Set the transaction state frominitial to pending and use the
$currentDate operator to set the lastModified eld to the current date.
db.transactions.update(
{ _id: t._id, state: "initial" },
{
$set: { state: "pending" },
$currentDate: { lastModified: true }
55
}
)
The operation returns a WriteResult() object with the status of the operation. Upon successful update, the
nMatched and nModified displays 1.
In the update statement, the state: "initial" condition ensures that no other process has already updated this
record. If nMatched and nModified is 0, go back to the rst step to get a different transaction and restart the
procedure.
Step 3: Apply the transaction to both accounts. Apply the transaction t to both accounts using the update()
method if the transaction has not been applied to the accounts. In the update condition, include the condition
pendingTransactions: { $ne: t._id } in order to avoid re-applying the transaction if the step is run
more than once.
To apply the transaction to the account, update both the balance eld and the pendingTransactions eld.
Update the source account, subtracting from its balance the transaction value and adding to its
pendingTransactions array the transaction _id.
db.accounts.update(
{ _id: t.source, pendingTransactions: { $ne: t._id } },
{ $inc: { balance: -t.value }, $push: { pendingTransactions: t._id } }
)
Upon successful update, the method returns a WriteResult() object with nMatched and nModified set to 1.
Update the destination account, adding to its balance the transaction value and adding to its
pendingTransactions array the transaction _id .
db.accounts.update(
{ _id: t.destination, pendingTransactions: { $ne: t._id } },
{ $inc: { balance: t.value }, $push: { pendingTransactions: t._id } }
)
Upon successful update, the method returns a WriteResult() object with nMatched and nModified set to 1.
Step 4: Update transaction state to applied. Use the following update() operation to set the transactions
state to applied and update the lastModified eld:
db.transactions.update(
{ _id: t._id, state: "pending" },
{
$set: { state: "applied" },
$currentDate: { lastModified: true }
}
)
Upon successful update, the method returns a WriteResult() object with nMatched and nModified set to 1.
Step 5: Update both accounts list of pending transactions. Remove the applied transaction _id from the
pendingTransactions array for both accounts.
Update the source account.
db.accounts.update(
{ _id: t.source, pendingTransactions: t._id },
56
{ $pull: { pendingTransactions: t._id } }
)
Upon successful update, the method returns a WriteResult() object with nMatched and nModified set to 1.
Update the destination account.
db.accounts.update(
{ _id: t.destination, pendingTransactions: t._id },
{ $pull: { pendingTransactions: t._id } }
)
Upon successful update, the method returns a WriteResult() object with nMatched and nModified set to 1.
Step 6: Update transaction state to done. Complete the transaction by setting the state of the transaction to
done and updating the lastModified eld:
db.transactions.update(
{ _id: t._id, state: "applied" },
{
$set: { state: "done" },
$currentDate: { lastModified: true }
}
)
Upon successful update, the method returns a WriteResult() object with nMatched and nModified set to 1.
Recovering from Failure Scenarios
The most important part of the transaction procedure is not the prototypical example above, but rather the possibility
for recovering from the various failure scenarios when transactions do not complete successfully. This section presents
an overview of possible failures and provides steps to recover from these kinds of events.
Recovery Operations
The two-phase commit pattern allows applications running the sequence to resume the transaction and arrive at a
consistent state. Run the recovery operations at application startup, and possibly at regular intervals, to catch any
unnished transactions.
The time required to reach a consistent state depends on how long the application needs to recover each transaction.
The following recovery procedures uses the lastModified date as an indicator of whether the pending transaction
requires recovery; specically, if the pending or applied transaction has not been updated in the last 30 minutes,
the procedures determine that these transactions require recovery. You can use different conditions to make this
determination.
Transactions in Pending State To recover from failures that occur after step Update transaction state to pend-
ing. (page ??) but before Update transaction state to applied. (page ??)step, retrieve from the transactions
collection a pending transaction for recovery:
var dateThreshold = new Date();
dateThreshold.setMinutes(dateThreshold.getMinutes() - 30);
var t = db.transactions.findOne( { state: "pending", lastModified: { $lt: dateThreshold } } );
And resume from step Apply the transaction to both accounts. (page ??)
57
Transactions in Applied State To recover from failures that occur after step Update transaction state to applied.
(page ??) but before Update transaction state to done. (page ??)step, retrieve from the transactions collection
an applied transaction for recovery:
var dateThreshold = new Date();
dateThreshold.setMinutes(dateThreshold.getMinutes() - 30);
var t = db.transactions.findOne( { state: "applied", lastModified: { $lt: dateThreshold } } );
And resume from Update both accounts list of pending transactions. (page ??)
Rollback Operations
In some cases, you may need to roll back or undo a transaction; e.g., if the application needs to cancel the
transaction or if one of the accounts does not exist or stops existing during the transaction.
Transactions in Applied State After the Update transaction state to applied. (page ??) step, you should not roll
back the transaction. Instead, complete that transaction and create a new transaction to reverse the transaction by
switching the values in the source and the destination elds.
Transactions in Pending State After the Update transaction state to pending. (page ??) step, but before the
Update transaction state to applied. (page ??) step, you can rollback the transaction using the following procedure:
Step 1: Update transaction state to canceling. Update the transaction state from pending to canceling.
db.transactions.update(
{ _id: t._id, state: "pending" },
{
$set: { state: "canceling" },
$currentDate: { lastModified: true }
}
)
Upon successful update, the method returns a WriteResult() object with nMatched and nModified set to 1.
Step 2: Undo the transaction on both accounts. To undo the transaction on both accounts, reverse the transaction
t if the transaction has been applied. In the update condition, include the condition pendingTransactions:
t._id in order to update the account only if the pending transaction has been applied.
Update the destination account, subtracting from its balance the transaction value and removing the transaction
_id from the pendingTransactions array.
db.accounts.update(
{ _id: t.destination, pendingTransactions: t._id },
{
$inc: { balance: -t.value },
$pull: { pendingTransactions: t._id }
}
)
Upon successful update, the method returns a WriteResult() object with nMatched and nModified set to
1. If the pending transaction has not been previously applied to this account, no document will match the update
condition and nMatched and nModified will be 0.
58
Update the source account, adding to its balance the transaction value and removing the transaction _id from
the pendingTransactions array.
db.accounts.update(
{ _id: t.source, pendingTransactions: t._id },
{
$inc: { balance: t.value},
$pull: { pendingTransactions: t._id }
}
)
Upon successful update, the method returns a WriteResult() object with nMatched and nModified set to
1. If the pending transaction has not been previously applied to this account, no document will match the update
condition and nMatched and nModified will be 0.
Step 3: Update transaction state to canceled. To nish the rollback, update the transaction state from
canceling to cancelled.
db.transactions.update(
{ _id: t._id, state: "canceling" },
{
$set: { state: "cancelled" },
$currentDate: { lastModified: true }
}
)
Upon successful update, the method returns a WriteResult() object with nMatched and nModified set to 1.
Multiple Applications
Transactions exist, in part, so that multiple applications can create and run operations concurrently without causing
data inconsistency or conicts. In our procedure, to update or retrieve the transaction document, the update conditions
include a condition on the state eld to prevent reapplication of the transaction by multiple applications.
For example, applications App1 and App2 both grab the same transaction, which is in the initial state. App1
applies the whole transaction before App2 starts. When App2 attempts to perform the Update transaction state to
pending. (page ??) step, the update condition, which includes the state: "initial" criterion, will not match
any document, and the nMatched and nModified will be 0. This should signal to App2 to go back to the rst step
to restart the procedure with a different transaction.
When multiple applications are running, it is crucial that only one application can handle a given transaction at any
point in time. As such, in addition including the expected state of the transaction in the update condition, you can
also create a marker in the transaction document itself to identify the application that is handling the transaction. Use
findAndModify() method to modify the transaction and get it back in one step:
t = db.transactions.findAndModify(
{
query: { state: "initial", application: { $exists: false } },
update:
{
$set: { state: "pending", application: "App1" },
$currentDate: { lastModified: true }
},
new: true
}
)
59
Amend the transaction operations to ensure that only applications that match the identier in the application eld
apply the transaction.
If the application App1 fails during transaction execution, you can use the recovery procedures (page 57), but appli-
cations should ensure that they own the transaction before applying the transaction. For example to nd and resume
the pending job, use a query that resembles the following:
var dateThreshold = new Date();
dateThreshold.setMinutes(dateThreshold.getMinutes() - 30);
db.transactions.find(
{
application: "App1",
state: "pending",
lastModified: { $lt: dateThreshold }
}
)
Using Two-Phase Commits in Production Applications
The example transaction above is intentionally simple. For example, it assumes that it is always possible to roll back
operations to an account and that account balances can hold negative values.
Production implementations would likely be more complex. Typically, accounts need information about current bal-
ance, pending credits, and pending debits.
For all transactions, ensure that you use a level of write concern appropriate for your deployment.
3.9 Create Tailable Cursor
Overview
By default, MongoDB will automatically close a cursor when the client has exhausted all results in the cursor. How-
ever, for capped collections you may use a Tailable Cursor that remains open after the client exhausts the
results in the initial cursor. Tailable cursors are conceptually equivalent to the tail Unix command with the -f
option (i.e. with follow mode). After clients insert new additional documents into a capped collection, the tailable
cursor will continue to retrieve documents.
Use tailable cursors on capped collections that have high write volumes where indexes arent practical. For instance,
MongoDB replication uses tailable cursors to tail the primarys oplog.
Note: If your query is on an indexed eld, do not use tailable cursors, but instead, use a regular cursor. Keep track of
the last value of the indexed eld returned by the query. To retrieve the newly added documents, query the collection
again using the last value of the indexed eld in the query criteria, as in the following example:
db.<collection>.find( { indexedField: { $gt: <lastvalue> } } )
Consider the following behaviors related to tailable cursors:
Tailable cursors do not use indexes and return documents in natural order.
Because tailable cursors do not use indexes, the initial scan for the query may be expensive; but, after initially
exhausting the cursor, subsequent retrievals of the newly added documents are inexpensive.
Tailable cursors may become dead, or invalid, if either:
the query returns no match.
60
the cursor returns the document at the end of the collection and then the application deletes those docu-
ment.
A dead cursor has an id of 0.
See your driver documentation for the driver-specic method to specify the tailable cursor. For more infor-
mation on the details of specifying a tailable cursor, see MongoDB wire protocol
12
documentation.
C++ Example
The tail function uses a tailable cursor to output the results from a query to a capped collection:
The function handles the case of the dead cursor by having the query be inside a loop.
To periodically check for new data, the cursor->more() statement is also inside a loop.
#include "client/dbclient.h"
using namespace mongo;
/
*
*
Example of a tailable cursor.
*
The function "tails" the capped collection (ns) and output elements as they are added.
*
The function also handles the possibility of a dead cursor by tracking the field 'insertDate'.
*
New documents are added with increasing values of 'insertDate'.
*
/
void tail(DBClientBase& conn, const char
*
ns) {
BSONElement lastValue = minKey.firstElement();
Query query = Query().hint( BSON( "$natural" << 1 ) );
while ( 1 ) {
auto_ptr<DBClientCursor> c =
conn.query(ns, query, 0, 0, 0,
QueryOption_CursorTailable | QueryOption_AwaitData );
while ( 1 ) {
if ( !c->more() ) {
if ( c->isDead() ) {
break;
}
continue;
}
BSONObj o = c->next();
lastValue = o["insertDate"];
cout << o.toString() << endl;
}
query = QUERY( "insertDate" << GT << lastValue ).hint( BSON( "$natural" << 1 ) );
}
}
The tail function performs the following actions:
12
http://docs.mongodb.org/meta-driver/latest/legacy/mongodb-wire-protocol
61
Initialize the lastValue variable, which tracks the last accessed value. The function will use the lastValue
if the cursor becomes invalid and tail needs to restart the query. Use hint() to ensure that the query uses
the $natural order.
In an outer while(1) loop,
Query the capped collection and return a tailable cursor that blocks for several seconds waiting for new
documents
auto_ptr<DBClientCursor> c =
conn.query(ns, query, 0, 0, 0,
QueryOption_CursorTailable | QueryOption_AwaitData );
*
Specify the capped collection using ns as an argument to the function.
*
Set the QueryOption_CursorTailable option to create a tailable cursor.
*
Set the QueryOption_AwaitData option so that the returned cursor blocks for a few seconds to
wait for data.
In an inner while (1) loop, read the documents from the cursor:
*
If the cursor has no more documents and is not invalid, loop the inner while loop to recheck for
more documents.
*
If the cursor has no more documents and is dead, break the inner while loop.
*
If the cursor has documents:
output the document,
update the lastValue value,
and loop the inner while (1) loop to recheck for more documents.
If the logic breaks out of the inner while (1) loop and the cursor is invalid:
*
Use the lastValue value to create a new query condition that matches documents added after the
lastValue. Explicitly ensure $natural order with the hint() method:
query = QUERY( "insertDate" << GT << lastValue ).hint( BSON( "$natural" << 1 ) );
*
Loop through the outer while (1) loop to re-query with the new query condition and repeat.
See also:
Detailed blog post on tailable cursor
13
3.10 Isolate Sequence of Operations
Overview
Write operations are atomic on the level of a single document: no single write operation can atomically affect more
than one document or more than one collection.
When a single write operation modies multiple documents, the operation as a whole is not atomic, and other opera-
tions may interleave. The modication of a single document, or record, is always atomic, even if the write operation
modies multiple sub-documents within the single record.
No other operations are atomic; however, you can isolate a single write operation that affects multiple documents
using the isolation operator.
13
http://shtylman.com/post/the-tail-of-mongodb
62
This document describes one method of updating documents only if the local copy of the document reects the current
state of the document in the database. In addition the following methods provide a way to manage isolated sequences
of operations:
the findAndModify() provides an isolated update and return operation.
Perform Two Phase Commits (page 54)
Create a unique index, to ensure that a key doesnt exist when you insert it.
Update if Current
In this pattern, you will:
query for a document,
modify the elds in that document
and update the elds of a document only if the elds have not changed in the collection since the query.
Consider the following example in JavaScript which attempts to update the qty eld of a document in the products
collection:
Changed in version 2.6: The db.collection.update() method now returns a WriteResult() object that
contains the status of the operation. Previous versions required an extra db.getLastErrorObj() method call.
var myCollection = db.products;
var myDocument = myCollection.findOne( { sku: 'abc123' } );
if (myDocument) {
var oldQty = myDocument.qty;
if (myDocument.qty < 10) {
myDocument.qty
*
= 4;
} else if ( myDocument.qty < 20 ) {
myDocument.qty
*
= 3;
} else {
myDocument.qty
*
= 2;
}
var results = myCollection.update(
{
_id: myDocument._id,
qty: oldQty
},
{
$set: { qty: myDocument.qty }
}
);
if ( results.hasWriteError() ) {
print("unexpected error updating document: " + tojson( results ));
} else if ( results.nMatched == 0 ) {
print("No update: no matching document for { _id: " + myDocument._id + ", qty: " + oldQty + " }")
}
}
Your application may require some modications of this pattern, such as:
63
Use the entire document as the query in the update() operation, to generalize the operation and guarantee
that the original document was not modied, rather than ensuring that as single eld was not changed.
Add a version variable to the document that applications increment upon each update operation to the documents.
Use this version variable in the query expression. You must be able to ensure that all clients that connect to your
database obey this constraint.
Use $set in the update expression to modify only your elds and prevent overriding other elds.
Use one of the methods described in Create an Auto-Incrementing Sequence Field (page 64).
3.11 Create an Auto-Incrementing Sequence Field
Synopsis
MongoDB reserves the _id eld in the top level of all documents as a primary key. _id must be unique, and always
has an index with a unique constraint. However, except for the unique constraint you can use any value for the _id
eld in your collections. This tutorial describes two methods for creating an incrementing sequence number for the
_id eld using the following:
Use Counters Collection (page 64)
Optimistic Loop (page 66)
Considerations
Generally in MongoDB, you would not use an auto-increment pattern for the _id eld, or any eld, because it does
not scale for databases with large numbers of documents. Typically the default value ObjectId is more ideal for the
_id.
Procedures
Use Counters Collection
Counter Collection Implementation Use a separate counters collection to track the last number sequence used.
The _id eld contains the sequence name and the seq eld contains the last value of the sequence.
1. Insert into the counters collection, the initial value for the userid:
db.counters.insert(
{
_id: "userid",
seq: 0
}
)
2. Create a getNextSequence function that accepts a name of the sequence. The function uses the
findAndModify() method to atomically increment the seq value and return this new value:
function getNextSequence(name) {
var ret = db.counters.findAndModify(
{
query: { _id: name },
update: { $inc: { seq: 1 } },
new: true
}
64
);
return ret.seq;
}
3. Use this getNextSequence() function during insert().
db.users.insert(
{
_id: getNextSequence("userid"),
name: "Sarah C."
}
)
db.users.insert(
{
_id: getNextSequence("userid"),
name: "Bob D."
}
)
You can verify the results with find():
db.users.find()
The _id elds contain incrementing sequence values:
{
_id : 1,
name : "Sarah C."
}
{
_id : 2,
name : "Bob D."
}
findAndModify Behavior When findAndModify() includes the upsert: true option and the query
eld(s) is not uniquely indexed, the method could insert a document multiple times in certain circumstances. For
instance, if multiple clients each invoke the method with the same query condition and these methods complete the
nd phase before any of methods perform the modify phase, these methods could insert the same document.
In the counters collection example, the query eld is the _id eld, which always has a unique index. Consider
that the findAndModify() includes the upsert: true option, as in the following modied example:
function getNextSequence(name) {
var ret = db.counters.findAndModify(
{
query: { _id: name },
update: { $inc: { seq: 1 } },
new: true,
upsert: true
}
);
return ret.seq;
}
If multiple clients were to invoke the getNextSequence() method with the same name parameter, then the
methods would observe one of the following behaviors:
65
Exactly one findAndModify() would successfully insert a new document.
Zero or more findAndModify() methods would update the newly inserted document.
Zero or more findAndModify() methods would fail when they attempted to insert a duplicate.
If the method fails due to a unique index constraint violation, retry the method. Absent a delete of the document, the
retry should not fail.
Optimistic Loop
In this pattern, an Optimistic Loop calculates the incremented _id value and attempts to insert a document with the
calculated _id value. If the insert is successful, the loop ends. Otherwise, the loop will iterate through possible _id
values until the insert is successful.
1. Create a function named insertDocument that performs the insert if not present loop. The function wraps
the insert() method and takes a doc and a targetCollection arguments.
Changed in version 2.6: The db.collection.insert() method now returns a writeresults-insert object
that contains the status of the operation. Previous versions required an extra db.getLastErrorObj()
method call.
function insertDocument(doc, targetCollection) {
while (1) {
var cursor = targetCollection.find( {}, { _id: 1 } ).sort( { _id: -1 } ).limit(1);
var seq = cursor.hasNext() ? cursor.next()._id + 1 : 1;
doc._id = seq;
var results = targetCollection.insert(doc);
if( results.hasWriteError() ) {
if( results.writeError.code == 11000 /
*
dup key
*
/ )
continue;
else
print( "unexpected error inserting data: " + tojson( results ) );
}
break;
}
}
The while (1) loop performs the following actions:
Queries the targetCollection for the document with the maximum _id value.
Determines the next sequence value for _id by:
adding 1 to the returned _id value if the returned cursor points to a document.
otherwise: it sets the next sequence value to 1 if the returned cursor points to no document.
For the doc to insert, set its _id eld to the calculated sequence value seq.
Insert the doc into the targetCollection.
If the insert operation errors with duplicate key, repeat the loop. Otherwise, if the insert operation encoun-
ters some other error or if the operation succeeds, break out of the loop.
66
2. Use the insertDocument() function to perform an insert:
var myCollection = db.users2;
insertDocument(
{
name: "Grace H."
},
myCollection
);
insertDocument(
{
name: "Ted R."
},
myCollection
)
You can verify the results with find():
db.users2.find()
The _id elds contain incrementing sequence values:
{
_id: 1,
name: "Grace H."
}
{
_id : 2,
"name" : "Ted R."
}
The while loop may iterate many times in collections with larger insert volumes.
3.12 Limit Number of Elements in an Array after an Update
New in version 2.4.
Synopsis
Consider an application where users may submit many scores (e.g. for a test), but the application only needs to track
the top three test scores.
This pattern uses the $push operator with the $each, $sort, and $slice modiers to sort and maintain an array
of xed size.
Important: The array elements must be documents in order to use the $sort modier.
Pattern
Consider the following document in the collection students:
{
_id: 1,
scores: [
67
{ attempt: 1, score: 10 },
{ attempt: 2 , score:8 }
]
}
The following update uses the $push operator with:
the $each modier to append to the array 2 new elements,
the $sort modier to order the elements by ascending (1) score, and
the $slice modier to keep the last 3 elements of the ordered array.
db.students.update(
{ _id: 1 },
{ $push: { scores: { $each : [
{ attempt: 3, score: 7 },
{ attempt: 4, score: 4 }
],
$sort: { score: 1 },
$slice: -3
}
}
}
)
Note: When using the $sort modier on the array element, access the eld in the subdocument element directly
instead of using the dot notation on the array eld.
After the operation, the document contains only the top 3 scores in the scores array:
{
"_id" : 1,
"scores" : [
{ "attempt" : 3, "score" : 7 },
{ "attempt" : 2, "score" : 8 },
{ "attempt" : 1, "score" : 10 }
]
}
See also:
$push operator,
$each modier,
$sort modier, and
$slice modier.
68
4 MongoDB CRUD Reference
4.1 Query Cursor Methods
Name Description
cursor.count() Returns a count of the documents in a cursor.
cursor.explain() Reports on the query execution plan, including index use, for a cursor.
cursor.hint() Forces MongoDB to use a specic index for a query.
cursor.limit() Constrains the size of a cursors result set.
cursor.next() Returns the next document in a cursor.
cursor.skip() Returns a cursor that begins returning results only after passing or skipping a number of
documents.
cursor.sort() Returns results ordered according to a sort specication.
cursor.toArray() Returns an array that contains all documents returned by the cursor.
4.2 Query and Data Manipulation Collection Methods
Name Description
db.collection.count() Wraps count to return a count of the number of documents in a collection or
matching a query.
db.collection.distinct() Returns an array of documents that have distinct values for the specied eld.
db.collection.find() Performs a query on a collection and returns a cursor object.
db.collection.findOne()Performs a query and returns a single document.
db.collection.insert()Creates a new document in a collection.
db.collection.remove()Deletes documents from a collection.
db.collection.save() Provides a wrapper around an insert() and update() to insert new
documents.
db.collection.update()Modies a document in a collection.
4.3 MongoDB CRUD Reference Documentation
Write Concern Reference (page 69) Conguration options associated with the guarantee MongoDB provides when
reporting on the success of a write operation.
SQL to MongoDB Mapping Chart (page 71) An overview of common database operations showing both the Mon-
goDB operations and SQL statements.
The bios Example Collection (page 76) Sample data for experimenting with MongoDB. insert(), update()
and find() pages use the data for some of their examples.
Write Concern Reference
Write concern (page 23) describes the guarantee that MongoDB provides when reporting on the success of a write
operation.
Changed in version 2.6: A new protocol for write operations integrates write concerns with the write operations and
eliminates the need to call the getLastError command. Previous versions required a getLastError command
immediately after a write operation to specify the write concern.
69
Read Isolation Behavior
MongoDB allows clients to read documents inserted or modied before it commits these modications to disk, regard-
less of write concern level or journaling conguration. As a result, applications may observe two classes of behaviors:
For systems with multiple concurrent readers and writers, MongoDB will allow clients to read the results of a
write operation before the write operation returns.
If the mongod terminates before the journal commits, even if a write returns successfully, queries may have
read data that will not exist after the mongod restarts.
Other database systems refer to these isolation semantics as read uncommitted. For all inserts and updates, Mon-
goDB modies each document in isolation: clients never see documents in intermediate states. For multi-document
operations, MongoDB does not provide any multi-document transactions or isolation.
When mongod returns a successful journaled write concern, the data is fully committed to disk and will be available
after mongod restarts.
For replica sets, write operations are durable only after a write replicates and commits to the journal of a majority of
the members of the set. MongoDB regularly commits data to the journal regardless of journaled write concern: use
the commitIntervalMs to control how often a mongod commits the journal.
Available Write Concern
Write concern can include the w (page 70) option to specify the required number of acknowledgments before returning,
the j (page 71) option to require writes to the journal before returning, and wtimeout (page 71) option to specify a time
limit to prevent write operations from blocking indenitely.
In sharded clusters, mongos instances will pass the write concern on to the shard.
w Option The w option provides the ability to disable write concern entirely as well as specify the write concern for
replica sets.
MongoDB uses w: 1 as the default write concern. w: 1 provides basic receipt acknowledgment.
The w option accepts the following values:
70
Value Description
1 Provides acknowledgment of write operations on a standalone mongod or the primary in a
replica set.
This is the default write concern for MongoDB.
0 Disables basic acknowledgment of write operations, but returns information about socket
exceptions and networking errors to the application.
If you disable basic write operation acknowledgment but require journal commit
acknowledgment, the journal commit prevails, and the server will require that mongod
acknowledge the write operation.
<Number
greater than
1>
Guarantees that write operations have propagated successfully to the specied number of replica
set members including the primary.
For example, w: 2 indicates acknowledgements from the primary and at least one secondary.
If you set w to a number that is greater than the number of set members that hold data,
MongoDB waits for the non-existent members to become available, which means MongoDB
blocks indenitely.
"majority" Conrms that write operations have propagated to the majority of congured replica set: a
majority of the sets congured members must acknowledge the write operation before it
succeeds. This allows you to avoid hard coding assumptions about the size of your replica set
into your application.
Changed in version 2.6: In Master/Slave deployments, MongoDB treats w:
"majority" as equivalent to w: 1. In earlier versions of MongoDB, w: "majority"
produces an error in master/slave deployments.
<tag set> By specifying a tag set, you can have ne-grained control over which replica set members must
acknowledge a write operation to satisfy the required level of write concern.
j Option The j option conrms that the mongod instance has written the data to the on-disk journal. This ensures
that data is not lost if the mongod instance shuts down unexpectedly. Set to true to enable.
Changed in version 2.6: Specifying a write concern that includes j: true to a mongod or mongos running with
--nojournal option now errors. Previous versions would ignore the j: true.
Note: Requiring journaled write concern in a replica set only requires a journal commit of the write operation to the
primary of the set regardless of the level of replica acknowledged write concern.
wtimeout This option species a time limit, in milliseconds, for the write concern. wtimeout is only applicable
for w values greater than 1.
wtimeout causes write operations to return with an error after the specied limit, even if the required write concern
will eventually succeed. When these write operations return, MongoDB does not undo successful data modications
performed before the write concern exceeded the wtimeout time limit.
If you do not specify the wtimeout option and the level of write concern is unachievable, the write operation will
block indenitely. Specifying a wtimeout value of 0 is equivalent to a write concern without the wtimeout option.
See also:
Write Concern Introduction (page 23) and Write Concern for Replica Sets (page 25).
SQL to MongoDB Mapping Chart
In addition to the charts that follow, you might want to consider the http://docs.mongodb.org/manualfaq
section for a selection of common questions about MongoDB.
71
Terminology and Concepts
The following table presents the various SQL terminology and concepts and the corresponding MongoDB terminology
and concepts.
SQL Terms/Concepts MongoDB Terms/Concepts
database database
table collection
row document or BSON document
column eld
index index
table joins embedded documents and linking
primary key
Specify any unique column or column
combination as primary key.
primary key
In MongoDB, the primary key is automatically set to the _id eld.
aggregation (e.g. group by) aggregation pipeline
See the
http://docs.mongodb.org/manualreference/sql-aggregation-comparison.
Executables
The following table presents some database executables and the corresponding MongoDB executables. This table is
not meant to be exhaustive.
MongoDB MySQL Oracle Informix DB2
Database Server mongod mysqld oracle IDS DB2 Server
Database Client mongo mysql sqlplus DB-Access DB2 Client
Examples
The following table presents the various SQL statements and the corresponding MongoDB statements. The examples
in the table assume the following conditions:
The SQL examples assume a table named users.
The MongoDB examples assume a collection named users that contain documents of the following prototype:
{
_id: ObjectId("509a8fb2f3f4948bd2f983a0"),
user_id: "abc123",
age: 55,
status: 'A'
}
Create and Alter The following table presents the various SQL statements related to table-level actions and the
corresponding MongoDB statements.
72
SQL Schema Statements MongoDB Schema Statements
CREATE TABLE users (
id MEDIUMINT NOT NULL
AUTO_INCREMENT,
user_id Varchar(30),
age Number,
status char(1),
PRIMARY KEY (id)
)
Implicitly created on rst insert() operation. The
primary key _id is automatically added if _id eld is
not specied.
db.users.insert( {
user_id: "abc123",
age: 55,
status: "A"
} )
However, you can also explicitly create a collection:
db.createCollection("users")
ALTER TABLE users
ADD join_date DATETIME
Collections do not describe or enforce the structure of
its documents; i.e. there is no structural alteration at the
collection level.
However, at the document level, update() operations
can add elds to existing documents using the $set op-
erator.
db.users.update(
{ },
{ $set: { join_date: new Date() } },
{ multi: true }
)
ALTER TABLE users
DROP COLUMN join_date
Collections do not describe or enforce the structure of
its documents; i.e. there is no structural alteration at the
collection level.
However, at the document level, update() operations
can remove elds from documents using the $unset
operator.
db.users.update(
{ },
{ $unset: { join_date: "" } },
{ multi: true }
)
CREATE INDEX idx_user_id_asc
ON users(user_id)
db.users.ensureIndex( { user_id: 1 } )
CREATE INDEX
idx_user_id_asc_age_desc
ON users(user_id, age DESC)
db.users.ensureIndex( { user_id: 1, age: -1 } )
DROP TABLE users db.users.drop()
For more information, see db.collection.insert(), db.createCollection(),
db.collection.update(), $set, $unset, db.collection.ensureIndex(), indexes,
db.collection.drop(), and http://docs.mongodb.org/manualcore/data-models.
Insert The following table presents the various SQL statements related to inserting records into tables and the cor-
responding MongoDB statements.
73
SQL INSERT Statements MongoDB insert() Statements
INSERT INTO users(user_id,
age,
status)
VALUES ("bcd001",
45,
"A")
db.users.insert(
{ user_id: "bcd001", age: 45, status: "A" }
)
For more information, see db.collection.insert().
Select The following table presents the various SQL statements related to reading records from tables and the corre-
sponding MongoDB statements.
74
SQL SELECT Statements MongoDB nd() Statements
SELECT
*
FROM users
db.users.find()
SELECT id,
user_id,
status
FROM users
db.users.find(
{ },
{ user_id: 1, status: 1 }
)
SELECT user_id, status
FROM users
db.users.find(
{ },
{ user_id: 1, status: 1, _id: 0 }
)
SELECT
*
FROM users
WHERE status = "A"
db.users.find(
{ status: "A" }
)
SELECT user_id, status
FROM users
WHERE status = "A"
db.users.find(
{ status: "A" },
{ user_id: 1, status: 1, _id: 0 }
)
SELECT
*
FROM users
WHERE status != "A"
db.users.find(
{ status: { $ne: "A" } }
)
SELECT
*
FROM users
WHERE status = "A"
AND age = 50
db.users.find(
{ status: "A",
age: 50 }
)
SELECT
*
FROM users
WHERE status = "A"
OR age = 50
db.users.find(
{ $or: [ { status: "A" } ,
{ age: 50 } ] }
)
SELECT
*
FROM users
WHERE age > 25
db.users.find(
{ age: { $gt: 25 } }
)
SELECT
*
FROM users
WHERE age < 25
db.users.find(
{ age: { $lt: 25 } }
)
SELECT
*
FROM users
WHERE age > 25
AND age <= 50
db.users.find(
{ age: { $gt: 25, $lte: 50 } }
)
SELECT
*
FROM users
WHERE user_id like "%bc%"
db.users.find( { user_id: /bc/ } )
SELECT
*
FROM users
WHERE user_id like "bc%"
db.users.find( { user_id: /^bc/ } )
SELECT
*
FROM users
WHERE status = "A"
ORDER BY user_id ASC
db.users.find( { status: "A" } ).sort( { user_id: 1 } )
SELECT
*
FROM users
WHERE status = "A"
ORDER BY user_id DESC
db.users.find( { status: "A" } ).sort( { user_id: -1 } )
SELECT COUNT(
*
)
FROM users
db.users.count()
or
db.users.find().count()
SELECT COUNT(user_id)
FROM users
db.users.count( { user_id: { $exists: true } } )
or
db.users.find( { user_id: { $exists: true } } ).count()
SELECT COUNT(
*
)
FROM users
WHERE age > 30
db.users.count( { age: { $gt: 30 } } )
or
db.users.find( { age: { $gt: 30 } } ).count()
SELECT DISTINCT(status)
FROM users
db.users.distinct( "status" )
SELECT
*
FROM users
LIMIT 1
db.users.findOne()
or
db.users.find().limit(1)
SELECT
*
FROM users
LIMIT 5
SKIP 10
db.users.find().limit(5).skip(10)
EXPLAIN SELECT
*
FROM users
WHERE status = "A"
db.users.find( { status: "A" } ).explain()
75
For more information, see db.collection.find(), db.collection.distinct(),
db.collection.findOne(), $ne $and, $or, $gt, $lt, $exists, $lte, $regex, limit(), skip(),
explain(), sort(), and count().
Update Records The following table presents the various SQL statements related to updating existing records in
tables and the corresponding MongoDB statements.
SQL Update Statements MongoDB update() Statements
UPDATE users
SET status = "C"
WHERE age > 25
db.users.update(
{ age: { $gt: 25 } },
{ $set: { status: "C" } },
{ multi: true }
)
UPDATE users
SET age = age + 3
WHERE status = "A"
db.users.update(
{ status: "A" } ,
{ $inc: { age: 3 } },
{ multi: true }
)
For more information, see db.collection.update(), $set, $inc, and $gt.
Delete Records The following table presents the various SQL statements related to deleting records from tables and
the corresponding MongoDB statements.
SQL Delete Statements MongoDB remove() Statements
DELETE FROM users
WHERE status = "D"
db.users.remove( { status: "D" } )
DELETE FROM users db.users.remove({})
For more information, see db.collection.remove().
The bios Example Collection
The bios collection provides example data for experimenting with MongoDB. Many of this guides examples on
insert, update and read operations create or query data from the bios collection.
The following documents comprise the bios collection. In the examples, the data might be different, as the examples
themselves make changes to the data.
{
"_id" : 1,
"name" : {
"first" : "John",
"last" : "Backus"
},
"birth" : ISODate("1924-12-03T05:00:00Z"),
"death" : ISODate("2007-03-17T04:00:00Z"),
"contribs" : [
"Fortran",
76
"ALGOL",
"Backus-Naur Form",
"FP"
],
"awards" : [
{
"award" : "W.W. McDowell Award",
"year" : 1967,
"by" : "IEEE Computer Society"
},
{
"award" : "National Medal of Science",
"year" : 1975,
"by" : "National Science Foundation"
},
{
"award" : "Turing Award",
"year" : 1977,
"by" : "ACM"
},
{
"award" : "Draper Prize",
"year" : 1993,
"by" : "National Academy of Engineering"
}
]
}
{
"_id" : ObjectId("51df07b094c6acd67e492f41"),
"name" : {
"first" : "John",
"last" : "McCarthy"
},
"birth" : ISODate("1927-09-04T04:00:00Z"),
"death" : ISODate("2011-12-24T05:00:00Z"),
"contribs" : [
"Lisp",
"Artificial Intelligence",
"ALGOL"
],
"awards" : [
{
"award" : "Turing Award",
"year" : 1971,
"by" : "ACM"
},
{
"award" : "Kyoto Prize",
"year" : 1988,
"by" : "Inamori Foundation"
},
{
"award" : "National Medal of Science",
"year" : 1990,
"by" : "National Science Foundation"
}
]
77
}
{
"_id" : 3,
"name" : {
"first" : "Grace",
"last" : "Hopper"
},
"title" : "Rear Admiral",
"birth" : ISODate("1906-12-09T05:00:00Z"),
"death" : ISODate("1992-01-01T05:00:00Z"),
"contribs" : [
"UNIVAC",
"compiler",
"FLOW-MATIC",
"COBOL"
],
"awards" : [
{
"award" : "Computer Sciences Man of the Year",
"year" : 1969,
"by" : "Data Processing Management Association"
},
{
"award" : "Distinguished Fellow",
"year" : 1973,
"by" : " British Computer Society"
},
{
"award" : "W. W. McDowell Award",
"year" : 1976,
"by" : "IEEE Computer Society"
},
{
"award" : "National Medal of Technology",
"year" : 1991,
"by" : "United States"
}
]
}
{
"_id" : 4,
"name" : {
"first" : "Kristen",
"last" : "Nygaard"
},
"birth" : ISODate("1926-08-27T04:00:00Z"),
"death" : ISODate("2002-08-10T04:00:00Z"),
"contribs" : [
"OOP",
"Simula"
],
"awards" : [
{
"award" : "Rosing Prize",
"year" : 1999,
"by" : "Norwegian Data Association"
78
},
{
"award" : "Turing Award",
"year" : 2001,
"by" : "ACM"
},
{
"award" : "IEEE John von Neumann Medal",
"year" : 2001,
"by" : "IEEE"
}
]
}
{
"_id" : 5,
"name" : {
"first" : "Ole-Johan",
"last" : "Dahl"
},
"birth" : ISODate("1931-10-12T04:00:00Z"),
"death" : ISODate("2002-06-29T04:00:00Z"),
"contribs" : [
"OOP",
"Simula"
],
"awards" : [
{
"award" : "Rosing Prize",
"year" : 1999,
"by" : "Norwegian Data Association"
},
{
"award" : "Turing Award",
"year" : 2001,
"by" : "ACM"
},
{
"award" : "IEEE John von Neumann Medal",
"year" : 2001,
"by" : "IEEE"
}
]
}
{
"_id" : 6,
"name" : {
"first" : "Guido",
"last" : "van Rossum"
},
"birth" : ISODate("1956-01-31T05:00:00Z"),
"contribs" : [
"Python"
],
"awards" : [
{
"award" : "Award for the Advancement of Free Software",
79
"year" : 2001,
"by" : "Free Software Foundation"
},
{
"award" : "NLUUG Award",
"year" : 2003,
"by" : "NLUUG"
}
]
}
{
"_id" : ObjectId("51e062189c6ae665454e301d"),
"name" : {
"first" : "Dennis",
"last" : "Ritchie"
},
"birth" : ISODate("1941-09-09T04:00:00Z"),
"death" : ISODate("2011-10-12T04:00:00Z"),
"contribs" : [
"UNIX",
"C"
],
"awards" : [
{
"award" : "Turing Award",
"year" : 1983,
"by" : "ACM"
},
{
"award" : "National Medal of Technology",
"year" : 1998,
"by" : "United States"
},
{
"award" : "Japan Prize",
"year" : 2011,
"by" : "The Japan Prize Foundation"
}
]
}
{
"_id" : 8,
"name" : {
"first" : "Yukihiro",
"aka" : "Matz",
"last" : "Matsumoto"
},
"birth" : ISODate("1965-04-14T04:00:00Z"),
"contribs" : [
"Ruby"
],
"awards" : [
{
"award" : "Award for the Advancement of Free Software",
"year" : "2011",
"by" : "Free Software Foundation"
80
}
]
}
{
"_id" : 9,
"name" : {
"first" : "James",
"last" : "Gosling"
},
"birth" : ISODate("1955-05-19T04:00:00Z"),
"contribs" : [
"Java"
],
"awards" : [
{
"award" : "The Economist Innovation Award",
"year" : 2002,
"by" : "The Economist"
},
{
"award" : "Officer of the Order of Canada",
"year" : 2007,
"by" : "Canada"
}
]
}
{
"_id" : 10,
"name" : {
"first" : "Martin",
"last" : "Odersky"
},
"contribs" : [
"Scala"
]
}
81
Index
C
connection pooling
read operations, 15
crud
write operations, 19
Q
query optimizer, 13
R
read operation
architecture, 14
connection pooling, 15
read operations
query, 7
W
write concern, 23
write operations, 19
82

You might also like