我是MongoDB的新手,但我正在考虑解决这个问题:
我的应用程序有一个动态表单构建器,允许用户创建自定义调查,联系表单等。我想记录所有表单提交,并让创建表单的用户搜索并导出他们提交的数据。
我来自典型的PHP / mySql背景,并且看到将这些数据存储在mySql数据库中的一些挑战。每个表单可以包含任意数量的所有类型的字段。我要么需要将我的数据库规范化为EAV结构来存储数据,要么为每个表单动态创建一个新表,或者将表单数据序列化为TEXT列(ick)。
MongoDb的“无架构”(或“动态架构”)性质似乎是解决我问题的完美解决方案,但我的理由让我不知道从哪里开始。
再次重述我的问题:我需要以易于搜索和排序的方式存储变量和未知结构的数据。
谢谢!
答案 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"})