2016 年 7 月

第 31 卷,第 7 期

此文章由机器翻译。

工作的程序员如何成为平均: 让我们成为 DEAN

通过 Ted Neward | 2016 年 7 月

Ted Neward欢迎回来再次重申,MEANers。或者,相反,对于这个月,"DEAN"用于。

使对话和体系结构在 MEAN 堆栈这样令人信服的事情之一是 MEAN 堆栈是本质上灵活 — 可以将替换为其他、 更多或不太等效部分堆栈的组件并创建一个新堆栈,而无需放弃体系结构的本质可满足企业/企业需要。这一概念的演示,在本专栏中我尝试使用 MongoDB 替换 Microsoft Azure DocumentDB (因此,"D"代替"M")。

MongoDB vs。DocumentDB

对于那些尚未花费多长时间熟悉 DocumentDB,我强烈建议查看现有的资源可用,包括 Julie Lerman 2015 年 6 月的数据点专栏中的某些 (msdn.com/magazine/mt147238)。Lerman 提供 DocumentDB,包括其最有趣的功能之一,执行服务器端代码 (如下所示在 JavaScript 中编写的存储过程是) 的绝佳概述。如果已经永远不会匆匆浏览了一下 DocumentDB 中,或需要进行了简要介绍,请在继续之前快速阅读。

表面上看,MongoDB 和 DocumentDB 是类似的生物。它们将 JSON 用作主体文档表示形式格式这两个面向文档的数据库。每个扩展以包含一些其他数据类型的 JSON。它们每考虑数据集合的文档,并将其用作 (而不是表) 的主体聚合方案。它们本质上"非关系",因为数据库不会执行任何验证用来将文档链接到另一个文档的文档标识符。就此而言,它们也同时"架构可用,"中的文档的内容将完全用手中的开发人员,而相同的文档结构不强制性的集合的所有元素。

因此,这应该是简单的交换。

但是,除了一些您会发现一些更深层次的差异,立即还有一个主要区别︰ 而 MongoDB 可以下载并关闭便携式计算机在本地运行,因此 DEAN 的第一步是在一个 Azure 帐户上创建的 DocumentDB 实例的简单的任务才可通过 Azure 订阅,DocumentDB。在详细信息 (包括 DocumentDB 文档中) 中的其他几个地方中将会介绍此对象,因此我将不会重复除要汇总的过程。转到 Azure 管理门户、 创建新的 Azure DocumentDb 资源、 为其提供唯一的名称 (我称地雷 dean db) 和打孔大蓝色的创建按钮。门户将在几分钟内改动,Azure 将在云中创建 DocumentDB 实例。

你已完成门户之前,有几个部分您将需要更高版本在代码中的信息。因此,让我们再来看现在将其记下。特别是,你将需要用于连接到的 URL 和以确保它是您的授权密钥。在 Azure 管理门户中,这称为为主键 (没有第二个调用的辅助密钥),并在撰写本文时,它将显示所有设置选项卡上的注册表项下,在。这些密钥是共享的机密信息,因此,请确保不要将它提供给任何人 — 特别是,如果代码进入公共源代码存储库 (la GitHub),请确保该密钥不是签入源代码的一部分。(按传统方法,Node.js 应用程序配置此为一个环境变量和使用应用程序入口点代码以选取它作为其启动的一部分; 所做的类似于此中以前的迭代的此基本代码,因此这也不奇怪。) 如果密钥已泄漏以任何方式 (作为在中,您发现该密钥以某种方式进行其缩小到公共),请确保重新生成密钥并将它们替换。实际上,它可能是个好办法循环它们只是在原则上每隔 30 天或 60 天。

这意味着,在现有基本代码 config.js 现在看起来像 图 1

图 1 中的现有基本代码 Config.js

module.exports = {
  mongoServer : "localhost",
  mongoPort : "27017",
  docdbServer : "https://dean-db.documents.azure.com:443/",
  docdbKey :
    "gzk030R7xC9629Cm1OAUirYg8n2sqLF3O0xtrVl8JT
      ANNM1zV1KLl4VEShJyB70jEtdmwnUUc4nRYyHhxsjQjQ=="
      };
if (process.env["ENV"] === "prod") {
  module.exports.mongoServer = "ds054308.mongolab.com";
  module.exports.mongoPort = "54308";
  module.exports.docdbServer = process.env["DOCDB_HOST"];
  module.exports.docdbKey = process.env["DOCDB_KEY"];
}

 (顺便说一下,我已经已经而需要循环访问密钥在我的存储库,以便显示此处的关键是只是为了显示,以便您了解它将如下所示。)

