Javascript MongoDB:您可以将一个集合作为字段包含在另一个集合的文档中吗?

Javascript MongoDB:您可以将一个集合作为字段包含在另一个集合的文档中吗?,javascript,node.js,mongodb,express,mongoose,Javascript,Node.js,Mongodb,Express,Mongoose,我正在使用Javascript、Node.js、Express和MongoDB制作一个Web应用程序。在应用程序中,您可以使用字段name和lastnames创建帐户,但我还需要一个跟踪已完成步骤的字段(布尔值:如果未完成,则为false;如果已完成,则为true)。不可能将步骤硬编码为单独的布尔字段,因为我希望使步骤列表可调整。因此,我正在考虑制作另一个集合(=进度),其中包含所有步骤的名称,您可以在其中添加一些,并且知道我正在寻找一种方法,为我创建的每个帐户包含这些布尔步骤。 我认为Mong

我正在使用Javascript、Node.js、Express和MongoDB制作一个Web应用程序。在应用程序中,您可以使用字段name和lastnames创建帐户,但我还需要一个跟踪已完成步骤的字段(布尔值:如果未完成,则为false;如果已完成,则为true)。不可能将步骤硬编码为单独的布尔字段,因为我希望使步骤列表可调整。因此,我正在考虑制作另一个集合(=进度),其中包含所有步骤的名称,您可以在其中添加一些,并且知道我正在寻找一种方法,为我创建的每个帐户包含这些布尔步骤。

我认为MongoDB集合模式应该是什么样子的草图:

帐户
-名称(字符串)
-lastname(字符串)
-进度:
-步骤名称(字符串),已完成(布尔值)
-步骤名称(字符串),已完成(布尔值)
-步骤名称(字符串),已完成(布尔值)
-

进展
-步骤名称(字符串)
-已完成(布尔值)


非常感谢

您所描述的被称为“嵌入式文档”,并且由mongodb支持

Mongodb文档包括您想要的示例:

{
   ...
   name: { first: "Alan", last: "Turing" },
   contact: { phone: { type: "cell", number: "111-222-3333" } },
   ...
}
在mongodb中,可通过以下方式访问:

"<embedded document>.<field>"
来源:

你可以——因为看起来你在使用猫鼬,你可以查看一些关于如何做的信息,就像你在这里概述的那样

然而,根据我做类似事情的经验(通过流程跟踪进度),我建议将事情设置得稍有不同。我所看到的最大问题是,如果您添加了一个新步骤,您不希望必须检查并更新每个
帐户
文档才能将新步骤放入其
进度
字段。或者类似地,如果您决定删除一个步骤,您不需要转到每个帐户并从其进度字段中删除该步骤的条目

我不认为它在
账户
集合的每个文档中都包含
进度
集合,而是认为它有一个
步骤
集合,其中包含关于每个步骤的任何可调整/可配置数据。这里不需要填写
字段,因为这是每个帐户特有的内容。根据您的需要,我建议如下:

step
    - id (String) -- something that will never change
    - name (String) -- a user-facing name that you might want to change later
    - position (number) -- used to control the order of steps presented to the user
    - ... other things, depending on what you need/want
现在,对于
帐户
,您需要一个显示进度的映射()(每个步骤的完成状态):

这意味着,无论何时检查帐户的进度,您都需要循环查看
步骤
集合中的文档(根据
位置
字段排序),并根据每个步骤id检查该帐户的
进度
映射,以查看是否有未完成的文档。虽然这听起来像是额外的工作,但这种方法有很多优点。这意味着,如果您决定在
步骤
集合中添加、删除或重新排序某个步骤,则无需对每个现有的
帐户
文档进行相同的更改以进行匹配——您只需在下次检查帐户的
进度
字段时自动获取更改

还有一点需要注意——我建议您设置模式,而不是为每个未完成的步骤指定一个显式的
false
值,大多数情况下,对于未完成的步骤,映射中没有任何值。在代码中,您可以轻松地将任何缺少的步骤进度值视为false(
if(!account.progress.firstStep){
默认情况下可用于javascript)。如果您愿意,这还可以选择仅当向用户显示某个步骤时,才将该步骤的进度设置为显式的
false
。这样,您就可以更容易地了解他们停止的步骤(即使您稍后更改了步骤的顺序)和/或他们是否跳过了任何步骤(如果某些步骤被视为可选的话),而不仅仅是能够看到哪些步骤已经完成

account
  - name (String)
  - lastname (String)
  - progress: (Map of boolean)
      - key: step id
      - value: boolean showing whether it has been completed
  - ...