- Getting Started
- Quick Tour
MongoDB Driver Quick Tour
This is the first part of the MongoDB driver quick tour. In this part, we will look at how to perform basic CRUD (create, read, update, delete) operations. In the next part, we’ll look at performing some administrative functions.
Note
See the installation guide for instructions on how to install the MongoDB Driver.Make a connection
The following example shows three ways to connect to a server or servers on the local machine.
// To directly connect to a single MongoDB server
// (this will not auto-discover the primary even if it's a member of a replica set)
var client = new MongoClient();
// or use a connection string
var client = new MongoClient("mongodb://localhost:27017");
// or, to connect to a replica set, with auto-discovery of the primary, supply a seed list of members
var client = new MongoClient("mongodb://localhost:27017,localhost:27018,localhost:27019");
The client
instance now holds a pool of connections to the server or servers specified in the connection string.
MongoClient
The MongoClient
instance actually represents a pool of connections to the database; you will only need one instance of class MongoClient even with multiple threads.
important
Typically you only create one MongoClient
instance for a given cluster and use it across your application. Creating multiple MongoClients
will, however, still share the same pool of connections if and only if the connection strings are identical.
Get a Database
To get a database, specify the name of the database to the GetDatabase
method on client
. It’s ok if the database doesn’t yet exist. It will be created upon first use.
var database = client.GetDatabase("foo");
The database
variable now holds a reference to the “foo” database.
Get a Collection
To get a collection to operate upon, specify the name of the collection to the GetCollection<TDocument>
method on database
. It’s ok if the collection doesn’t yet exist. It will be created upon first use.
var collection = database.GetCollection<BsonDocument>("bar");
The collection
variable now holds a reference to the “bar” collection in the “foo” database.
Note
The generic parameter TDocument
represents the schema that exists in your collection. Above, we’ve used a BsonDocument
to indicate that we have no pre-defined schema. It is possible to use your plain-old-C#-objects (POCOs) as well. See the mapping documentation for more information.
Insert a Document
Once you have the collection
instance, you can insert documents into the collection. For example, consider the following JSON document; the document contains a field info which is an embedded document:
{
"name": "MongoDB",
"type": "database",
"count": 1,
"info": {
x: 203,
y: 102
}
}
To create the document using the .NET driver, use the BsonDocument
class. You can use this class to create the embedded document as well.
var document = new BsonDocument
{
{ "name", "MongoDB" },
{ "type", "Database" },
{ "count", 1 },
{ "info", new BsonDocument
{
{ "x", 203 },
{ "y", 102 }
}}
};
To insert the document into the collection, use the InsertOne
or InsertOneAsync
methods.
collection.InsertOne(document);
await collection.InsertOneAsync(document);
Note
The .NET driver is fully async capable. For more information on async and await, please see the MSDN documentation.
All APIs are available in both synchronous and asynchronous versions.
Insert Multiple Documents
To insert multiple documents, you can use the InsertMany
or InsertManyAsync
methods.
// generate 100 documents with a counter ranging from 0 - 99
var documents = Enumerable.Range(0, 100).Select(i => new BsonDocument("counter", i));
collection.InsertMany(documents);
await collection.InsertManyAsync(documents);
Counting Documents
Now that we’ve inserted 101 documents (the 100 we did in the loop, plus the first one), we can check to see if we have them all using the CountDocuments
or CountDocumentsAsync
methods. The following code should set the value of count to 101.
var count = collection.CountDocuments(new BsonDocument());
var count = await collection.CountDocumentsAsync(new BsonDocument());
Note
The empty BsonDocument
parameter to the CountDocumentsAsync
method is a filter. In this case, it is an empty filter indicating to count all the documents.
Query the Collection
Use the Find
method to query the collection. The Find
method returns an IFindFluent<TDocument, TProjection>
instance that provides a fluent interface for chaining find operation options.
Find the First Document in a Collection
To get the first document in the collection, call the FirstOrDefault
or FirstOrDefaultAsync
methods. FirstOrDefault
returns the first document or null. This is useful for queries that should only match a single document, or if you are interested in the first document only.
The following examples print the first document found in the collection.
var document = collection.Find(new BsonDocument()).FirstOrDefault();
Console.WriteLine(document.ToString());
var document = await collection.Find(new BsonDocument()).FirstOrDefaultAsync();
Console.WriteLine(document.ToString());
The example should print the following document:
{
"_id": ObjectId("551582c558c7b4fbacf16735"),
"name": "MongoDB",
"type": "database",
"count": 1,
"info": { "x" : 203, "y" : 102 }
}
Note
The “id” element has been added automatically by MongoDB to your document and your value will differ from that shown. MongoDB reserves field names that start with “” and “$” for internal use.Find All Documents in a Collection
To retrieve all the documents in the collection, call the ToList
or ToListAsync
methods. This is useful when the number of documents expected to be returned is small.
var documents = collection.Find(new BsonDocument()).ToList();
var documents = await collection.Find(new BsonDocument()).ToListAsync();
If the number of documents is expected to be large or they can be processed iteratively, the ForEachAsync
will invoke a callback for each document returned.
await collection.Find(new BsonDocument()).ForEachAsync(d => Console.WriteLine(d));
To iterate over the returned documents using the synchronous API use the C# foreach statement with the ToEnumerable
adapter method:
var cursor = collection.Find(new BsonDocument()).ToCursor();
foreach (var document in cursor.ToEnumerable())
{
Console.WriteLine(document);
}
Each of the above examples will print the exact same thing to the console. For more information on iteration, see the reference documention.
Get a Single Document with a Filter
We can create a filter to pass to the Find
method to get a subset of the documents in our collection. For example, if we wanted to find the document for which the value of the “i” field is 71, we would do the following:
var filter = Builders<BsonDocument>.Filter.Eq("i", 71);
var document = collection.Find(filter).First();
Console.WriteLine(document);
var document = await collection.Find(filter).FirstAsync();
Console.WriteLine(document);
and it should print just one document:
{ "_id" : ObjectId("5515836e58c7b4fbc756320b"), "i" : 71 }
Note
Use the Filter, Sort, and Projection builders for simple and concise ways of building up queries.Get a Set of Documents with a Filter
We can also get a set of documents from our collection. For example, if we wanted to get all documents where i > 50
, we could write:
var filter = Builders<BsonDocument>.Filter.Gt("i", 50);
var cursor = collection.Find(filter).ToCursor();
foreach (var document in cursor.ToEnumerable())
{
Console.WriteLine(document);
}
await collection.Find(filter).ForEachAsync(document => Console.WriteLine(document));
We could also get a range, say 50 < i <= 100
:
var filterBuilder = Builders<BsonDocument>.Filter;
var filter = filterBuilder.Gt("i", 50) & filterBuilder.Lte("i", 100);
var cursor = collection.Find(filter).ToCursor();
foreach (var document in cursor.ToEnumerable())
{
Console.WriteLine(document);
}
await collection.Find(filter).ForEachAsync(document => Console.WriteLine(document));
Sorting Documents
We add a sort to a find query by calling the Sort
method. Below we use the Exists
filter builder method and Descending
sort builder method to sort our documents:
var filter = Builders<BsonDocument>.Filter.Exists("i");
var sort = Builders<BsonDocument>.Sort.Descending("i");
var document = collection.Find(filter).Sort(sort).First();
var document = await collection.Find(filter).Sort(sort).FirstAsync();
Projecting Fields
Many times we don’t need all the data contained in a document. The Projection builder will help build the projection parameter for the find operation. Below we’ll exclude the “_id” field and output the first matching document:
var projection = Builders<BsonDocument>.Projection.Exclude("_id");
var document = collection.Find(new BsonDocument()).Project(projection).First();
Console.WriteLine(document.ToString());
var document = await collection.Find(new BsonDocument()).Project(projection).FirstAsync();
Console.WriteLine(document.ToString());
Updating Documents
There are numerous update operators supported by MongoDB.
To update at most 1 document (may be 0 if none match the filter), use the UpdateOne
or UpdateOneAsync
methods to specify the filter and the update document. Here we update the first document that meets the filter i == 10
and set the value of i
to 110
:
var filter = Builders<BsonDocument>.Filter.Eq("i", 10);
var update = Builders<BsonDocument>.Update.Set("i", 110);
collection.UpdateOne(filter, update);
await collection.UpdateOneAsync(filter, update);
To update all documents matching the filter use the UpdateMany
or UpdateManyAsync
methods. Here we increment the value of i
by 100
where i < 100
.
var filter = Builders<BsonDocument>.Filter.Lt("i", 100);
var update = Builders<BsonDocument>.Update.Inc("i", 100);
var result = collection.UpdateMany(filter, update);
if (result.IsModifiedCountAvailable)
{
Console.WriteLine(result.ModifiedCount);
}
var result = await collection.UpdateManyAsync(filter, update);
if (result.IsModifiedCountAvailable)
{
Console.WriteLine(result.ModifiedCount);
}
The update methods return an UpdateResult
which provides information about the operation including the number of documents modified by the update.
Note
Depending on the version of the server, certain features may not be available. In those cases, we’ve tried to surface the ability to check for their availability.Deleting Documents
To delete at most 1 document (may be 0 if none match the filter) use the DeleteOne
or DeleteOneAsync
methods:
var filter = Builders<BsonDocument>.Filter.Eq("i", 110);
collection.DeleteOne(filter);
await collection.DeleteOneAsync(filter);
To delete all documents matching the filter use the DeleteMany
or DeleteManyAsync
methods. Here we delete all documents where i >= 100
:
var filter = Builders<BsonDocument>.Filter.Gte("i", 100);
var result = collection.DeleteMany(filter);
Console.WriteLine(result.DeletedCount);
var result = await collection.DeleteManyAsync(filter);
Console.WriteLine(result.DeletedCount);
The delete methods return a DeleteResult
which provides information about the operation including the number of documents deleted.
Bulk Writes
There are two types of bulk operations:
Ordered bulk operations.
Executes all the operations in order and errors out on the first error.
Unordered bulk operations.
Executes all the operations and reports any errors. Unordered bulk operations do not guarantee the order of execution.
Let’s look at two simple examples using ordered and unordered operations:
var models = new WriteModel<BsonDocument>[]
{
new InsertOneModel<BsonDocument>(new BsonDocument("_id", 4)),
new InsertOneModel<BsonDocument>(new BsonDocument("_id", 5)),
new InsertOneModel<BsonDocument>(new BsonDocument("_id", 6)),
new UpdateOneModel<BsonDocument>(
new BsonDocument("_id", 1),
new BsonDocument("$set", new BsonDocument("x", 2))),
new DeleteOneModel<BsonDocument>(new BsonDocument("_id", 3)),
new ReplaceOneModel<BsonDocument>(
new BsonDocument("_id", 3),
new BsonDocument("_id", 3).Add("x", 4))
};
// 1. Ordered bulk operation - order of operation is guaranteed
collection.BulkWrite(models);
// 2. Unordered bulk operation - no guarantee of order of operation
collection.BulkWrite(models, new BulkWriteOptions { IsOrdered = false });
// 1. Ordered bulk operation - order of operation is guaranteed
await collection.BulkWriteAsync(models);
// 2. Unordered bulk operation - no guarantee of order of operation
await collection.BulkWriteAsync(models, new BulkWriteOptions { IsOrdered = false });