MongoDB关系与词典

MongoDB关系与词典,mongodb,dictionary,model,Mongodb,Dictionary,Model,我在MongoDB中建模数据结构时遇到问题。以下是我的考虑: 假设我有一个父对象和一个子对象。父对象可以包含许多子对象。我可能有无限多的父对象(但让我们将其定义为数十万),一个父对象中最多可能有一千个子对象。问题是父对象的一个属性是基于子对象列表计算的。所以,当我将关系链接到child中的父级时,我必须在添加新的子级时更新父级,这在MongoDB中不支持作为原子操作(两个不同的文档)。当我将children列表嵌入到parent中时,我可能不需要将这个属性存储在parent中,因为它可以动态计算

我在MongoDB中建模数据结构时遇到问题。以下是我的考虑:

  • 假设我有一个父对象和一个子对象。父对象可以包含许多子对象。我可能有无限多的父对象(但让我们将其定义为数十万),一个父对象中最多可能有一千个子对象。问题是父对象的一个属性是基于子对象列表计算的。所以,当我将关系链接到child中的父级时,我必须在添加新的子级时更新父级,这在MongoDB中不支持作为原子操作(两个不同的文档)。当我将children列表嵌入到parent中时,我可能不需要将这个属性存储在parent中,因为它可以动态计算。此外,若我检索父列表,所有子项都将被下载,这对于只有父列表的页面来说并不完全好。另外,关于父对象的详细信息,我想对子对象进行分页,但它们总是会被下载的,对吗?这里哪种方法更好
  • MongoDB中的词典。假设我有一个属性,它是一个字典值,并且有一个文档保存这个字典。它可以看起来像[Object1:'A',Object2:'B',Object3:'C']。现在,若我要在文档中定义要链接到此属性的属性,我有一个问题,我如何才能连接此属性?如果从该字典中检索具有属性的对象,如何使字典值位于属性中而不是对象ID中?如果我要在其中插入值,那么我无法控制插入的值以及该值是否有效
  • “此外,如果我检索父列表,所有子项都将被下载,这对于只有父列表的页面并不完全好。”
  • 通过指定所需/不需要的
    字段
    ,可以非常轻松地解决该问题。也就是说,如果子文档中有子文档,请说
    子文档
    。那就在mongo贝壳里

    db.parent.find( {}, { children: 0 } )
    
    如果没有一把钥匙,那么你必须事先知道他们的钥匙是疯狂的,不可能的

    db.parent.find( {}, { child1: 0, child2, 0 ... child1000: 0 } )
    
    如果原子性很重要,那么这就解决了(仅?)这个问题

    不能轻易地对子对象进行分页。您将不得不执行一些笨拙且低效的专有数组切片代码,而用于子级的集合/表将允许使用
    skip
    limit
    进行非常简单的分页

    db.children.find({}).skip(5).limit(10)
    
    为了简单性和原子性,建议使用单个集合——但如果给定1000个子对象(正如您正确建议的那样,这确实需要分页),则使用第二个集合是有益的

  • 你在说什么,威利斯。 您的示例
    [object1:'A',object2:'B',object3:'C']
    是一个字典数组。这可能是一个常规的
    “对象”:{ObjectId1:'A',ObjectId2:'B',ObjectId3:'C'}
    然后使用dot.notation
    object.object1
    或者我肯定错过了什么

  • 如上所述,我认为这些问题过于宽泛,有太多可能的答案。您能在特定应用程序或用例的上下文中提出这些问题吗?我们有机会确定一种优于其他方法的方法。我可以从关系数据库世界来解释这一点,是我比较熟悉的。我们有一本活动字典:1游泳,2跑步,3骑自行车。我们有一个person表,其中包含activity列,其中的值为1,2,3。但对于用户,我希望显示活动名称,所以通常我会将其与活动表连接起来。我怎样才能在Mongo做到这一点。所以我可以嵌套子列表,这将消除原子性问题和下载问题,但我不会有正确的分页?是否可以提供我要检索的子表的索引?1。可以为子文档上的子文档编制索引。下面是一个很好的回答。但这并不能解决1000个孩子之间的分页问题。我知道你想要什么;就像谷歌每页只显示10个结果一样(相比之下,可能会返回200000个结果)。对于可用性来说,您的I/O速度太慢。分页是至关重要的。好啊您可以只包含{“activities”:“Running”}或者一对一的数组,{“activities”:[“Running”、“Riding”、“sweening”]}。这在快速、廉价的NoSQL世界中是可以接受的,因为它受到无连接的限制。此外,您还可以使用db.people.find(“活动”:“Running”})运行简单的查找,例如,它将为您提供所有正在运行的人员。或者更有效地使用分页db.people.find(“活动”:“Running”})。跳过(0)。限制(10)2。您会发现,在非关系世界中,您经常会复制数据。这使得req/resp时间很快,但对于查找表来说非常令人沮丧。例如,您改变了主意,“跑步”现在被称为“慢跑”,您将被迫更新所有人的跑步活动。因此,确保这些条款是最终的。当然,您可以使用1、2、3,并且只需在UI中使用这些字符串常量。由你决定。两者都很好。