在CouchDB中使用JSON模式

时间:2014-12-19 09:50:29

标签: javascript json couchdb schema

我会问一下CouchDB中关于JSON原理图的好实践。我现在使用纯CouchDB 1.6.1。我没有任何couchapp框架处理它(我知道这很有用,但我担心它将来会有用)。

  • 在CouchDB中放置架构?作为常规文件?设计文件?或者可能将它们存储为文件?但是如果我要验证它们,尤其是validate_doc_update函数中的服务器端,它们应该存储在设计文档中。

  • CouchDB和Client(Web浏览器)中是否有任何库(JavaScript最好)?我可以用库生成JSON并自动验证它们吗?

  • 我考虑如何将数据发送到客户端,将它们存储在输入标签中,然后以某种方式收集并发送到服务器。也许将输入id设置为字段的路径,例如:

    {  " ADRESS" :{     "街道" :" xxx",     " N T个#34; :" 33"     } }

在这种情况下,输入可以有id =" Adress。" Street",但我不知道这是一个好的解决方案。我应该从服务器发送模式并使用这个模式构建JSON对象,但不知道如何(如果JSON中的所有字段都有唯一的名称 - 包括层次结构)。

3 个答案:

答案 0 :(得分:6)

在探索CouchDB在数据表单用例中的潜在优势时,您问了我多年来的同样问题。

最初,我希望找到一种方法,根据相同的JSON模式定义和验证代码(服务器端和客户端)启用数据验证。事实证明,这不仅是可能的,而且还存在一些额外的优势。

  

在CouchDB中放置架构?作为常规文件?设计文件?或者可能将它们存储为文件?但是如果我要验证它们,尤其是validate_doc_update函数中的服务器端,它们应该存储在设计文档中。

你是对的。设计doc(ddoc)还包括validate_doc_update函数,用于在doc更新之前执行验证,这是将schemata放入validate {doc_update函数中{.1}}的最常见位置是ddoc本身 - ddoc中包含的所有内容可以从验证码访问。

我已经开始将schemata作为JSON对象存储在我的通用库属性/文件夹中,用于commonjs模块,例如this。我的文档的lib/schemata.json属性指定了文档更新验证应获取的架构的关键字,例如type - > type: 'adr'。模式也可以引用每个属性的其他模式 - 无论嵌套属性是什么类型,递归验证函数都遍历到任何属性的末尾。它在第一个项目中运作良好。

lib/schemata/adr

但后来我想在另一个项目中使用该模式的子集。简单地复制它并添加/删除一些模式本来是太短视的想法。如果像地址这样的通用模式有错误并需要在每个使用它的项目中更新怎么办?

此时我的架构存储在存储库中的一个文件中(我使用erica作为ddocs的上传工具)。然后我意识到当我将每个模式存储在一个单独的文件中时,例如{ "person": { "name": "/type/name", "adr": "/type/adr", ... }, "name": { "forname": { "minlenght": 2, "maxlength": 42, ... }, "surname": { ... } }, "adr": { ... } } adr.jsongeo.json等。它使用单文件方法在服务器ddoc中产生与以前相同的JSON结构。但它更适合源代码管理。不仅较小的文件导致较少的合并冲突和更清晰的提交历史记录 - 还启用了通过子存储库(子模块)的模式依赖关系管理。

另一个想法是使用CouchDB本身作为模式存储和管理的地方。但正如您自己提到的那样 - 必须可以在validate_doc_update函数中访问模式。首先,我尝试了一种使用更新处理程序的方法 - 每个doc更新都必须传递一个验证更新处理程序,它自己从CouchDB中获取正确的模式:

tel.json

但是这种方法不适用于嵌套模式。更糟糕的是 - 为了防止文档更新而不通过处理程序进行验证,我必须在CouchDB前面使用代理来隐藏直接内置的doc更新路径(例如POST到/ / doc / _id)。我没有找到一种在validate_doc_update函数中检测更新处理程序是否涉及之前的方法(也许其他人有?我很乐意阅读这样的解决方案。)。

在调查期间,同一架构的不同版本的问题出现在我的雷达上。我应该如何管理?所有相同类型的文档必须对相同的模式版本有效(在几乎每个模式版本更改之前,还需要进行数据库范围的数据迁移)? type属性是否还包含版本号?等

但是等等!如果文档的架构附加到文档本身怎么办?它:

  • 将为文档内容每个文档
  • 提供兼容版本
  • 可在validate_doc_update函数(POST /_design/validator/_update/doctype/person function (schema, req) { ... //validate req.body against schema "person" return [req.body, {code: 202, headers: ...}] }
  • 中访问
  • 可以在没有管理员访问权限的情况下进行复制(正如您需要进行ddoc更新)
  • 将包含在客户端文档请求的每个响应中

这听起来非常有趣,直到现在我感觉像CouchDB-ish最接近的方法。要说得清楚 - 文档的架构附加到文档本身 - 表示将其存储在doc的属性中。作为附件的存储和作为doc结构的模式本身的使用都没有成功。

该方法最敏感的时刻是文档的CRUD生命周期中的 C (创建)。有许多不同的解决方案可以确保附加的模式是正确的和可接受的#34;。但这取决于您在特定项目中对该术语的定义。

  

CouchDB和Client(Web浏览器)中是否有任何库(JavaScript最好)?我可以用库生成JSON并自动验证它们吗?

我已经开始实施流行的JQuery Validation plugin。我可以使用架构作为配置,并自动获得整洁的客户端验证。在服务器端,我已将验证函数解压缩为commonjs模块。我希望以后能够找到一种模块化的代码管理方法来防止代码重复。

事实证明,大多数现有的验证框架在模式匹配和单一属性验证方面都非常出色,但却无法在同一文档中验证依赖值。模式定义要求通常也是专有的。对我来说,选择正确的模式定义的经验法则是:更喜欢自己实现的标准化定义(jsonschema.org,微数据,rdfa,hcard等)。如果您保留结构和属性名称,那么您将需要更少的文档,更少的转换,有时您也可以自动获得用户使用的外国软件(例如日历,地址簿等)的兼容性。如果您想为您的文档实现HTML演示文稿,那么您已准备好以语义Web-ish和SEO-zed方式进行。

最后 - 不希望听起来傲慢 - 编写模式验证实现并不困难。也许你想阅读JQuery Validation Plugin的源代码 - 我确定你发现像我一样令人惊讶的可理解。在前端框架的流失率增加的时候,它可能是拥有自己的验证功能的最具前瞻性的方式。此外,我相信您应该100%了解验证实现 - 它是您的应用程序的关键部分。如果您了解外部实现 - 您也可以自己编写库。

确定。这是一个很好的答案。抱歉。如果有人将其读到最后并希望通过示例源代码查看详细信息 - upvote,我将编写博客文章并将URI附加为评论。

答案 1 :(得分:5)

我会告诉你,我是如何实施它的。

  1. 每个文档类型都有一个数据库,这样我就可以为每个数据库实现一个模式。

  2. 在每个数据库上,我有一个_design/schema ddoc,其中包含一个架构和validate_doc_update函数来验证它。

  3. 我正在使用Tiny Validator (for v4 JSON Schema),我将其包含在_design/schema ddoc中。

  4. _design/schema ddoc看起来像这样:

    {
      "_id": "_design/schema",
      "libs": {
        "tv4": // Code from https://raw.githubusercontent.com/geraintluff/tv4/master/tv4.min.js
      },
      "validate_doc_update": "..."
      "schema": {
        "title": "Blog",
        "description": "A document containing a single blog post.",
        "type": "object",
        "required": ["title", "body"],
        "properties": {
          "_id": {
            "type": "string"
          },
          "_rev": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "body": {
            "type": "string"
          }
        }
      }
    }
    

    validate_doc_update函数如下所示:

    function(newDoc) {
      if (newDoc['_deleted']) return;
    
      var tv4 = require('libs/tv4');
    
      if (!tv4.validate(newDoc, this.schema)) {
        throw({forbidden: tv4.error.message + ' -> ' + tv4.error.dataPath});
      }
    }
    

    希望这有帮助。

答案 2 :(得分:0)

也许最好的选择是使用json-schema。您在a lot of languages中有实现。我已成功使用javascript中的tv4

为了与couch db集成,我认为最好的选择是定义validation function并使用json-schema javascript验证器。