MongoDB中的子结构与扁平数据结构- NoSQL

3

我尝试理解如何最佳构建MongoDB的Schema,并因此寻求指导,尤其是在使用子结构(嵌入式文档)与平面数据结构方面。

假设我们想在MongoDB中存储一个用户帐户。用户只有一个地址,因此我们可以选择以下两种结构之一:

{ 
_id: String,
username: String,
firstname: String,
surname: String,
email: String,
street: String,
city String,
zip: Number,
}

或者

{
_id: String,
name: {
    first: String,
    last: String,
    }
email: String,
address: {
    street: String,
    city String,
    zip: Number,
    }
}

每种结构的优缺点是什么?在使用子结构还是使用平面结构时是否有规则?一个对另一个的理由是什么?
谢谢您提前!
1个回答

1
在MongoDB中提供了各种数据建模模式和模式设计。我将分享我的经验,包括我遇到的问题以及不同数据库模式的好处。我们将逐一讨论如下:
1. 嵌入式与扁平化数据结构:在这种情况下,两种模式之间没有太大区别,但是在嵌入式数据模型中,我们将类似的数据分组,这样可以使您的查询变得更加容易或者更小,当您从任何集合中$project数据时。
例如,如果您想要获取完整地址,则在嵌入式文档的情况下,您不需要单独$project地址字段,如果您想要跳过获取文档时的地址字段,则也不需要单独跳过地址字段。
2. 嵌入式(一对一)与嵌入式(一对多):正如我们讨论嵌入式文档对于扁平数据结构的好处一样,但是在某些情况下,如果我们的用户有多个地址,则需要使用具有一对多关系的嵌入式文档。
定义一对一和一对多关系的模式如下:
一对一关系模式:
{
_id: String,
name: {
    first: String,
    last: String,
    }
email: String,
address: {
    street: String,
    city String,
    zip: Number,
    }
}

一对多关系模式:
  {
    _id: String,
    name: {
        first: String,
        last: String,
        }
    email: String,
    address: [{           // Embedded address doc with one to many relationship
        street: String,
        city String,
        zip: Number,
      }]
  }

如果是一对一的关系,它不会太影响您的查询部分,但如果您使用一对多的关系,您的查询将有很多概念上的变化。

例如:由于我们主要在更新两种数据结构时面临不同的情况,因此我将分享更新查询之间的差异。

要更新嵌入了一对一关系的数据,您可以简单地使用点符号。

db.collection.update(
   { _id: 'anyId' },
   { $set: { "address.street": "abc" } }
)   

要更新具有一对多关系的数据,您需要使用$操作符。这里有两种不同的情况。首先,如果您想要更新子文档的特定元素,其次是如果您想要更新所有子文档:
情况1查询将是(使用$操作符):
  db.collection.update(
       { 'address.streent': 'abc' },
       { $set: { "address.$.street": "xyz" } }
  )   

案例2的查询将是(使用$[]):
  db.collection.update(
       { 'address.streent': 'abc' },
       { $set: { "address.$[]": "xyz" } }
  )  

非常感谢!嵌入式与扁平化的查询示例是一个关键考虑因素,很有意义! - Jason

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接