[英]What does uniqueness mean in the NoSQL world, how do I handle relations in MongoDB?
我目前正在試圖弄清楚,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);
沒有相關集合的關系或自動更新之類的東西。 好像你希望mongo表現得像ORM,但這不是它的作用,至少不是C#驅動程序。 如果要保存人員和組,則必須單獨保存。
您應該僅存儲人員ID,而不是將完整的人物對象存儲在組對象中。 然后使用這些ID在需要人員數據時查找此人。
另外,您可能想閱讀dbref上的文檔。
http://www.mongodb.org/display/DOCS/Database+References#DatabaseReferences-DBRef
Name上沒有唯一性,除非您在其上創建了唯一索引。 (參見http://www.mongodb.org/display/DOCS/Indexes#Indexes-UniqueIndexes )
您使用Insert而不是Update或Save,因此它將為您創建一個新文檔。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.