如何在 MongoDb 中存储动态生成的表单的结果?

Posted

技术标签:

【中文标题】如何在 MongoDb 中存储动态生成的表单的结果?【英文标题】:How to store results from dynamically generated forms in MongoDb? 【发布时间】:2011-12-21 06:27:28 【问题描述】:

我是 MongoDB 新手,但我正在研究它来解决这个问题:

我的应用程序有一个动态表单构建器,允许用户创建自定义调查、联系表单等。我想记录所有表单提交,并让创建表单的用户搜索并导出他们提交的数据。

我来自典型的 php/mysql 背景,并且看到了将这些数据存储在 mySql 数据库中的一些挑战。每个表单可以有任意数量的所有类型的字段。我需要将我的数据库规范化为 EAV 结构来存储数据,或者为每个表单动态创建一个新表,或者将表单数据序列化为 TEXT 列 (ick)。

MongoDb 的“无模式”(或“动态模式”)性质似乎是我问题的完美解决方案,但我的 n00b 特性让我不确定从哪里开始。

    是否应将每个自定义表单的结果存储为单独的集合? 我是否应该有一个“表单”集合,并将结果嵌入到每个表单的子文档中? 还有其他更好的方法吗? MongoDb 真的是一个很好的解决方案,还是我离谱?

再次重申我的问题:我需要以一种易于搜索和排序的方式存储可变和未知结构的数据。

谢谢!

【问题讨论】:

【参考方案1】:

我不会将结果作为嵌入文档存储在 form 文档中,因为您可能不知道先验预期有多少提交。 MongoDB 将每个文档限制为 16MB,但实际上您可能希望远低于此阈值。

由于您的表单是可变的,但是是预先确定的(也就是说,每个表单可能不同,但表单是在某种管理 UI 中提前定义的),我建议使用两个集合:

第一个(称为forms)将存储有关每个表单构成的数据:哪些字段、哪些类型、按什么顺序等。您可以想象这个集合中的文档看起来像这样:

 _id: ObjectId(...),
  name: "...",
  // other fields, for permissions, URL, etc
  fields: [
     name: "username",
      type: "text",
      validation:  required: true, min: 1, max: null ,
    ,
     name: "email",
      type: "text",
      validation:  required: true, min: 5, max: null, email: true ,
    
  ]

这使您可以根据需要动态构建表单(连同一些服务器端代码)以在应用程序中显示。它还提供有关字段是什么以及它们需要什么验证的信息,您可以在表单提交期间使用这些信息。您需要在 URL 或您使用的任何字段上建立索引,以确定在提供 Web 请求时要显示的表单。

第二个集合,submissions 之类的,将存储每个表单的提交数据。文件看起来像:

 _id: ObjectId(...),
  form: ObjectId(...), // the ObjectId of the record in "forms"
                       // that this is a submission on
  // other information here about the submitter:
  // IP address, browser, date and time, etc
  values: 
    username: "dcrosta",
    email: "dcrosta@awesomesite.com",
    //any other fields here
  

如果您需要能够在提交的表单中按字段-值对(或仅按值)进行搜索,则可以使用values 字段的数组,例如:

 ...
  values: [
     name: "username", value: "dcrosta" ,
     name: "email", value: "dcrosta@awesomesite.com" 
  ]

然后您可以在 values 字段上创建索引,然后搜索:

// find "dcrosta" as username
db.submissions.find(values: $elemMatch: name: "username", value: "dcrosta")

或在“values.value”上创建索引并搜索:

// find "dcrosta" as value to any field
db.submissions.find("values.value": "dcrosta")

【讨论】:

这种设计如何让您动态创建表单?看起来您已经在表单对象中对表单字段进行了硬编码,这不正是我们的目标吗,即用户应该能够构建他们想要的任何输入类型和输入数量的表单? @riley 的重点是,可以轻松地为管理员创建一个用户界面,他们可以通过该界面修改表单对象。 感谢您的回答。添加有关索引的信息也非常有价值。 ObjectId 代表每个自定义字段怎么样?这将允许稍后编辑表单字段名称并且不会影响提交。字段的 ID 为:forms.fields[x].id

以上是关于如何在 MongoDb 中存储动态生成的表单的结果?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Mongoose 在 mongodb 中存储动态对象数组?

如何在 MongoDB 中搜索动态字段并首先对最佳匹配结果进行排序

动态生成 GraphQL 模式支持

如何通过SpringBoot表单将html内容保存在mongodb中

如何创建“动态”表单 - 并在两个字段中存储数据和表单设计

vue中通过后台返回的只动态生成表单及提交