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

时间:2011-11-03 14:51:47

标签: mongodb schema

我是MongoDB的新手,但我正在考虑解决这个问题:

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

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

MongoDb的“无架构”(或“动态架构”)性质似乎是解决我问题的完美解决方案,但我的理由让我不知道从哪里开始。

  1. 每个自定义表单的结果是否应存储为单独的集合?
  2. 我是否应该拥有“表单”集合,并将结果作为每个表单的子文档嵌入?
  3. 还有另一种更好的方法吗?
  4. MongoDb实际上是一个很好的解决方案,还是我离开基地?
  5. 再次重述我的问题:我需要以易于搜索和排序的方式存储变量和未知结构的数据。

    谢谢!

1 个答案:

答案 0 :(得分:17)

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

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

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

{ _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"})