tob*_*sen 3 c# mongodb nosql mongodb-.net-driver
我目前正在试图弄清楚,Nosql数据库如何处理关系以及文档的唯一ID真正意味着什么.
也许我期待MongoDb过多,或者我还没有掌握NoSQL数据库中的关系概念.
基本上,以下测试失败,我想知道如何模拟用户和组之间的这种关系(这是1:0..N关系).
[TestFixture]
public class MongoDbExamples
{
private MongoServer _mongoServer;
[TestFixtureSetUp]
public void FixtureSetUp()
{
_mongoServer = MongoServer.Create();
}
[TestFixtureTearDown]
public void FixtureTearDown()
{
_mongoServer.Disconnect();
}
[Test]
public void RelationTest()
{
var database = _mongoServer.GetDatabase("StackoverflowExamples");
var p = new Person() { Name = "Testperson" };
var persons = database.GetCollection<Person>("Persons");
persons.Save<Person>(p);
var group = new Group() { Description = "A fancy descriptor" };
group.Add(p);
var groups = database.GetCollection<Group>("Groups");
groups.Save<Group>(group);
var readPerson = persons.FindOneById(p.Id);
readPerson.Name = "a different name";
// since the id hasn't change this is an update of the original person:
persons.Insert<Person>(readPerson);
// and I thought that it should be reflected in the group as well:
var readGroup = groups.FindOneById(group.Id);
Assert.AreEqual(readPerson.Id, readGroup.persons[0].Id); // this passes, the id is the same
Assert.AreEqual(readPerson.Name, readGroup.persons[0].Name); // this fails, the groups person still has the old name
}
}
Run Code Online (Sandbox Code Playgroud)
这种关系有最佳实践吗?例如,应该搜索所有馆藏/文件中的所有人,并与人员馆藏的匹配人交换那些人?或者是NoSQL数据库不擅长的关系,我应该避免关系(我想知道如何在更大的系统中使用NoSQL-DB然后使用更复杂的对象图)?
首先,mongodb没有任何关系和联系.所有'关系'都是合乎逻辑的,但它不像sql数据库那样真正的关系.在上面的测试中你存储了两次:第一个人进入人物收集,第二个我想进入组内的嵌套人员.
你只是重复的人.所以,他们没有关系.如果在人员收集中更新了人,那并不意味着他将在群组中的嵌套人员中进行神奇的更新.这就是您的测试失败的原因.
mongodb中通常的一对多关系非常适合嵌入.
更新: 我猜你有这样的文件:
public class Person
{
public Person()
{
Id = ObjectId.GenerateNewId().ToString();
}
[BsonId]
public string Id { get; set; }
public string Name { get; set; }
}
public class Group
{
public Group()
{
Id = ObjectId.GenerateNewId().ToString();
persons = new List<Person>();
}
[BsonId]
public string Id { get; set; }
public string Description { get; set; }
public List<Person> persons { get; set; }
public void Add(Person p)
{
persons.Add(p);
}
}
Run Code Online (Sandbox Code Playgroud)
我也很少修改你的测试以使其工作:
var database = _mongoServer.GetDatabase("StackoverflowExamples");
var p = new Person() { Name = "Testperson" };
var persons = database.GetCollection<Person>("Persons");
persons.Save<Person>(p);
var group = new Group() { Description = "A fancy descriptor" };
group.Add(p);
var groups = database.GetCollection<Group>("Groups");
groups.Save<Group>(group);
//Groups collection
//{
// "_id": "4da54d3c00a9ec06a0067456",
// "Description": "A fancy descriptor",
// "persons": [
// {
// "_id": "4da54d3b00a9ec06a0067455",
// "Name": "Testperson"
// }
// ]
//}
//Persons collection
//{
// "_id": "4da54d3b00a9ec06a0067455",
// "Name": "Testperson"
//}
var readPerson = persons.FindOneById(p.Id);
readPerson.Name = "a different name";
//Here i've changed Insert to Save
persons.Save(readPerson);
//Here you updating person in persons collection,
//but within group name still old
//Persons collection
//{
// "_id": "4da54d3b00a9ec06a0067455",
// "Name": "a different name"
//}
//So to achieve 'physical relation' you need also update person within group
var query = Query.EQ("persons._id", readPerson.Id);
groups.Update(query, Update.Set("persons.$.Name", readPerson.Name));
//Groups collection
//{
// "_id": "4da54d3c00a9ec06a0067456",
// "Description": "A fancy descriptor",
// "persons": [
// {
// "_id": "4da54d3b00a9ec06a0067455",
// "Name": "a different name"
// }
// ]
//}
//Test passed
var readGroup = groups.FindOneById(group.Id);
Assert.AreEqual(readPerson.Id, readGroup.persons[0].Id);
Assert.AreEqual(readPerson.Name, readGroup.persons[0].Name);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
641 次 |
| 最近记录: |