Open	  source,	  high	  performance	  database	  What’s New in the C#/.NET Driver            Robert Stam      Software Eng...
•  The	  C#/.NET	  driver	         –  Is	  wriFen	  in	  C#	         –  Can	  be	  called	  from	  other	  .NET	  language...
•  Recent	  versions	      –  1.4	   	     	  Introduced	  support	  for	  LINQ	  queries	      –  1.4.1	        	  Added	...
•  Today’s	  topics:	      –  SerializaIon	  (POCOs)	      –  Handling	  schema	  evoluIon	      –  The	  new	  Query	  bu...
•  Documents	  are	  stored	  as	  BSON	  in	  the	  database	  •  When	  you	  read	  a	  document	  from	  the	  databas...
•  An	  in	  memory	  representaIon	  of	  a	  BSON	  document	  •  It’s	  not	  the	  original	  binary	  BSON,	  it’s	  ...
•  Very	  likely	  you	  will	  want	  to	  use	  your	  own	  domain	     classes	  instead	  of	  BsonDocument	  •  Seri...
•  The	  driver	  users	  serializers	  to	  convert	  POCOs	  to	  and	     from	  BSON	  documents	  •  A	  serializer	 ...
•  If	  your	  POCOs	  follow	  these	  rules	  they	  can	  be	     serialized	  automaIcally	  by	  the	  C#/.NET	  driv...
•  One	  way	  to	  configure	  automaIc	  serializaIon	  is	  by	     annotaIng	  your	  class	  with	  aFributes	  [BsonI...
•  If	  you	  want	  your	  domain	  classes	  to	  be	  independent	  of	     your	  persistence	  layer	  you	  can	  co...
•  Common	  changes	  to	  your	  schema	      –  You	  added	  a	  new	  property	      –  You	  removed	  an	  exisIng	 ...
•  ExisIng	  documents	  dont	  have	  a	  value	  for	  the	  new	     property,	  new	  documents	  automaIcally	  will	...
•  ExisIng	  documents	  sIll	  have	  an	  element	  for	  the	     property	  that	  you	  removed	  •  An	  excepIon	  ...
•  If	  you	  just	  want	  to	  rename	  the	  property	  in	  your	  code	     but	  keep	  the	  same	  element	  name	...
public class C : ISupportInitialize {    [BsonExtraElements]    public BsonDocument ExtraElements;    public   void BeginI...
•  If	  the	  C#	  type	  didnt	  change	  and	  the	  two	     representaIons	  are	  compaIble	  you	  dont	  need	  to	...
•  If	  the	  new	  type	  is	  compaIble	  with	  the	  old	  type	  (e.g.	     you	  changed	  from	  Int32	  to	  Int64...
•  What	  is	  a	  query?	       –  Anything	  that	  implements	  IMongoQuery	       –  IMongoQuery	  has	  an	  implied	...
•  Version	  1.5	  introduced	  a	  new	  query	  builder	  •  What	  was	  wrong	  with	  the	  old	  query	  builder?	  ...
•  Works	  at	  a	  slightly	  higher	  level	  (e.g.,	  requires	     Query.And	  instead	  of	  implied	  and)	  •  Much...
•  Yes!	  The	  old	  query	  builder	  will	  be	  removed	  in	  a	     future	  release	  •  For	  the	  Ime	  being,	 ...
•  There	  is	  a	  method	  in	  the	  untyped	  query	  builder	  for	     every	  query	  operator	  in	  the	  MongoDB...
•  You	  have	  to	  know	  the	  element	  name	      –  What	  if	  you	  use	  [BsonElement]	  to	  change	  the	  elem...
•  The	  typed	  builder	  has	  the	  same	  methods	  as	  the	     untyped	  builder	  but	  is	  type	  aware	  and	  ...
•  The	  typed	  query	  builder	  also	  lets	  you	  write	  the	     predicate	  in	  C#	  and	  it	  will	  be	  trans...
var query = Query.GTE("x", 1).LTE(3);// becomesvar query = Query.And(Query.GTE("x", 1), Query.LTE("x", 3));var query = Que...
•  LINQ	  is	  supported	  for	  queries	  only	  (although	     Query<T>.Where	  supports	  wriIng	  predicates	  in	  C#...
•  C#	  compiler	  creates	  an	  Expression	  tree	  •  C#/.NET	  driver	  translates	  the	  Expression	  tree	  to	  an...
•  The	  primary	  goal	  is:	  we	  will	  only	  support	  LINQ	     queries	  that	  have	  a	  reasonable	  translaIon...
var query = from e in collection.AsQueryable<Employee>()    where e.EmployeeStatus == Status.Active    select e;// transla...
var query = from e in collection.AsQueryable<Employee>()    where        e.EmployeeStatus == Status.Active &&        e.Sal...
var query = from e in collection.AsQueryable<Employee>()    where        e.EmployeeStatus == Status.Active ||        e.Sal...
var query = from e in collection.AsQueryable<Employee>()    where e.Name.Contains("oh")    select e;// translates to:{ nm:...
var query = from e in collection.AsQueryable<Employee>()    where e.Name.Length == 4    select e;// translates to:{ nm: /^...
var query = from e in collection.AsQueryable<Employee>()    where e.Name.ToLower() == "john macadam"    select e;// transl...
var query = from e in collection.AsQueryable<Employee>()    where e.Skills[0] == "Java"    select e;// translates to:{ "Sk...
var query = from e in collection.AsQueryable<Employee>()    where e.Address.City == "Hoboken"    select e;// translates to...
var states = new [] { "NJ", "NY", "PA" };var query = from e in collection.AsQueryable<Employee>()    where states.Contains...
var desiredSkills = new [] { "Java", "C#" };var query = from e in collection.AsQueryable<Employee>()    where e.Skills.Con...
var query = from e in collection.AsQueryable<Employee>()    where        e.Addresses.Any(a =>            a.City == "Hoboke...
•  You	  can	  "Inject"	  naIve	  MongoDB	  queries	  into	  a	  LINQ	     query	  if	  you	  need	  to	  include	  a	  te...
•  Turn	  on	  authenIcaIon	  using	  mongod	  -­‐-­‐auth	  •  AuthenIcaIon	  is	  at	  the	  database	  level	  •  Add	  ...
•  If	  you	  are	  using	  the	  same	  credenIals	  with	  all	     databases	  you	  can	  simply	  set	  the	  default...
•  If	  you	  are	  using	  different	  credenIals	  for	  each	     database	  you	  can	  use	  a	  credenIals	  store	  ...
•  You	  can	  also	  postpone	  providing	  the	  credenIals	  unIl	     you	  call	  GetDatabase	  var credentials = new...
•  To	  authenIcate	  using	  the	  admin	  database	  you	  have	  to	     flag	  the	  credenIals	  as	  being	  admin	  ...
•  You	  have	  to	  provide	  admin	  credenIals	  to	  run	  a	     command	  against	  the	  admin	  database	  var   a...
•  Some	  helper	  methods	  require	  admin	  credenIals	  var adminCredentials = new MongoCredentials("user", "pwd", tru...
Open	  source,	  high	  performance	  database	               Q&A         Robert Stam   Software Engineer, 10gen          ...
Upcoming SlideShare
Loading in …5
×

Webinar: What's new in the .NET Driver

1,562 views

Published on

Recent releases of the .NET driver have added lots of cool new features. In this webinar we will highlight some of the most important ones. We will begin by discussing serialization. We will describe how serialization is normally handled, and how you can customize the process when you need to, including some tips on migration strategies when your class definitions change. We will continue with a discussion of the new Query builder, which now includes support for typed queries. A major new feature of recent releases is support for LINQ queries. We will show you how the .NET driver supports LINQ and discuss what kinds of LINQ queries are supported. Finally, we will discuss what you need to do differently in your application when authentication is enabled at the server.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Webinar: What's new in the .NET Driver

  1. 1. Open  source,  high  performance  database  What’s New in the C#/.NET Driver Robert Stam Software Engineer, 10gen July  19,  2012   1
  2. 2. •  The  C#/.NET  driver   –  Is  wriFen  in  C#   –  Can  be  called  from  other  .NET  languages  •  Where  to  find  more  informaIon:   –  hFp://www.mongodb.org/display/DOCS/CSharp+Language+Center     2
  3. 3. •  Recent  versions   –  1.4      Introduced  support  for  LINQ  queries   –  1.4.1    Added  support  for  addiIonal  LINQ  queries   –  1.4.2    A  few  bug  fixes   –  1.5      SerializaIon  changes,  new  Query  builders  •  Upcoming  version   –  1.6      Support  for  new  server  2.2  features   3
  4. 4. •  Today’s  topics:   –  SerializaIon  (POCOs)   –  Handling  schema  evoluIon   –  The  new  Query  builders   –  LINQ  queries   –  AuthenIcaIon   4
  5. 5. •  Documents  are  stored  as  BSON  in  the  database  •  When  you  read  a  document  from  the  database  what   do  you  get  back  in  your  C#  program?  •  You  can  choose  to  get  back  either:   –  A  BsonDocument   –  A  plain  old  C#  object  (POCO)  that  you  defined  •  SerializaIon  is  the  process  by  which  a  POCO  instance   is  transformed  to  a  BSON  document  and  back   5
  6. 6. •  An  in  memory  representaIon  of  a  BSON  document  •  It’s  not  the  original  binary  BSON,  it’s  the  result  of   decoding  the  binary  BSON  •  Very  similar  to  a  DicIonary<string,  BsonValue>  •  Important  classes:   –  BsonValue  (abstract  base  class)   –  BsonInt32,  BsonInt64,  BsonString,  BsonDateTime,  …   –  BsonDocument,  BsonArray  •  More  informaIon:   hFp://www.mongodb.org/display/DOCS/CSharp+Driver +Tutorial#CSharpDriverTutorial-­‐BsonValueandsubclasses   6
  7. 7. •  Very  likely  you  will  want  to  use  your  own  domain   classes  instead  of  BsonDocument  •  SerializaIon  makes  that  possible  •  Sample  code:  var collection = database.GetCollection<Employee>("employees");var employee = collection.FindOne( Query<Employee>.EQ(e => e.EmployeeNumber, 1234));employee.Salary += 1000;collection.Save(employee); 7
  8. 8. •  The  driver  users  serializers  to  convert  POCOs  to  and   from  BSON  documents  •  A  serializer  is  a  class  that  implements  IBsonSerializer  •  A  serializer  is  registered  by  calling   BsonSerializer.RegisterSerializer  •  The  driver  provides  many  serializers  for   common  .NET  types  •  You  can  write  your  own  if  you  need  to  •  Class  map  based  serializaIon  works  automaIcally  for   your  POCOs  if  you  follow  a  few  simple  rules   8
  9. 9. •  If  your  POCOs  follow  these  rules  they  can  be   serialized  automaIcally  by  the  C#/.NET  driver:   –  Has  a  public  no-­‐argument  constructor   –  Has  a  public  get/set  property  for  each  value  that  you  want   to  have  serialized  •  In  most  cases  automaIc  class  map  based   serializaIon  requires  you  to  do:  NOTHING!  •  You  only  need  to  do  something  when  you  want  to   override  the  automaIc  serializaIon   9
  10. 10. •  One  way  to  configure  automaIc  serializaIon  is  by   annotaIng  your  class  with  aFributes  [BsonIgnoreExtraElements]public class Employee { [BsonId] public ObjectId EmployeeNumber { get; set; } [BsonElement("nm")] public string Name { get; set; } [BsonDateTimeOptions(DateOnly = true)] public DateTime DateOfBirth { get; set; } [BsonRepresentation(BsonType.Int64)] public int Salary { get; set; }} 10
  11. 11. •  If  you  want  your  domain  classes  to  be  independent  of   your  persistence  layer  you  can  configure  serializaIon   in  code  instead  of  using  aFributes  BsonClassMap.RegisterClassMap<Employee>(cm => { cm.AutoMap(); cm.SetIgnoreExtraElements(true); cm.SetIdMember(cm.GetMemberMap(c => c.EmployeeNumber)); cm.GetMemberMap(c => c.Name).SetElementName("nm"); cm.GetMemberMap(c => c.DateOfBirth) .SetSerializationOptions( DateTimeSerializationOptions.DateOnlyInstance); cm.GetMemberMap(c => c.Salary) .SetRepresentation(BsonType.Int64);}); 11
  12. 12. •  Common  changes  to  your  schema   –  You  added  a  new  property   –  You  removed  an  exisIng  property   –  You  renamed  an  exisIng  property   –  You  changed  the  representaIon  of  an  exisIng  property   –  You  changed  the  type  of  an  exisIng  property  •  MigraIon  strategies   –  All  at  once  using  an  upgrade  script  (much  easier)   –  Incremental   12
  13. 13. •  ExisIng  documents  dont  have  a  value  for  the  new   property,  new  documents  automaIcally  will  •  When  you  deserialize  a  document  that  doesnt  have   that  element,  the  property  in  your  class  will  be  null   (or  zero)  •  You  can  provide  a  default  value  for  missing  elements   if  you  want   [BsonDefaultValue(Status.Active)] public Status EmployeeStatus { get; set; }// or cm.GetMemberMap(c => c.EmployeeStatus) .SetDefaultValue(Status.Active); 13
  14. 14. •  ExisIng  documents  sIll  have  an  element  for  the   property  that  you  removed  •  An  excepIon  will  be  thrown  when  a  document   containing  the  removed  property  is  deserialized   because  we  dont  know  what  to  do  with  the   unexpected  element  •  You  could  handle  this  in  two  ways   –  Ignore  the  extra  element   –  Add  an  ExtraElements  property  to  your  class   14
  15. 15. •  If  you  just  want  to  rename  the  property  in  your  code   but  keep  the  same  element  name  in  the  database   use  the  [BsonElement]  aFribute  or  the   SetElementName  method  •  If  you  use  a  migraIon  script  to  update  the  enIre   collecIon  at  once  simply  change  the  name  of  the   element  in  the  database  •  Otherwise,  consider  wriIng  a  custom  serializer  or   perhaps  just  implemenIng  ISupportIniIalize   15
  16. 16. public class C : ISupportInitialize { [BsonExtraElements] public BsonDocument ExtraElements; public void BeginInit() { } public void EndInit() { // check ExtraElements for elements with old names // and load them into the appropriate property // also clear them out of ExtraElements so they wont // be saved back to the document again }} 16
  17. 17. •  If  the  C#  type  didnt  change  and  the  two   representaIons  are  compaIble  you  dont  need  to  do   anything.  Old  documents  can  sIll  be  read  and  new   documents  will  be  wriFen  with  the  new   representaIon  •  Otherwise,  you  will  either  have  to  write  a  custom   serializer  or  a  migraIon  script   17
  18. 18. •  If  the  new  type  is  compaIble  with  the  old  type  (e.g.   you  changed  from  Int32  to  Int64)  you  dont  need  to   do  anything  •  Otherwise,  you  will  have  to  write  a  migraIon  script   or  a  custom  serializer   18
  19. 19. •  What  is  a  query?   –  Anything  that  implements  IMongoQuery   –  IMongoQuery  has  an  implied  contract:  that  when  the   object  is  serialized  to  a  BSON  document  it  will  be  a  valid   MongoDB  query  •  Ways  to  create  query:   –  new  QueryDocument  {  …  }   –  new  QueryWrapper(object  query)   –  Use  the  untyped  query  builder   –  Use  the  typed  query  builder   19
  20. 20. •  Version  1.5  introduced  a  new  query  builder  •  What  was  wrong  with  the  old  query  builder?   –  It  exposed  too  many  of  the  idiosyncrasies  of  the  naIve   MongoDB  query  language  (implied  and,  unusual   restricIons  of  not,  etc…)   –  It  required  some  helper  classes  (QueryComplete,   QueryNot,  etc…)  that  were  intended  to  be  internal  but  yet   had  to  be  public  or  you  couldnt  write  a  query   –  The  query  language  rules  that  the  helper  classes  were   aFempIng  to  enforce  were  changing  from  version  to   version  of  the  server  but  the  driver  couldnt  adapt   gracefully  because  the  rules  were  encoded  in  source  code   20
  21. 21. •  Works  at  a  slightly  higher  level  (e.g.,  requires   Query.And  instead  of  implied  and)  •  Much  simpler  API  (and  no  helper  classes  that  leak   out  into  the  public  API)  •  Mostly  compaIble  with  the  old  query  builder   (specially  for  simple  queries)  •  Easier  to  maintain  from  version  to  version  of  the   server   21
  22. 22. •  Yes!  The  old  query  builder  will  be  removed  in  a   future  release  •  For  the  Ime  being,  you  can  conInue  using  the  old   query  builder  without  changing  your  source  code  by   adding  the  following  lines  to  the  top  of  your  source   file:  #pragma warning disable 618 // DeprecatedQuery is marked Obsoleteusing Query = MongoDB.Driver.Builder.DeprecatedQuery; 22
  23. 23. •  There  is  a  method  in  the  untyped  query  builder  for   every  query  operator  in  the  MongoDB  query   language  Query.EQ("_id", 1234)Query.EQ("nm", "John Doe")Query.NE("EmployeeStatus", 1) // assumes Status.Active == 1Query.GT("Salary", 100000)// are equivalent tonew QueryDocument("_id", 1234)new QueryDocument("nm", "John Doe")new QueryDocument("EmployeeStatus", new BsonDocument("$ne", 1))new QueryDocument("Salary", new BsonDocument("$gt", 100000)) 23
  24. 24. •  You  have  to  know  the  element  name   –  What  if  you  use  [BsonElement]  to  change  the  element   name?   –  What  if  you  mistype  the  element  name?  •  You  have  to  correctly  serialize  any  values  yourself   –  What  if  you  serialize  the  value  wrong?   –  What  if  you  dont  even  know  how  to  serialize  the  value?   24
  25. 25. •  The  typed  builder  has  the  same  methods  as  the   untyped  builder  but  is  type  aware  and  type  safe  Query<Employee>.EQ(d => d.EmployeeNumber, 1234)Query<Employee>.EQ(d => d.Name, "John Doe")Query<Employee>.NE(d => d.EmployeeStatus, Status.Active)Query<Employee>.GT(d => d.Salary, 100000)// also equivalent tonew QueryDocument("_id", 1234)new QueryDocument("nm", "John Doe")new QueryDocument("EmployeeStatus", new BsonDocument("$ne", 1))new QueryDocument("Salary", new BsonDocument("$gt", 100000)) 25
  26. 26. •  The  typed  query  builder  also  lets  you  write  the   predicate  in  C#  and  it  will  be  translated  to  an   equivalent  MongoDB  query  Query<Employee>.Where(d => d.EmployeeNumber == 1234)Query<Employee>.Where(d => d.Name == "John Doe")Query<Employee>.Where(d => d.EmployeeStatus != Status.Active)Query<Employee>.Where(d => d.Salary > 100000)// still equivalent tonew QueryDocument("_id", 1234)new QueryDocument("nm", "John Doe")new QueryDocument("EmployeeStatus", new BsonDocument("$ne", 1))new QueryDocument("Salary", new BsonDocument("$gt", 100000)) 26
  27. 27. var query = Query.GTE("x", 1).LTE(3);// becomesvar query = Query.And(Query.GTE("x", 1), Query.LTE("x", 3));var query = Query.Not("x").GT(1);// becomesvar query = Query.Not(Query.GT("x", 1));var query = Query.Exists("x", true);// becomesvar query = Query.Exists("x");var query = Query.Exists("x", false);// becomesvar query = Query.NotExists("x"); 27
  28. 28. •  LINQ  is  supported  for  queries  only  (although   Query<T>.Where  supports  wriIng  predicates  in  C#   that  can  be  used  with  Update)  •  You  opt-­‐in  to  LINQ  using  AsQueryable()  var collection = database.GetCollection<Employee>("employees");var query = from e in collection.AsQueryable() where e.Name == "John Doe" && e.Salary >= 100000 select e;foreach (var employee in query) { // process employee} 28
  29. 29. •  C#  compiler  creates  an  Expression  tree  •  C#/.NET  driver  translates  the  Expression  tree  to  an   equivalent  MongoDB  query  at  run  Ime  •  Requirements   –  For  each  C#  property  referenced  in  the  LINQ  query  the   driver  has  to  be  able  to  figure  out  the  matching  element   name  in  the  BSON  document  (using  doFed  names  for   nested  elements)   –  For  each  test  using  those  C#  properIes  the  driver  has  to   be  be  able  to  translate  the  test  into  an  equivalent   MongoDB  query  operator   29
  30. 30. •  The  primary  goal  is:  we  will  only  support  LINQ   queries  that  have  a  reasonable  translaIon  to  an   equivalent  MongoDB  query  •  The  reason:  we  want  to  ensure  predictable   performance  from  LINQ  queries  (no  black  magic,  no   surprises)  •  So,  you  will  not  find:   –  Any  hidden  map/reduce  or  Javascript  tricks   –  Any  hidden  client  side  processing  •  Online  LINQ  tutorial  at:   hFp://www.mongodb.org/display/DOCS/CSharp+Driver+LINQ+Tutorial   30
  31. 31. var query = from e in collection.AsQueryable<Employee>() where e.EmployeeStatus == Status.Active select e;// translates to (assuming enum value for Active is 1):{ EmployeeStatus : 1 }var query = from e in collection.AsQueryable<Employee>() where e.EmployeeStatus != Status.Active select e;// translates to:{ EmployeeStatus : { $ne : 1 } } 31
  32. 32. var query = from e in collection.AsQueryable<Employee>() where e.EmployeeStatus == Status.Active && e.Salary > 100000 select e;// translates to:{ EmployeeStatus : 1, Salary : { $gt : 100000 } } 32
  33. 33. var query = from e in collection.AsQueryable<Employee>() where e.EmployeeStatus == Status.Active || e.Salary > 100000 select e;// translates to:{ $or : [ { EmployeeStatus : 1 }, { Salary : { $gt : 100000 } }]} 33
  34. 34. var query = from e in collection.AsQueryable<Employee>() where e.Name.Contains("oh") select e;// translates to:{ nm: /oh/s }var query = from e in collection.AsQueryable<Employee>() where e.Name.StartsWith("John") select e;// translates to:{ nm: /^John/s } 34
  35. 35. var query = from e in collection.AsQueryable<Employee>() where e.Name.Length == 4 select e;// translates to:{ nm: /^.{4}$/s }var query = from e in collection.AsQueryable<Employee>() where string.IsNullOrEmpty(e.Name) select e;// translates to:{ $or : [ { nm: { $type : 10 } }, { nm: "" } ] } 35
  36. 36. var query = from e in collection.AsQueryable<Employee>() where e.Name.ToLower() == "john macadam" select e;// translates to:{ nm: /^john macadam$/is } 36
  37. 37. var query = from e in collection.AsQueryable<Employee>() where e.Skills[0] == "Java" select e;// translates to:{ "Skills.0" : "Java" }var query = from e in collection.AsQueryable<Employee>() where e.Skills.Length == 3 select e;// translates to:{ Skills : { $size : 3 } } 37
  38. 38. var query = from e in collection.AsQueryable<Employee>() where e.Address.City == "Hoboken" select e;// translates to:{ "Address.City" : "Hoboken" } 38
  39. 39. var states = new [] { "NJ", "NY", "PA" };var query = from e in collection.AsQueryable<Employee>() where states.Contains(e.Address.State) select e;// translates to:{ "Address.State" : { $in : [ "NJ", "NY", "PA" ] } }// alternative syntax using C#/.NET driver "In" methodvar query = from e in collection.AsQueryable<Employee>() where e.Address.State.In(states) select e; 39
  40. 40. var desiredSkills = new [] { "Java", "C#" };var query = from e in collection.AsQueryable<Employee>() where e.Skills.ContainsAny(desiredSkills) select e;// translates to:{ "Skills" : { $in : [ "Java", "C#" ] } }var query = from e in collection.AsQueryable<Employee>() where e.Skills.ContainsAll(desiredSkills) select e;// translates to:{ "Skills" : { $all : [ "Java", "C#" ] } }// note: ContainsAny and ContainsAll are defined by the C#/.NET driver and are not part of standard LINQ 40
  41. 41. var query = from e in collection.AsQueryable<Employee>() where e.Addresses.Any(a => a.City == "Hoboken" && a.State == "NJ") select e;// translates to:{ "Addresses" : { $elemMatch : { City : "Hoboken", State : "NJ" } } } 41
  42. 42. •  You  can  "Inject"  naIve  MongoDB  queries  into  a  LINQ   query  if  you  need  to  include  a  test  that  LINQ  doesnt   support,  without  giving  up  LINQ  enIrely  var query = from e in collection.AsQueryable() where e.Salary > 50000 && Query.NotExists("EmployeeStatus").Inject() select e;// translates to:{ Salary : { $gt : 50000 }, EmployeeStatus : { $exists : false }} 42
  43. 43. •  Turn  on  authenIcaIon  using  mongod  -­‐-­‐auth  •  AuthenIcaIon  is  at  the  database  level  •  Add  a  username/password  to  each  database  that   you  need  to  access  •  AuthenIcaIng  against  a  username/password  in  the   admin  database  is  like  root  access,  it  gives  you  access   to  all  databases   43
  44. 44. •  If  you  are  using  the  same  credenIals  with  all   databases  you  can  simply  set  the  default  credenIals    // on the connection stringvar connectionString = "mongodb://user:pwd@localhost/?safe=true";var server = MongoServer.Create(connectionString);// in codevar settings = new MongoServerSettings() { DefaultCredentials = new MongoCredentials("user", "pwd"), SafeMode = SafeMode.True};var server = MongoServer.Create(settings); 44
  45. 45. •  If  you  are  using  different  credenIals  for  each   database  you  can  use  a  credenIals  store  to  hold  all   the  credenIals  (in  code  only,  not  supported  on  the   connecIon  string)  var credentialsStore = new MongoCredentialsStore();credentialsStore.AddCredentials( "hr", new MongoCredentials("user1", "pwd1"));credentialsStore.AddCredentials( "inventory", new MongoCredentials("user2", "pwd2"));var settings = new MongoServerSettings { CredentialsStore = credentialsStore, SafeMode = SafeMode.True};var server = MongoServer.Create(settings); 45
  46. 46. •  You  can  also  postpone  providing  the  credenIals  unIl   you  call  GetDatabase  var credentials = new MongoCredentials("user", "pwd");var database = server.GetDatabase("hr", credentials); 46
  47. 47. •  To  authenIcate  using  the  admin  database  you  have  to   flag  the  credenIals  as  being  admin  credenIals  •  You  can  either  add  "(admin)"  to  the  end  of  the  user   name  or  set  the  Admin  flag  to  true  var cs = "mongodb://user(admin):pwd@localhost/?safe=true";var server = MongoServer.Create(cs);var adminCredentials = new MongoCredentials("user", "pwd", true);var settings = new MongoServerSettings { DefaultCredentials = adminCredentials, SafeMode = SafeMode.True};var server = MongoServer.Create(settings); 47
  48. 48. •  You  have  to  provide  admin  credenIals  to  run  a   command  against  the  admin  database  var adminCredentials = new MongoCredentials("user", "pwd", true);var adminDatabase = server.GetDatabase("admin", adminCredentials);var adminCommand = new CommandDocument { … }; // some admin commandvar result = adminDatabase.RunCommand(adminCommand); 48
  49. 49. •  Some  helper  methods  require  admin  credenIals  var adminCredentials = new MongoCredentials("user", "pwd", true);var result = database.RenameCollection( "from", "to", adminCredentials); 49
  50. 50. Open  source,  high  performance  database   Q&A Robert Stam Software Engineer, 10gen   50

×