Querying
CREATE
db.{collection}.insertOne()
db.{collection}.insertMany()
insertOne
Response:
The acknowledged: true
part means that the command was acknowledged by the
ReplicaSet. It does not mean that the command was successful. It depends on
the selected Write Concern.
insertMany
Response:
By default, all write operations are atomic on the level of a single document. When we write/modify multiple documents, we can make the whole operation atomic by using distributed transactions.
Insert operation will create a collection if it doesn’t exist yet.
We can provide a second parameter {"ordered": false}
to speed up the
insertMany
. This way, MongoDB does not have to insert documents in order and
can do it parallelly.
_id
Every document has an _id
field. If the provided document doesn’t have it,
MongoDB will add it by itself. It must be unique. By default, it’s of type
ObjectId (BSON), but we can set it ourselves as any type.
READ
db.{collection}.find()
db.{collection}.findOne()
These operations is used for queries. When invoked without parameters, it returns all the documents. The optional parameters are:
filter
projection
readConcern
(useful for Replica Set)
We can also skip
and limit
results. It’s useful for paging.
Some example:
Filter
The MongoDB documentation contains a list of all the supported operators.
Examples:
A full example: db.{collection}.find({name: 'Marcin'})
.
$expr
There is also a way to filter documents based on operations on various fields within a document. For example, we could return only those documents where the difference between the values of fields “totalSeats” and “registeredSeats” is greater than 5:
Arrays
There are operators to be used with arrays:
-
{$all: [...]}
- matches if an array contains all of the provided elements (order doesn’t matter) -
{$size: n}
- matches if an array containsn
elements -
$elemMatch
- multiple conditions to be matched for an array item. It is useful when the array item is an objectExample:
Special Cases
Here are some special cases for queries;
-
NULL values
To find only explicit NULLs, it’s better to use
{ $type: "null" }
-
documents where a field doesn’t exist
-
query by a specific BSON type
Projections
Projections are used to specify the fields to return from the source documents.
It’s a bit like a SELECT
in SQL.
Example:
As a result, 4 fields will be returned per document: “title”, “runtime”, “award.wins”, “_id” (if they exist in source documents).
We can also use projections to exlude just the specified fields:
Everything but “title” and “runtime” will be returned.
Arrays
Arrays have their own projection operators:
-
$slice
- limits the number of items of an array to be returnedThere is also another variant which allows to skip
m
elementes and returnn
elements ([m,n]
): -
$
- a bit similar to$slice
, but returns firstn
items that match the filter -
$elemMatch
- useful for object items in the array. It can further filter the documents with specified confitionsExample:
Read Concern
This parameter allows us to specify the level of consistency and isolation that are expected. We can either opt for higher consistency or higher availability. There is a way to specify a global read concern that will be used by default.
Levels:
- Local - The query returns data from the instance with no guarantee that the data has been written to a majority of the replica set members (i.e. may be rolled back). It’s the default.
- Available - Similar to “Local”, but it cannot be used with causally consistent sessions and transactions. For sharded clusters, it’s the fastest query.
- Majority - returns document that was accepted by the majority of replicas
- Linearizable - The query returns data that reflects all successful majority-acknowledged writes that completed prior to the start of the read operation. The query may wait for concurrently executing writes to propagate to a majority of replica set members before returning results. This query might take more time, it makes sense to specify a timeout.
- Snapshot - For use with multi-document projections.
Limit
Sort
We can provide an object with field names that should be sorted.
An example:
The title
field will be sorted in an ascending order, while the rating
field
will be sorted in a descending order.
An example:
We can sort by multiple fields. The order of the fields in the sort object matters.
Timeout
To specify a timeout we can add maxTimeMS
to our query. An example:
Agregations
We can get the count of documents satisfying the query by adding
.count()
at the end of the command.
We can get a count of all the documents in a collection with countDocuments()
.
Collation
There is a way to fine tune collation of the query, making sure that the proper language is used, casing, and many more.
UPDATE
Documents in the DB can be updated.
Write Concern
Similarly to Read Concern, we have Write Concern (the w
parameter). Levels:
- 0 - no acknowledgment is requested
- 1 - only acknowledgment from the Primary node is needed
- (n) - Primary + (n-1) Secondary nodes.
- “majority” - majority of nodes should acknowledge
We can also specify a timeout (wtimeout
) for write concern. It makes sense to
always specify it. A 0
value will be indefinite timeout.
Commands
The update commands are:
db.{collection}.updateOne()
- some fields are updateddb.{collection}.updateMany()
db.{collection}.replaceOne()
- the whole document is replaced
Examples:
We can specify the filter for a document to find, and the changes to be made:
Multiple documents can be updated as well:
A document can be completely replaced, meaning that unspecified fields will be
lost. As a result, only the _id
parameter stays the same, the only other
parameter is year
.
More Options
With the 3rd parameter we can specify some additional options for the update,
for example for it to be an “upsert”. If no documents are found to be updated, a
new document will be created with the specified fields. It works with
updateOne
and updateMany
.
An example:
If there were no movies with year
equal to “1994”, no documents will be
updated. However, a single new document will be addded with {year: 2222}
as
its content.
Additionally, for upsert, we can specify $setOnInsert
, which defines default
values for a documented in case it needs to be created.
Other options include:
w
for Write Concernwtimeout
for the timeout.arrayFilters
Operators
Update may use the following operators:
-
$set
- sets a value of a field -
$unset
- removes a field -
$inc
- increment the field’s valueIf the field doesn’t exist, the starting value is assumed to be 0. A negative value may be used as well.
-
$mul
- multiplies the field’s value
The MongoDB Docs contain the complete list of update operators.
Arrays
Arrays have their own update operators:
$pop
- removes a single value from an array either from the beginning or the end.$pull
- removes multiple elements, that meet some condition, from an array$push
- adds values to the array. There are modifiers that specify the position of elements, or multiple values to be added.
There’s also the arrayFilters
option that specifies elements that should be
updated in an array (e.g., with $inc
).
DELETE
The commands for deletion are:
db.{collection}.deleteOne()
db.{collection}.deleteMany()
db.{collection}.remove()
- pretty much the same as the two above, there is a special parameter to control whether just one or many document should be removed.
Indexes are not dropped implicitly. We need to remove them explicitly if we want that.
Similarly to UPDATE, DELETE supports Write Concerns.
Examples
Deleting a single document:
Deleting multiple documents: