【问题标题】:MongoDB: Can you include a collection as a field in a document of another collection?MongoDB:你可以将一个集合作为一个字段包含在另一个集合的文档中吗?
【发布时间】:2020-05-21 15:46:55
【问题描述】:

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

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

帐户
- 名称(字符串)
- 姓氏(字符串)
- 进展:
- stepName (String) , completed (boolean)
- stepName (String) , completed (boolean)
- stepName (String) , completed (boolean)
- ...

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

非常感谢提前

【问题讨论】:

    标签: javascript node.js mongodb express mongoose


    【解决方案1】:

    您可以 -- 因为您似乎在使用 Mongoose,您可以查看 https://mongoosejs.com/docs/subdocs.html 以获取有关如何执行您在此处概述的操作的一些信息。

    但是,根据我做类似事情的经验(通过流程跟踪进度),我建议进行一些不同的设置。我看到的最大问题是,如果您添加一个新步骤,您不希望必须遍历并更新每个 account 文档以将新步骤放入其 progress 字段。或者类似地,如果您决定删除一个步骤,您不希望必须转到每个帐户并从其进度字段中删除该步骤的条目。

    与其认为它在account 集合的每个文档中都包含progress 集合,不如将其视为具有一个包含有关每个步骤的任何可调整/可配置数据的step 集合。那里不需要有completed 字段,因为这是每个帐户特有的。根据您的需要,我建议如下:

    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
    

    现在,对于account,您需要一张地图 (https://mongoosejs.com/docs/schematypes.html#maps) 来显示进度(每个步骤的完成状态):

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

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

    还有一点需要注意——我建议您设置架构的方式,而不是为每个未完成的步骤设置明确的 false 值,大多数情况下您只是没有任何价值在地图中查看未完成的步骤。在您的代码中,您可以轻松地将任何缺少的步骤进度值视为错误(if (!account.progress.firstStep) { 默认使用 javascript)。如果需要,这还为您提供了选项,即仅在向用户呈现该步骤时将步骤的进度显式设置为 false。因此,您可以更轻松地了解他们停止的步骤(即使您稍后更改步骤的顺序)和/或他们是否跳过了任何步骤(如果某些步骤被认为是可选的),而不仅仅是能够看到哪个步骤已完成。

    【讨论】:

      【解决方案2】:

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

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

      {
         ...
         name: { first: "Alan", last: "Turing" },
         contact: { phone: { type: "cell", number: "111-222-3333" } },
         ...
      }
      

      在 mongodb 中,它是通过以下方式访问的:

      "<embedded document>.<field>"
      

      来源:https://docs.mongodb.com/manual/core/document/

      【讨论】:

        猜你喜欢
        • 2012-01-22
        • 2015-01-18
        • 1970-01-01
        • 2019-09-11
        • 1970-01-01
        • 2019-04-15
        • 1970-01-01
        • 2016-09-22
        • 2023-03-26
        相关资源
        最近更新 更多