C#을 사용하여 MongoDB 고유 키 만들기
나는 독특한 분야를 만들기 위해 싸우고 있습니다.EmailAddress
이미 포럼에서 인덱스를 만들어야 한다는 것을 보았지만, 지금까지 제게는 잘 되지 않았습니다.코드 예제를 가진 사람이 있습니까?인덱스를 저장/호출할 때마다 만들어야 합니까? 아니면 한 번만 생성하면 됩니까?
나는 이 코드를 시도했습니다.
DB.GetCollection<User>(Dbname)
.EnsureIndex(new IndexKeysBuilder()
.Ascending("EmailAddress"), IndexOptions.SetUnique(true));
DB.GetCollection<User>(Dbname).Save(user, SafeMode.True);
나의User
모델은 다음과 같습니다.
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; }
}
고유 색인은 한 번만 작성하면 됩니다. 그런 다음 중복된 전자 메일 주소를 포함하는 문서 삽입이 실패합니다.다음은 예입니다.
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 = "joe@example.com" };
var user2 = new User { EmailAddress = "joe@example.com" };
try
{
users.Save(user1, WriteConcern.Acknowledged);
users.Save(user2, WriteConcern.Acknowledged); // <-- throws MongoSafeModeException
}
catch (MongoSafeModeException ex)
{
Console.WriteLine(ex.Message);
}
C# mongo 드라이버 버전 2.0 사양에 따라 인덱스()가 더 이상 사용되지 않는지 확인합니다. http://api.mongodb.org/csharp/current/html/M_MongoDB_Driver_MongoCollection_EnsureIndex_2.htm
다음은 비동기 및 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);
문자열 인덱스가 아닌 경우:
var options = new CreateIndexOptions() { Unique = true };
IndexKeysDefinition<Foo> keyCode = "{ Code: 1 }";
var codeIndexModel = new CreateIndexModel<Foo>(keyCode, options);
아래 2.8 기준으로 인덱스를 생성하는 방법입니다.마지막 두 줄을 기록해 두십시오. CreateOneAsync(indexDefinition, options)
구식입니다.
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);
var indexModel = new CreateIndexModel<User>(indexDefinition,options);
await db.GetCollection<Users>("users").Indexes.CreateOneAsync(indexModel);
코드가 맞는 것 같습니다.다음은 전체 실행 중인 프로그램과 비교할 수 있는 방법입니다.
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 = "jsmith@xyz.com" };
users.Insert(john);
var joe = new User { FirstName = "Joe", LastName = "Smith", EmailAddress = "jsmith@xyz.com" };
users.Insert(joe); // should throw exception
}
}
}
또한 mongo 셸을 사용하여 인덱스가 생성되었는지 확인할 수 있습니다.
> 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
}
]
>
제 생각에 이것을 하는 더 좋고 실현 가능한 방법은 사용자 지정 특성을 만드는 것입니다. 그런 다음 c#을 사용하면 속성을 해당 특성으로 장식하고 고유한 인덱스를 추가할 수 있습니다. 이 접근 방식은 일반적이고 사용하기 매우 간단합니다.아래의 예:
내 사용자 지정 특성:Mongo Unique 문자열
public class DynamicFieldConfig
{
public string InputType { get; set; }
[MongoUniqueStringIndex]
public string Name { get; set; }
public string Label { get; set; }
public List<string> Options { get; set; } = new List<string>();
public string LookupTypeName { get; set; }
public int Type { get; set; } //int to enum
public string Value { get; set; }
public List<DynamicFieldValidation> Validations { get; set; } = new List<DynamicFieldValidation>();
}
그런 다음 데이터 액세스 클래스에서 다음 작업을 수행합니다.
public MongoDataAccess(IDatabaseSettings settings)
{
// todo: create a connection service/factory to get connection
var client = new MongoClient(settings.ConnectionString);
var database = client.GetDatabase(settings.DatabaseName);
var entityName = new Pluralizer().Pluralize(typeof(TMongoEntity).Name);
_entityStore = database.GetCollection<TMongoEntity>(entityName);
var uniqueStringIndexProperties = typeof(TMongoEntity).GetProperties().Where(
prop => Attribute.IsDefined(prop, typeof(MongoUniqueStringIndex))).ToList();
if (uniqueStringIndexProperties.Any())
foreach (var propertyInfo in uniqueStringIndexProperties)
{
var options = new CreateIndexOptions { Unique = true };
var propertyInfoName = propertyInfo.Name;
var field = new StringFieldDefinition<TMongoEntity>(propertyInfoName);
var indexDefinition = new IndexKeysDefinitionBuilder<TMongoEntity>().Ascending(field);
var indexModel = new CreateIndexModel<TMongoEntity>(indexDefinition, options);
_entityStore.Indexes.CreateOne(indexModel);
}
}
여기 MongoDB를 사용하는 작업 프로그램이 있습니다.엔티티(거부자:내가 저자야)
using System;
using MongoDB.Driver;
using MongoDB.Entities;
namespace StackOverflow
{
public class User : Entity
{
public string Name { get; set; }
public string EmailAddress { get; set; }
}
class Program
{
static void Main(string[] args)
{
new DB("test");
DB.Index<User>()
.Options(o => o.Unique = true, o => o.Background = false)
.Key(u => u.EmailAddress, Type.Ascending)
.Create();
var user1 = new User { Name = "First User", EmailAddress = "email@domain.com" };
user1.Save();
try
{
var user2 = new User { Name = "Second User", EmailAddress = "email@domain.com" };
user2.Save();
}
catch (MongoWriteException x)
{
Console.WriteLine(x.Message);
Console.ReadKey();
}
}
}
}
동일한 전자 메일 주소를 가진 두 번째 사용자를 생성하려고 하면 다음 예외가 발생합니다.
A write operation resulted in an error. E11000 duplicate key error collection: test.User index: EmailAddress(Asc) dup key: { : "email@domain.com" }
당신은 당신의 것을 포장해야 합니다.IndexKeysDefinition<TDocument>
의 상태가.CreateIndexModel<TDocument>
다음과 같은 옵션을 지정할 수 있습니다.Unique = true
예:
collection.Indexes.CreateOne(
new CreateIndexModel<DbModel>(
Builders<DbModel>.IndexKeys.Ascending(d => d.SomeField),
new CreateIndexOptions { Unique = true }
));
https://stackoverflow.com/a/55210026/2279059 도 참조하십시오.
한 가지 중요한 점에서 모든 답변이 누락된 것은 이미 인덱스가 있는 경우 인덱스를 생성하지 않는 것입니다.
var db = _mongoClient.GetDatabase("db");
var coll = db.GetCollection<Coll>("collName");
var indexes = (await (await coll.Indexes.ListAsync()).ToListAsync()).Select(_ => _.GetElement("name").Value.ToString()).ToList();
// If index not present create it else skip.
if (indexes.Where(_ => _.Equals("<Index Name>")).Count() == 0)
{
// Create Index here
}
사용 중<PackageReference Include="MongoDB.Driver" Version="2.11.5" />
고유 인덱스를 만들기 위한 내 코드입니다.
var client = new MongoClient(mongourl);
var database = client.GetDatabase(dbName);
IMongoCollection<CollectionModel> myCollection = database.GetCollection<CollectionModel>("collection_name");
myCollection .Indexes.CreateOne(
new CreateIndexModel<CollectionModel>(Builders<CollectionModel>.IndexKeys.Descending(model => model.YOUR_PROPERTY),
new CreateIndexOptions { Unique = true }));
언급URL : https://stackoverflow.com/questions/6218966/creating-mongodb-unique-key-with-c-sharp
'programing' 카테고리의 다른 글
데이터베이스의 보기를 업데이트할 수 있습니까? (0) | 2023.07.04 |
---|---|
"__block" 키워드는 무엇을 의미합니까? (0) | 2023.06.29 |
오라클 SQL 개발자에서 "읽기 호출에서 하나를 뺀 값"을 어떻게 해결할 수 있습니까? (0) | 2023.06.29 |
하나의 문에서 시퀀스에서 여러 NEXTVAL 쿼리 (0) | 2023.06.29 |
단일 글로벌 시퀀스와 테이블당 시퀀스 중 어느 것이 더 나은가요? (0) | 2023.06.29 |