我正在试图弄清楚如何将文档链接/引用到另一个文档,但我在文档或其他来源中找不到太多信息或示例。链接文档时,我是否必须通过ObjectID进行链接,还是可以使用任何字段?我是否需要直接从原始文档中提取字段值,还是可以从任何地方传递相同的值?例如,给定一个UUID对象的十六进制字符串,我想通过包含uuid1对象的字段'GUID'链接2个文档:
# What is more efficience/the correct way, option 1 or 2?
# Option 1
hexString = '5d78ad35ea5f11e1a183705681b29c47'
newLinkField = { 'linkToSong' : uuid.UUID( hexString ) }
db.artists.update( { 'name' : 'Bob Dylan' }, { $set : newLinkField }, upsert = False)
# Option 2
hexString = '5d78ad35ea5f11e1a183705681b29c47'
songGUID = db.songs.find_one({ 'GUID' : uuid.UUID( hexString ) }, {'GUID': 1 });
newLinkField = { 'linkToSong' : songGUID }
db.artists.update( { 'name' : 'Bob Dylan' }, { $set : newLinkField }, upsert = False)
此外,这是存储实际链接还是只存储UUID对象的副本?
答案 0 :(得分:3)
我强烈推荐这个10gen视频来理解链接和嵌入,如何使用它们以及权衡取舍:
http://www.10gen.com/presentations/mongosv-2011/schema-design-principles-and-practice
回答你的问题:"链接"文档A到文档B只是意味着将一些信息放在A中,允许您的应用程序查询B.通常,它是这样的:
// Document A, in collection 'comments':
{ _id: ObjectId('123...'), user: ObjectId('abc...'), text: 'Hi!' }
// Document B, in collection 'users':
{ _id: ObjectId('abc...'), name: 'Jesse' }
文档A,我的评论,链接到我的用户个人资料B.您的应用程序可以查询A但是它想要(通过_id,按用户,按文本,...)然后检查其用户'字段,然后通过查询该ObjectId的用户集合来查找我的用户配置文件。
用于将A链接到B的字段在B&#39的集合中应该是唯一的,并且它肯定在B&C的集合中被索引。
任何集合的_id字段总是满足这两个要求,但是其他字段也可以满足它们。
你的例子1没问题。虽然你可能倒退了:歌曲中应该有艺术家ID,而不是反之亦然,除非Bob Dylan只写过一首歌。
在示例2中,如果您已经知道如何查询艺术家文档,则在艺术家之前找到该歌曲是不必要且成本高昂的。
答案 1 :(得分:-1)
Mongoengine可以在开箱即用的模型之间进行引用。但是,对于面向文档的数据库,这真的很糟糕。因为您可以在扩展DB时遇到问题并根据引用进行求解会降低noSQL dbs的性能。 您可以随意在一条记录中写下您需要的所有数据,例如,如果您需要为歌曲创建记录,您可以这样做:
{'title': 'Black and white', 'singer': 'M Jackson', 'album': 'Some album' and etc}
不要害怕数据开销,面向对象的DB主要是为这些东西设计的。