找到你要的答案

Q:When to use embedded documents MongoDB

Q:当使用嵌入式文件MongoDB

After reading the guide for using embedded documents in MongoDB I am still a bit confused as to what they are used for when modelling one-to-one relationships. For example if I had a user which had a username an email and an address which contained street, city, state and zip. Why would I model it like:

{
  username: "joe",
  email: "joe@example.com",
  address: {
    street: "123 example rd",
    city: "Faketon",
    state: "MA",
    zip: 1234
  }
}

when I could do something like this which would often save quite a bit of code when saving and loading from the database:

{
  username: "joe",
  email: "joe@example.com",
  street: "123 example rd",
  city: "Faketon",
  state: "MA",
  zip: 1234
}

Are there and what are the benefits to using embedded documents for one-to-one relationships? Does it give you any more flexibility or speed with queries? Are there any negative aspects of using embedded documents like this?

在阅读使用指南文件嵌入在MongoDB中我还是有点搞不清楚他们是用于建模时的一对一关系。例如,如果我有一个用户有一个用户名,电子邮件和地址,其中包含街道,城市,国家和邮编。为什么我会模仿它:

{
  username: "joe",
  email: "joe@example.com",
  address: {
    street: "123 example rd",
    city: "Faketon",
    state: "MA",
    zip: 1234
  }
}

当我可以做这样的事情,这往往会节省大量的代码时,从数据库中保存和加载:

{
  username: "joe",
  email: "joe@example.com",
  street: "123 example rd",
  city: "Faketon",
  state: "MA",
  zip: 1234
}

是否有使用嵌入式文件一对一的关系的好处是什么?它给你更多的灵活性或速度查询?使用这样的嵌入式文档有什么负面的方面吗?

answer1: 回答1:

There are several helpful side effects when using embedded documents vs flattening the structure for 1:1 relationships:

  • You can specify embedded document in query projections, which saves writing code to get sets of related fields and can help reduce network overhead if your application often works with subsets of the full document.

Using your first example document:

{
  username: "joe",
  email: "joe@example.com",
  address: {
    street: "123 example rd",
    city: "Faketon",
    state: "MA",
    zip: 1234
  }
}

You can easily get all of the address fields by projecting the subdocument:

> db.user.find({}, {address:1})
{
  "_id": ObjectId("554a0656f5549fd193161e2e"),
  "address": {
    "street": "123 example rd",
    "city": "Faketon",
    "state": "MA",
    "zip": 1234
  }
}
  • Embedded documents can provide additional semantic context.

Looking at your second example it may not be clear to another developer whether state is meant to be used as part of an address or if it might represent an application state (i.e. one arbitrary interpretation might be "MA" => "Management Approval"). The semantics can get harder to infer as are more fields are added to schema over time, or in cases where some of the fields may not be present in all documents.

Similarly, if you wanted to add home and office addresses both could have identical fields:

{
  "home": {
    "street": "123 example rd",
    "city": "Faketon",
    "state": "MA",
    "zip": 1234
  },
  "work": {
    "street": "456 Longcommuta Way",
    "city": "Busyville",
    "state": "CA",
    "zip": 90210
  }
}

You could take advantage of the similarity in subdocuments to have reusable code that works with either home or work addresses.

有几个有用的副作用,采用嵌入式文件与1:1的关系,扁平化结构:

  • You can specify embedded document in query projections, which saves writing code to get sets of related fields and can help reduce network overhead if your application often works with subsets of the full document.

使用您的第一个示例文档:

{
  username: "joe",
  email: "joe@example.com",
  address: {
    street: "123 example rd",
    city: "Faketon",
    state: "MA",
    zip: 1234
  }
}

你可以很容易地得到所有的地址字段的子文档:

> db.user.find({}, {address:1})
{
  "_id": ObjectId("554a0656f5549fd193161e2e"),
  "address": {
    "street": "123 example rd",
    "city": "Faketon",
    "state": "MA",
    "zip": 1234
  }
}
  • Embedded documents can provide additional semantic context.

看着你的第二个例子可能不清楚另一个开发者是否状态是用来作为地址的一部分,或者它可能代表一个应用程序状态(即一个任意的解释可能是“马”= & gt;“审批管理”)。的语义可以更难推断,随着更多的字段被添加到架构随着时间的推移,或在一些字段可能不存在的所有文件的情况下。

类似地,如果你想添加家庭地址和办公室地址,两者都可以有相同的字段:

{
  "home": {
    "street": "123 example rd",
    "city": "Faketon",
    "state": "MA",
    "zip": 1234
  },
  "work": {
    "street": "456 Longcommuta Way",
    "city": "Busyville",
    "state": "CA",
    "zip": 90210
  }
}

你可以利用在子文档的相似度有可重用的代码,与家庭或工作地址。

answer2: 回答2:

There won't be any performance difference. Both solutions are valid, but you should consider how you'll handle data with your programming language.

Example: with PHP or Java classes, you may want to create two classes, User and Address. Address will be embed in your User class/document. You may also want to reuse the Address class/document elsewhere.

You can see Mongo documents as PHP/Java classes.

There won't be any performance difference. Both solutions are valid, but you should consider how you'll handle data with your programming language.

例如:PHP或java类,你可以创建两类,用户地址。地址将嵌入在您的用户类/文档中。您还可以在其他地方重用地址类/文档。

你可以看到Mongo的文件作为PHP和java类。

json  mongodb