2011-06-02 11 views
22

Mam całkowitą n00b z MongoDB i walczę o stworzenie unikalnego pola EmailAddress. Widziałem już na forach, że muszę stworzyć indeks, ale jak na razie to nie zadziałało. Czy ktoś ma przykład kodu? Czy muszę utworzyć indeks dla każdego zapisu/wywołania, czy wystarczy go utworzyć tylko raz?Tworzenie unikalnego klucza MongoDB z C#

Próbowałem ten kod:

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

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

Moja User wzór wygląda tak:

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

który używasz sterownika? – atbebtg

Odpowiedz

8

Twój kod wygląda dobrze. Oto pełny program działa, aby porównać przeciw:

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

Można również użyć powłoki Mongo, aby potwierdzić, że indeks został stworzony:

> 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

Działa poprawnie, ale chcę dwa lub więcej pól, aby zmniejszyć duplikaty. Zaproponuj mnie –

27

Unikalny indeks musi jedynie być tworzone raz, potem wszystkie inserty dokumentów zawierające zduplikowany adres e-mail zawiedzie. Oto przykład:

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() jest przestarzała/przestarzałe per wersji C# kierowców Mongo 2,0 Spec: http://api.mongodb.org/csharp/current/html/M_MongoDB_Driver_MongoCollection_EnsureIndex_2.htm

herezje jak to zrobić asynchroniczny i poprzez kod 2.0:

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); 
Powiązane problemy