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

发布于 2024-12-13 15:15:28 字数 547 浏览 2 评论 0原文

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

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

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

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

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

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

谢谢!

I am new to MongoDB, but am looking at it to solve this problem:

My application has a dynamic form builder that lets users create custom surveys, contact forms, etc. I want to log all of the form submissions and let the users who created the forms search through and export their submitted data.

I come from a typical PHP/mySql background, and see some challenges in storing this data in a mySql database. Each form could have any number of fields of all types. I would either need to normalize my DB to an EAV structure to store the data, or dynamically create a new table for each form, or serialize the form data into TEXT columns (ick).

The "schema-less" (or "dynamic schema") nature of MongoDb seems like the perfect solution to my problem, but my n00b-iness leaves me unsure where to start.

  1. Should the results of each custom form be stored as separate collections?
  2. Should I have a "forms" collection, and embed the results as sub-documents for each form?
  3. Is there another, better way?
  4. Is MongoDb actually a good solution for this, or am I way off base?

To restate my problem one more time: I need to store data of variable and unknown structures in an easily searchable and sortable way.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

独孤求败 2024-12-20 15:15:28

我不会将结果存储为 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: "[email protected]",
    //any other fields here
  }
}

的数组,例如:

{ ...
  values: [
    { name: "username", value: "dcrosta" },
    { name: "email", value: "[email protected]" }
  ]
}

如果您需要能够在提交的表单中按字段值对(或仅值)进行搜索,则可以使用 values字段 然后可以在 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"})

I wouldn't store results as embedded documents within the form document, since you may not know a priori how many submissions to expect. MongoDB limits each document to 16MB, but in practice you probably want to stay well below this threshold.

Since your forms are variable, but pre-determined (that is, each form may differ but the forms are defined ahead of time in some sort of admin UI), I'd recommend using two collections:

The first (call it forms) will store data about the makeup of each form: what fields, what types, in what order, etc. You could imagine documents in this collection would look something like this:

{ _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 },
    }
  ]
}

This lets you construct the forms dynamically (along with some server-side code) as needed for display in your application. It also gives information about what the fields are and what validation is required for them, which you can use during form submission. You'll want an index on URL or whatever field you use to determine which form to display when serving web requests.

The second collection, submissions or something, would store the submitted data for each form. Documents would look like:

{ _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: "[email protected]",
    //any other fields here
  }
}

If you need to be able to search by field-value pairs (or just values) in the submitted forms, a variation on this uses an array for the values field, like:

{ ...
  values: [
    { name: "username", value: "dcrosta" },
    { name: "email", value: "[email protected]" }
  ]
}

You can then create an index on the values field, and search like:

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

Or create an index on "values.value" and search like:

// find "dcrosta" as value to any field
db.submissions.find({"values.value": "dcrosta"})
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文