2011-06-02 6 views
22

Je suis un total de n00b avec MongoDB et je me bats pour créer un champ unique EmailAddress. J'ai déjà vu dans les forums que je devais créer un index, mais cela n'a pas fonctionné pour moi jusqu'ici. Quelqu'un at-il un exemple de code? Dois-je créer l'index à chaque sauvegarde/appel, ou est-ce suffisant pour le créer une seule fois?Création de MongoDB Unique Clé avec C#

J'ai essayé ce code: modèle

DB.GetCollection<User>(Dbname) 
    .EnsureIndex(new IndexKeysBuilder() 
     .Ascending("EmailAddress"), IndexOptions.SetUnique(true)); 

DB.GetCollection<User>(Dbname).Save(user, SafeMode.True); 

Mon User ressemble à ceci:

public class User 
{ 
    [Required(ErrorMessage = "Email Required")] 
    public string EmailAddress { get; set; } 

    public ObjectId Id { get; set; } 

    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 
+0

qui pilote utilisez-vous? – atbebtg

Répondre

8

Votre code semble bon. Voici un programme en cours d'exécution complet pour vous de comparer contre:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

using MongoDB.Bson; 
using MongoDB.Driver; 
using MongoDB.Driver.Builders; 

namespace TestEnsureIndexOnEmailAddress { 
    public class User { 
     public ObjectId Id; 
     public string FirstName; 
     public string LastName; 
     public string EmailAddress; 
    } 

    public static class Program { 
     public static void Main(string[] args) { 
      var server = MongoServer.Create("mongodb://localhost/?safe=true"); 
      var database = server["test"]; 
      var users = database.GetCollection<User>("users"); 
      if (users.Exists()) { users.Drop(); } 

      users.EnsureIndex(IndexKeys.Ascending("EmailAddress"), IndexOptions.SetUnique(true)); 
      var john = new User { FirstName = "John", LastName = "Smith", EmailAddress = "[email protected]" }; 
      users.Insert(john); 
      var joe = new User { FirstName = "Joe", LastName = "Smith", EmailAddress = "[email protected]" }; 
      users.Insert(joe); // should throw exception 
     } 
    } 
} 

Vous pouvez également utiliser le shell mongo pour confirmer que l'indice a été effectivement créé:

> db.users.getIndexes() 
[ 
     { 
       "name" : "_id_", 
       "ns" : "test.users", 
       "key" : { 
         "_id" : 1 
       }, 
       "v" : 0 
     }, 
     { 
       "_id" : ObjectId("4de8152ee447ad2550e3b5fd"), 
       "name" : "EmailAddress_1", 
       "ns" : "test.users", 
       "key" : { 
         "EmailAddress" : 1 
       }, 
       "unique" : true, 
       "v" : 0 
     } 
] 
> 
+0

Son fonctionnement bien, mais je veux deux champs ou plus pour réduire les doublons. Suggère moi –

27

L'index unique ne doit être créé une fois, après cela, tout document inséré contenant une adresse e-mail en double échouera. Voici un exemple:

var server = MongoServer.Create("mongodb://localhost"); 
var db = server.GetDatabase("myapp"); 

var users = db.GetCollection<User>("users"); 

users.EnsureIndex(new IndexKeysBuilder() 
    .Ascending("EmailAddress"), IndexOptions.SetUnique(true)); 

var user1 = new User { EmailAddress = "[email protected]" }; 
var user2 = new User { EmailAddress = "[email protected]" }; 

try 
{ 
    users.Save(user1, WriteConcern.Acknowledged); 
    users.Save(user2, WriteConcern.Acknowledged); // <-- throws MongoSafeModeException 
} 
catch (MongoSafeModeException ex) 
{ 
    Console.WriteLine(ex.Message); 
} 
14

ensureIndex() est dépréciée/obsolète par les pilotes mongo C# version 2.0 spec: http://api.mongodb.org/csharp/current/html/M_MongoDB_Driver_MongoCollection_EnsureIndex_2.htm

Heres comment le faire async et via 2.0 code:

var mongoClient = new MongoClient("connection"); 
var db = mongoClient.GetDatabase("database"); 

var options = new CreateIndexOptions() { Unique = true }; 
var field = new StringFieldDefinition<User>("EmailAddress"); 
var indexDefinition = new IndexKeysDefinitionBuilder<User>().Ascending(field); 
await db.GetCollection<Users>("users").Indexes.CreateOneAsync(indexDefinition, options);