10. Sample BsonDocument
// using functional construction
var book = new BsonDocument(
new BsonElement(“Author”, “Ernest Hemingway”),
new BsonElement(“Title”,
“For Whom the Bell Tolls”)
);
11. Sample BsonDocument (conUnued)
// using collection initializer syntax
var book = new BsonDocument {
{ “Author”, “Ernest Hemingway” },
{ “Title”, “For Whom the Bell Tolls” }
};
// compiler converts that to
var book = new BsonDocument();
book.Add(“Author”, “Ernest Hemingway”);
book.Add(“Title”, “For Whom the Bell Tolls”);
13. Accessing BSON Document Elements
BsonValue value = document[“name”];
string author = book[“Author”].AsString;
string author = (string) book[“Author”];
string author = (string) book[“Author”, null];
int year = book[“PublicationYear”].AsInt32;
bool outOfPrint = book[“OutOfPrint”].AsBoolean;
bool outOfPrint = book[“OutOfPrint”].ToBoolean();
BsonElement element = document.GetElement(“name”);
14. C# Driver Classes
• Main classes:
– MongoServer
– MongoDatabase
– MongoCollecUon
– MongoCursor
These top level classes are all thread safe.
(MongoCursor is thread safe once frozen).
15. MongoServer
var server = MongoServer.Create();
// or
var url = “mongodb://localhost:27017”;
var server = MongoServer.Create(url);
One instance is created for each URL.
Subsequent calls to Create with the same URL
return the same instance.
Not [Serializable], so don’t put in session state.
18. ConnecUon Modes
• Direct
– If mulUple host names are provided they are tried
in sequence unUl a match is found
• Replica set
– MulUple host names are treated as a seed list. All
hosts are contacted in parallel to find the current
primary. The seed list doesn’t have to include all
the members of the replica set. If the replica set
name was provided it will be verified.
19. slaveok
• If connect=direct
– If slaveok=true then it is OK if the server is not a
primary (useful to connect directly to secondaries
in a replica set)
• If connect=replicaset
– If slaveok=true then all writes are sent to the
primary and reads are distributed round‐robin to
the secondaries
20. ConnecUon Pools
• The driver maintains one connecUon pool for
each server it is connected to
• The connecUons are shared among all threads
• A connecUon is normally returned to the
connecUon pool as soon as possible (there is a
way for a thread to temporarily hold on to a
connecUon)
21. MongoDatabase
MongoDatabase test = server["test"];
// or
MongoCredentials credentials =
new MongoCredentials(username, password);
MongoDatabase test = server["test", credentials];
// or
MongoDatabase test = server[“test”, SafeMode.True];
One instance is created for each combinaUon of
name, credenUals and safemode. Subsequent calls
with the same values return the same instance.
22. MongoCollecUon
MongoCollection<BsonDocument> books = test["books"];
MongoCollection<BsonDocument> books =
test.GetCollection("books");
// or
MongoCollection<Book> books =
test.GetCollection<Book>("books");
Book is default document type
23. MongoCollecUon (conUnued)
var books = database[“books”, SafeMode.True];
var books = database.GetCollection<Book>(
“books”, SafeMode.True);
One instance is created for each combinaUon of
name, TDefaultDocument and safemode.
Subsequent calls with the same values return
the same instance.
24. Insert
var books = database[“books”];
var book = new BsonDocument {
{ “Author”, “Ernest Hemingway” },
{ “Title”, “For Whom the Bell Tolls” }
};
SafeModeResult result = books.Insert(book);
Returns a SafeModeResult (null if not using
safemode). Consider using InsertBatch if
inserUng mulUple documents.
25. Insert (using serializaUon)
// Book is a class with Author and Title properties
var books = database.GetCollection<Book>(“books”);
var book = new Book {
Author = “Ernest Hemingway”,
Title = “For Whom the Bell Tolls”
};
var result = books.Insert(book);
The book instance will be serialized to a BSON
document (see SerializaUon and
DefaultSerializer).
26. FindOne
var books = database[“books”];
var book = books.FindOne(); // returns BsonDocument
27. FindOne (using serializaUon)
var books = database[“books”];
var book = books.FindOneAs<Book>();
// returns Book instead of BsonDocument
or
var books = database.GetCollection<Book>(“books”);
var book = books.FindOne(); // returns Book
// because Book is default document type
28. Find (with query)
var query = new BsonDocument {
{ “Author”, “Ernest Hemingway” }
};
var cursor = books.Find(query);
foreach (var book in cursor) {
// process book
}
29. Find (with Query builder)
var query = Query.EQ(“Author”, “Ernest Hemingway”);
var cursor = books.Find(query);
foreach (var book in cursor) {
// process book
}
// a more complicated query
var query = Query.And(
Query.EQ(“Author”, “Ernest Hemingway”),
Query.GTE(“PublicationYear”, 1950)
);
30. Cursor opUons
• A cursor can be modified before being
enumerated (before it is frozen)
var query = Query.GTE(“PublicationYear”, 1950);
var cursor = books.Find(query);
cursor.Skip = 100;
cursor.Limit = 10;
foreach (var book in cursor) {
// process 10 books (first 100 skipped)
}
31. Cursor opUons (fluent interface)
var query = Query.GTE(“PublicationYear”, 1950);
var cursor = books.Find(query);
foreach (var book in
cursor.SetSkip(100).SetLimit(10)) {
// process 10 books (first 100 skipped)
}
// or even shorter
var query = Query.GTE(“PublicationYear”, 1950);
foreach (var book in
books.Find(query).SetSkip(100).SetLimit(10)) {
// process 10 books (first 100 skipped)
}
32. Update
var query = Query.EQ(“Title”, “For Who”);
var update = new BsonDocument {
{ “$set”, new BsonDocument {
{ “Title”, “For Whom the Bell Tolls” }
}}
};
SafeModeResult result = books.Update(query, update);
33. Update (using Update builder)
var query = Query.EQ(“Title”, “For Who”);
var update =
Update.Set(“Title”, “For Whom the Bell Tolls”);
SafeModeResult result = books.Update(query, update);
34. Save
• If it’s a new document calls Insert otherwise
calls Update
var query = Query.EQ(“Title”, “For Who”);
var book = books.FindOne(query);
book.Title = “For Whom the Bell Tolls”;
SafeModeResult result = book.Save();
How does Save know whether it’s a new
document or not? (It looks at the _id value).
35. Remove
var query = Query.EQ(“Author”, “Ernest Hemingway”);
SafeModeResult result = books.Remove(query);
// also
books.RemoveAll();
books.Drop();
36. RequestStart/RequestDone
• When a sequence of operaUons all need to occur
on the same connecUon wrap the operaUons with
calls to RequestStart/RequestDone
• RequestStart is per thread
• For the duraUon of the Request the thread holds
and uses a single connecUon, which is not returned
to the pool unUl RequestDone is called
• Calls to RequestStart can be nested. The request
ends when the nesUng level reaches zero again.
37. RequestStart (conUnued)
• RequestStart and the using statement
– Return value of RequestStart is a helper object that
implements IDisposable
– RequestDone is called for you automaUcally when
the using statement terminates
using (server.RequestStart(database)) {
// a series of related operations
}
38. RunCommand
• Wrapper methods are provided for many
commands, but you can always run them
yourself
var command =
new BsonDocument(“collstats”, “books”);
CommandResult result = database.RunCommand(command);
CommandResult result =
server.RunAdminCommand(“buildinfo”);
43. SerializaUon
• C# classes are mapped to BSON documents
• AutoMap:
– Public fields and properUes
• Lots of ways to customize serializaUon
– IBsonSerializable
– IBsonSerializer (call BsonSerializer.RegisterSerializer)
– Replace one or more default convenUons
– [Bson…] AQributes (like DataContract)
– BsonClassMap.RegisterClassMap
44. GridFS
• MongoDB’s Grid file system
var gridFS = database.GridFS;
var fileInfo = gridFS.Upload(“filename”);
gridFS.Download(“filename”);
// or
var fileInfo = gridFS.Upload(stream, “remotename”);
gridFS.Download(stream, “remotename”);
45. GridFS Streams
• Allow you to treat files stored in GridFS as if
they were local files
var gridFS = database.GridFS;
var stream = gridFS.Create(“remotename”);
// stream implements .NET’s Stream API
// more examples
var stream = gridFS.OpenRead(“remotename”);
var stream = gridFS.Open(“remotename”,
FileMode.Append);