大家好,从 Node.js

下一步是可预测 — 您需要 Node.js 模块来访问 DocumentDB 实例,并且不要使用"npm install-保存 documentdb。" 当然,您将需要"require"它在 app.js 代码中,如下所示︰

var express = require('express'),
  bodyParser = require('body-parser'),
  debug = require('debug')('app'),
  edge = require('edge'),
  documentdb = require('documentdb'),
  ...;
// Go get our configuration settings
var config = require('./config.js');
debug("Mongo is available at ",config.mongoServer,":",config.mongoPort);
debug("DocDB is available at ",config.docdbServer);

从此处,打开的连接是只需构造 DocumentClient 对象使用服务器和授权密钥,如下所示︰

// Connect to DocumentDB
var docDB = documentdb.DocumentClient(config.docdbServer, {
  masterKey: config.docdbKey
});

现在,当然,更重要的问题是︰ 您做什么,它打开了?

使用 DocumentDB

如 MongoDB,DocumentDB 使用基于 JSON 的格式为架构和集合的文档,因此存储数据存在 (例如"演示文稿") 涉及同一类型的操作,如您所见通过 MongoDB 在过去。但是,该 API 是稍有不同,可能由于 Microsoft 喜欢如何设计事项并如何操作的排序不断发展外开源世界之间的一些文化差异。

(顺便说一下,我认为到目前为止的最佳 DocumentDB/Node.js 引用是一组 Azure 文档页面上的示例 [bit.ly/1TkqXaP]。它是指向存储在 GitHub,以及生成外 DocumentDB Node.js API 源代码中,文档的链接上的 Microsoft 授权示例项目的直接链接的集合和替代的任何内容更加正式,我一直在使用它作为我转到引用的 DocumentDB Api)。

对于初学者而言,一旦完成构造数据库客户端对象,您需要连接到有问题的数据库使用 databaseId;这是实际的数据库,在很大程度的 MongoDB 服务器可以承载多个数据库的方式相同。但是,与 MongoDB,不同的是使用 DocumentDB 此数据库必须创建提前。这可在任何一个以编程方式 (这是非常适合演示和 DevOps 方案) 通过 createDatabase API 调用,或通过 Azure 管理门户 (它可能会更常用的方法,考虑到这通常是一次性操作) 使用添加数据库选项卡下 DocumentDB 资源页。为简单起见,此处的代码假定 conferencedb 数据库已经存在,大概是先前创建在门户中。假定数据库存在,如果通过调用 queryDatabases,接下来在方法之间 MongoDB 和 DocumentDB,下一步最大区别中所示,Node.js 将可以连接到该 图 2

图 2 查询 DocumentDB 数据库的列表

docClient.queryDatabases({
  query: 'SELECT * FROM root r WHERE r.id = @id',
  parameters: [
    {
      name: '@id',
      value: 'conferencedb'
    }
  ]}).toArray(function (err, results) {
  if (err) {
    handleError(err);
  }
  if (results.length === 0) {
    // No error occured, but there were no results returned
    // indicating no database exists matching the query           
    // so, explictly return null
    debug("No results found");
  } else {
    // Found a database, so return it
    debug('Found a database:', results[0]);
    var docDB = results[0];
  }
});

首先,请注意如何 DocumentDB API 使用显式"查询规范中,"即使对于提取的数据库中完成,但参数的列表。这是从 Mongo 的"按示例查询"方法显著的差别。当然,您显然不一定要使用此 — 只是可以通过字符串串联的参数的内联填充 — 但那样将能够证实任何开发人员一直 SQL 注入式攻击的牺牲品,执行此类参数化的查询是很久更安全。

其他主要区别是当然的查询语言 — hello,SQL 中,我的老朋友。为了公平起见,它并不是 SQL 中,因为您不一定表、 列等,但 Microsoft 已极力不遗余力地熟悉查询语言通过适应面向文档的世界。无论这是"bug"或"功能"是可能取决于开发人员的喜爱或仇恨关系与关系数据库领域中,但这些 (以及其他) 通过决策,Microsoft 已将 DocumentDB 清楚地标记为 SQL Server 与 MongoDB 之间的折衷选择 (或其他文档数据库) 以及这不是会错误放置位置。

