2011-06-02 24 views
22

Soy un n00b total con MongoDB y estoy luchando para crear un campo único EmailAddress. Ya he visto en foros que tengo que crear un índice, pero hasta ahora no me ha funcionado. ¿Alguien tiene un ejemplo de código? ¿Tengo que crear el índice en cada llamada/guardado, o es suficiente crearlo solo una vez?Creando la clave única de MongoDB con C#

yo probamos este código:

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

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

Mi modelo User se ve así:

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

cuales conductor estás usando? – atbebtg

Respuesta

8

Su código es correcto. Aquí hay un programa en ejecución completo para que usted pueda comparar en contra:

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 
     } 
    } 
} 

También puede utilizar la consola mongo para confirmar que el índice consiguió creado:

> 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

Está funcionando bien pero quiero dos o más campos para reducir duplicados. Sugiereme –

27

El índice único sólo necesita ser creado una vez, después de eso, cualquier inserción de documentos que contenga una dirección de correo electrónico duplicada fallará. He aquí un ejemplo:

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á en desuso/obsoletos por la versión de los conductores de C# mongo 2.0 especificaciones: http://api.mongodb.org/csharp/current/html/M_MongoDB_Driver_MongoCollection_EnsureIndex_2.htm

aquí está cómo hacerlo asíncrono y por medio de 2,0 código:

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); 
Cuestiones relacionadas