gpt4 book ai didi

c# - 唯一性在 NoSQL 世界中意味着什么,我如何处理 MongoDB 中的关系?

转载 作者:可可西里 更新时间:2023-11-01 09:19:03 25 4
gpt4 key购买 nike

我目前正在尝试弄清楚 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
}

}

这种关系是否有最佳实践?例如。是否应该在所有集合/文档中搜索所有人并将找到的人与人物集合的匹配人物交换?或者关系是 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);
}
}

我还稍微修改了您的测试以使其正常工作:

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

关于c# - 唯一性在 NoSQL 世界中意味着什么,我如何处理 MongoDB 中的关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5641709/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com