一旦找到的数据库,您需要再次获取该集合,由标识符。如数据库一样,集合是"正式"操作,这意味着他们需要或者显式创建使用 createCollection API 调用或通过 Azure 管理门户。给出如何 DocumentDB 认为的集合以表的形式,这并不令人惊讶。同样,最简单办法就是通过 (撰写本文时) 创建一个通过门户中,单击 DocumentDB 资源磁贴中的数据库磁贴中的数据库名称。此时会弹出一个新选项卡,您可以添加新的集合,演示文稿,然后通过该标识符,如在中找到它 图 3

图 3 发现的数据库吗? 现在找到集合

// We found a database
debug('Found a database:', results[0]);
docDB = results[0];
debug('Looking for collections:');
docClient.readCollections('dbs/conferencedb').
toArray(function(err, colls) {
if (err) {
  debug(err);
}
else {
  if (colls.length === 0) {
    debug("No collections found");
  }
  else {
    for (var c in colls) {
      debug("Found collection",colls[c]);
      if (colls[c].id === 'presentations')
        presentationColl = colls[c];
      }
    }
  }
});

请记下的第一个参数到 readCollections API 调用;如果它看上去像它指定某种类型的类似/URL 的 URI 路径有问题的数据库,,应该是这样。每次调用 Node.js DocumentDB API 使用这些种类的 REST-ish 标识符以方便地直接为集合 (和,从根本上讲,文档) 而无需复杂的层次结构中导航所需的钻取。

(与 MongoDB 截然不同的一个重要的注意事项︰ 对基于每个集合,其服务的 azure 费用因此 MongoDB 用户会认为的位置有关集合从纯建模的角度看,与 DocumentDB,决定创建新的集合将具有直接影响每月得到支付的费用。)

最后,若要查找该集合中的任何特定的文档,您可以使用 queryDocuments API。同样,传入集合标识符 (其中,因为您知道的集合后,您将可以只嵌入直接在代码中),并将结果以退回直接将其作为 JSON 正文中,就像我所做少量的列返回 MongoDB,如中所示 图 4

图 4 列表集合中的所有文档

var getAllPresentations = function(req, res) {
  debug("Getting all presentations from DocumentDB:");
  docClient.queryDocuments("dbs/conferencedb/colls/presentations",
  {
    query: "SELECT * FROM presentations p"
  }).toArray(function (err, results) {
    if (err) res.status(500).jsonp(err);
    else res.status(200).jsonp(results);
  });
};
// ...
app.get('/presentations', getAllPresentations);

正常情况下,如果您想要限制对演讲者的演示文稿,程序将作为路由配置的一部分为查询参数和将成为在查询规范中,参数,依此类推。

总结

当我开始这篇文章时,我提到 MongoDB 和 DocumentDB 都很相似; 的所有方法但是,现在您可以开始感测有实际的差异的两个,通过其构造背后的理念许多如果任何其他内容。Microsoft 清楚地希望将一些"企业"放入面向文档数据库领域中与 DocumentDB,和赋予其客户群,这是稳定的移动。但是,显然缺少的一件事 (目前) 是任何一种"object-ish"包装器而 DocumentDB API,类似于 Mongoose 提供了对 Node.js MongoDB API。这不是开发人员可以构建其自身和复杂的事情,但它不表示说开发人员需要编写和维护随时间的更多代码。或至少是开放源代码社区直到任一端口 Mongoose、 采用它以使用 MongoDB 或 DocumentDB (不太可能),直到某人生成类似于它只是在更专用的方式比哪些 DocumentDB 接近生命。

更重要的是,但是,是要意识到首字母缩写词"平均值"就是指 — 是首字母缩写。DocumentDB 表示十几种可能的后端的持久性工具之一"* EAN"-风格堆栈,包括良好古老的 SQL Server。"MEAN"不符合企业标准,操作人员或业务目标,可随意将有问题的部分替换为更友好的内容位置。在第二天,一种体系结构到信 (顾名思义) 结束时,可为您作为开发人员和/或为整个组织中创建的问题是有点多余。 我还有其他空间现在 … 祝您编码愉快 !


Ted Neward 是基于西雅图的 polytechnology 顾问、 发言人和导师。 他曾写过 100 多篇文章,是 F # MVP 和具有创作,并且与人合著过十几本书。如果您有兴趣请他参与您的团队工作,请通过 ted@tedneward.com 与他联系,或通过 blogs.tedneward.com 访问其博客。

感谢以下技术专家对本文的审阅: Shawn Wildermuth