Skip to content

Latest commit

 

History

History
487 lines (251 loc) · 21.3 KB

File metadata and controls

487 lines (251 loc) · 21.3 KB

七、MongoDB 简介

What is Oracle bone inscriptions? A bunch of people. All our products are just the ideas in these people's minds-the ideas that people put into computers and tested, which proved to be the best ideas for databases or programming languages. - Larry Ellision [T1】 T3]

在本章中,我们将探讨以下主题:

  • 蒙戈布贝壳
  • Node.js 的 MongoDB 本机驱动程序
  • MongoDB on Heroku with MongoLab
  • 留言板:MongoDB 版本

MongoDB 是一个 NoSQL 文档存储数据库。它具有可扩展性和高性能。它没有模式,所以所有的逻辑和关系都在应用层实现。你可以使用像水线或者猫鼬这样的 ODM。MongoDB 使用 JavaScript 接口,完成了浏览器、服务器、数据库层的全栈 JavaScript 栈拼图。有了 MongoDB,我们可以对所有三层使用一种语言。开始使用 MongoDB 最简单的方法是使用它的 shell,也就是 REPL (read-eval-print-loop)。

蒙戈布贝壳

如果您还没有安装,请从 mongodb.org/downloads 安装最新版本的 MongoDB。更多说明,请参考第二章中的数据库:MongoDB 部分。您可能需要按照说明创建一个数据文件夹。

现在,从解压归档文件的文件夹中,使用以下命令启动mongod服务:

$ ./bin/mongod

localhost:28017时,您应该能够在您的终端和浏览器中看到信息。

对于 MongoDB shell,或mongo,在新的终端窗口中启动(重要!),并在同一文件夹中执行以下命令:

$ ./bin/mongo

根据您的 MongoDB shell 版本,您应该会看到类似这样的内容:

MongoDB shell version: 2.0.6

connecting to: test

要测试数据库,使用类似 JavaScript 的界面和命令savefind:

> db.test.save( { a: 1 } )

> db.test.find()

更详细的分步说明可以在数据库中找到:第 2 章的的 MongoDB 部分。

其他一些有用的 MongoDB shell 命令来自 MongoDB 和 mongose cheat sheet(https://gum.co/mongodb/git-874e6fb4):

  • > show dbs:显示服务器上的数据库
  • > use DB_NAME:选择数据库DB_NAME
  • > show collections:显示所选数据库中的收藏
  • > db.COLLECTION_NAME.find():对名称为 COLLECTION_NAME 的集合执行查找查询,查找任何项目
  • > db.COLLECTION_NAME.find({"_id": ObjectId("549d9a3081d0f07866fdaac6")}):对 COLLECTION_NAME 名称的集合执行查找查询,查找 ID 为 549d9a3081d0f07866fdaac6 的项目
  • > db.COLLECTION_NAME.find({"email": /gmail/}):对 COLLECTION_NAME 名称的集合执行查找查询,查找邮件属性与/gmail匹配的项目
  • > db.COLLECTION_NAME.update(QUERY_OBJECT, SET_OBJECT):对 COLLECTION_NAME 名称的集合执行更新查询,更新 QUERY_OBJECT 与 SET_OBJECT 匹配的项目
  • > db.COLLECTION_NAME.remove(QUERY_OBJECT):对 COLLECTION_NAME 集合中符合 QUERY_OBJECT 条件的项目进行删除查询
  • > db.COLLECTION_NAME.insert(OBJECT):将对象添加到名称为集合名称的集合中

因此,从一个新的 shell 会话开始,您可以执行以下命令来创建、更改和删除文档:

> help

> show dbs

> use board

> show collections

> db.messages.remove();

> var a = db.messages.findOne();

> printjson(a);

> a.message = "hi";

> a.name = "John";

> db.messages.save(a);

> db.messages.find({});

> db.messages.update({name: "John"},{$set: {message: "bye"}});

> db.messages.find({name: "John"});

> db.messages.remove({name: "John"});

你可以下载 MongoDB 和 Mongoose cheatsheet 作为 PDF ( https://gumroad.com/l/mongodb/fsjs-CB07C579 #)或者在 https://github.com/mongodb/node-mongodb-native/#data-types 在线查看。

MongoDB 交互 shell 的完整概述可以在 mongodb.org 上找到:概述——MongoDB 交互 Shell ( https://docs.mongodb.org/manual/tutorial/getting-started-with-the-mongo-shell/ )。

断续器

二进制 JSON 或 BSON 是 MongoDB 使用的一种特殊数据类型。它在符号上类似于 JSON,但是支持更多更复杂的数据类型,比如 buffer 或 date。

关于 BSON 有一点需要注意:MongoDB 中的 ObjectID 相当于 MongoDB Native Node.js 驱动程序中的 ObjectId(即,确保使用正确的大小写)。否则你会得到一个错误。更多关于类型:MongoDB 中的 ObjectId(http://www.mongodb.org/display/DOCS/Object+IDs)vsMongoDB 原生 Node 中的数据类型。js 干燥机 ( https://github.com/mongodb/node-mongodb-native/#data-types )。带有mongodb.ObjectID() : collection.findOne({_id: new ObjectID(idString)}, console.log) // ok的 Node.js 代码示例。另一方面,在 MongoDB shell 中,我们使用了:db.messages.findOne({_id:ObjectId(idStr)});

MongoDB 本地驱动程序

引导您完成实施并演示项目的补充视频: http://bit.ly/1QnqZSk

我们将使用 MongoDB 的 Node.js 本地驱动程序( https://github.com/christkv/node-mongodb-native )从 Node.js 应用访问 MongoDB。完整文档也可在 http://mongodb.github.com/node-mongodb-native/api-generated/db.html 获取。

要为 Node.js 安装 MongoDB 本机驱动程序,请使用:

$ npm install mongodb

更多详情请见 http://www.mongodb.org/display/DOCS/node.JS

不要忘记在package.json文件中包含依赖关系:

{

"name": "node-example",

"version": "0.0.1",

"dependencies": {

"mongodb":"",

...

},

"engines": {

"node": ">=0.6.x"

}

}

或者,对于您自己的开发,您可以使用其他映射器,它们是本地驱动程序的扩展:

这个小例子将测试我们是否可以从 Node.js 脚本连接到本地 MongoDB 实例。

在我们安装了库之后,我们可以在我们的app.js文件中包含mongodb库:

var util = require(’util’)

var mongodb = require (’mongodb’)

这是建立到 MongoDB 服务器的连接的方法之一,其中 DB 变量将保存对指定主机和端口上的数据库的引用:

var Db = mongodb.Db

var Connection = mongodb.Connection

var Server = mongodb.Server

var host = ’127.0.0.1’

var port = 27017

var db=new Db (’test’, new Server(host,port, {}))

要实际打开一个连接:

db.open(function(error, connection){

// Do something with the database here

db.close()

})

为了检查我们是否有连接,我们需要处理error。同样,让我们用db.admin()获取管理对象,用listDatabases()获取数据库列表:

var db=new Db (’test’, new Server(host, port, {}))

db.open(function(error, connection){

console.log(’error: ’, error)

var adminDb = db.admin()

adminDb.listDatabases(function(error, dbs) {

console.log(’error: ’, error)

console.log(’databases: ’, dbs.databases)

db.close()

})

})

这段代码片段可在https://github.com/mongodb/node-mongodb- native/#data-types获得。如果我们运行它,它应该在终端中输出“connected”。当你有疑问并且需要检查一个对象的属性时,在util模块中有一个有用的方法:

console.log(util.inspect(db))

现在,您可能希望在云中设置数据库,并从 Node.js 脚本测试连接。

蒙戈布 on Heroku:蒙戈布

引导您完成实施并演示项目的补充视频: http://bit.ly/1Qnr8Fn

在您使显示“已连接”的应用在本地工作之后,是时候稍微修改它并将其作为服务部署到平台上了(例如 Heroku)。

我们推荐使用 MongoLab 附加组件( https://elements.heroku.com/addons/mongolab )。MongoLab 插件提供了一个基于浏览器的 GUI 来查找和操作数据和集合。更多信息请访问 https://elements.heroku.com/addons/mongolab#docs

请注意,即使您选择了免费版本,也可能需要提供您的信用卡信息才能使用 MongoLab。不过,你不应该被起诉。

为了连接到数据库服务器,有一个数据库连接 URL(又名 MongoLab URL/URI),这是一种传输所有必要信息的方法,以便在一个字符串中连接到数据库。

数据库连接字符串MONGOLAB_URI具有以下格式:

mongodb://user:pass@server_NAME.mongolab.com:PORT/db_name

您可以从 Heroku 网站复制 MongoLab URL 字符串(并对其进行硬编码),或者从 Node.js process.env对象获取字符串:

process.env.MONGOLAB_URI

或者

var connectionUri = url.parse(process.env.MONGOLAB_URI)

全局对象进程通过process.env访问环境变量。这些变量通常用于传递数据库主机名和端口、密码、API 键、端口号以及其他不应该硬编码到主逻辑中的系统信息。

为了让我们的代码在本地和 Heroku 上都能工作,我们可以使用逻辑 OR 操作符||并在环境变量未定义的情况下分配一个本地主机和端口:

var port = process.env.PORT || 1337

var dbConnUrl = process.env.MONGOLAB_URI ||

’mongodb://127.0.0.1:27017/test’

这里是我们更新的跨环境就绪app.js文件( https://github.com/azat-co/fullstack-javascript/tree/master/10-db-connect-heroku )。我添加了一个方法来获取集合列表listCollections,而不是获取数据库列表(我们现在在 MongoLab 中只有一个数据库):

var util = require(’util’)

var url = require(’url’)

var client = require (’mongodb’).MongoClient

var dbConnUrl = process.env.MONGOLAB_URI ||

’mongodb://127.0.0.1:27017/test’

console.log(’db server: ’, dbConnUrl)

client.connect(dbConnUrl, {}, function(error, db){

console.log(’error: ’, error)

db.listCollections().toArray(function(err, collections) {

console.log(’error: ’, error)

console.log(’collections: ’, collections)

db.close()

})

})

通过添加MONGOLAB_URIapp.js进行修改后,我们现在可以初始化 Git 存储库,创建一个 Heroku 应用,向其中添加 MongoLab 附加组件,并使用 Git 部署该应用。

利用与前面示例中相同的步骤创建一个新的 git 存储库:

$ git init

$ git add .

$ git commit -am ’initial commit’

创建雪松栈 Heroku 应用:

$ heroku create

如果一切顺利,你应该可以看到一条消息,告诉你新的 Heroku 应用名称(和网址)以及一条消息,远程已被添加。在您的本地 git 中拥有 remote 是至关重要的;您可以随时通过以下方式查看遥控器列表:

$ git remote show

要在现有的 Heroku 应用上安装免费的 MongoLab(加载项基于每个应用),请使用:

$ heroku addons:create mongolab:sandbox

或者使用您的 Heroku 凭证登录 Heroku ( https://elements.heroku.com/addons/mongolab ),并为特定的 Heroku 应用选择 MongoLab Free(如果您知道该应用的名称)。

项目文件夹需要有Procfilepackage.json。你可以从 https://github.com/azat-co/fullstack-javascript/tree/master/10-db-connect-heroku 中复制它们。

现在,您可以通过以下方式将代码推送到 Heroku:

$ git push heroku master

享受应该告诉您部署成功的日志。现在查看以下命令的输出:

$ heroku logs

结果将是这样的:

2015-12-01T12:34:51.438633+00:00 app[web.1]: db server:  mongodb://heroku_cxgh54g6:9d76gspc45v899i44sm6bn790c@ds035617.mongolab.com:34457/heroku_cxgh54g6

2015-12-01T12:34:53.264530+00:00 app[web.1]: error:  null

2015-12-01T12:34:53.236398+00:00 app[web.1]: error:  null

2015-12-01T12:34:53.271775+00:00 app[web.1]: collections:  [ { name: ’system.indexes’, options: {} },

2015-12-01T12:34:53.271778+00:00 app[web.1]:   { name: ’test’, options: { autoIndexId: true } } ]

如果您让app.js和修改过的app.js文件工作,让我们通过添加一个 HTTP 服务器来增强,这样‘已连接’消息将显示在浏览器中,而不是终端窗口中。为此,我们将把服务器对象实例化封装在一个数据库连接回调中(file 11-d b-server/app . js athttps://github.com/azat-co/fullstack-javascript/blob/master/11-db/app.js)。

引导您完成实施并演示项目的补充视频: http://bit.ly/1Qnrmwr

var util = require(’util’)

var url = require(’url’)

var http = require(’http’)

var mongodb = require (’mongodb’)

var client = require (’mongodb’).MongoClient

var port = process.env.PORT || 1337

var dbConnUrl = process.env.MONGOLAB_URI || ’mongodb://@127.0.0.1:27017/test’

client.connect(dbConnUrl, {}, function(error, db) {

console.log(’error: ’, error)

db.listCollections().toArray(function(error, collections) {

console.log(’error: ’, error)

console.log(’collections: ’, collections)

var server = http.createServer(function (request, response) { // Creates server

response.writeHead(200, {’Content-Type’: ’text/plain’})   // Sets the right header and status code

response.end(util.inspect(collections))  // Outputs string with line end symbol

})

server.listen(port, function() {

console.log(’Server is running at %s:%s ’, server.address().address, server.address().port) // Sets port and IP address of the server

})

db.close()

})

})

最终 Heroku 部署就绪项目位于 https://github.com/azat-co/fullstack-javascript/tree/master/11-db-serverunder

部署完成后,您应该能够打开 Heroku 提供的 URL 并查看收藏列表。如果它是一个新创建的应用,数据库为空,则不会有收藏。您可以使用 Heroku 中的 MongoLab web 界面创建一个集合。

关于原生 MongoDB 驱动程序的更多信息,请查看 http://mongodb.github.io/node-mongodb-native/api-articles/nodekoarticle1.html

留言板:MongoDB 版本

引导您完成实施并演示项目的补充视频: http://bit.ly/1QnsfoE .

我们应该已经为编写 Node.js 应用做好了一切准备,它既可以在本地运行,也可以在 Heroku 上运行。源代码可在 https://github.com/azat-co/fullstack-javascript/tree/master/12-board-api-mongonder 获得。应用的结构很简单:

/12-board-api-mongo

-web.js

-Procfile

-package.json

这就是web.js的样子;首先,我们包括我们的图书馆:

var http = require(’http’)

var util = require(’util’)

var querystring = require(’querystring’)

var client = require(’mongodb’).MongoClient

然后输出一个连接 MongoDB 的神奇字符串:

var uri = process.env.MONGOLAB_URI || ’mongodb://@127.0.0.1:27017/messages’

注意,URI/URL 格式包含可选的数据库名称,我们的集合将存储在其中。请随意将其更改为其他名称:例如,“rpjs”或“test”。

我们将所有逻辑以回调函数的形式放在开放连接中:

client.connect(uri, function(error, db) {

if (error) return console.error(error)

我们用下面的语句获取集合:

var collection = db.collection(’messages’)

现在,我们可以实例化服务器并设置逻辑来处理我们的端点/路由。我们需要在 GET /messages/list.json上获取文档:

var app = http.createServer( function (request, response) {

if (request.method === ’GET’ && request.url === ’/messages/list.json’) {

collection.find().toArray(function(error,results) {

response.writeHead(200,{ ’Content-Type’: ’text/plain’})

console.dir(results)

response.end(JSON.stringify(results))

})

在帖子/messages/create.json上,我们插入了文档:

} else if (request.method === ’POST’ && request.url === ’/messages/create.json’) {

request.on(’data’, function(data) {

collection.insert(querystring.parse(data.toString(’utf-8’)), {safe:true}, function(error, obj) {

if (error) throw error

response.end(JSON.stringify(obj))

})

})

} else {

如果客户端请求与上述任何条件都不匹配,就会显示这一信息。当我们试图去http://localhost:1337而不是http://localhost:1337/messages/list.json时,这是一个很好的提醒:

response.end(’Supported endpoints: \n/messages/list.json\n/messages/create.json’)

}

})

var port = process.env.PORT || 1337

app.listen(port)

})

Note

我们不必在集合/实体名称后使用额外的单词;也就是说,对于所有的 HTTP 方法,比如 GET、POST、PUT、DELETE,只使用/messages,而不是/messages/list.json/messages/create.json,是非常好的。如果您在应用代码中更改它们,请确保使用更新的 CURL 命令和前端代码。

要通过 CURL 终端命令运行测试:

$ curl http://localhost:5000/messages/list.json

或者在http://locahost:1337/messages/list.json位置打开浏览器。

它应该会给你一个空数组:[],没问题。然后发布一条新消息:

$ curl  -d "username=BOB&message=test" http://localhost:5000/messages/create.json

现在我们必须看到一个包含新创建元素的 ObjectID 的响应,例如:[{"username":"BOB","message":"test","_id":"51edcad45862430000000001"}]。您的 ObjectId 可能有所不同。

如果在本地一切正常,尝试将其部署到 Heroku。

要在 Heroku 上测试应用,您可以使用相同的 CURL 命令( http://curl.haxx.se/docs/manpage.html ),用您独特的 Heroku 应用的主机/URL 替换http://localhost/ or “ http://127.0.0.1 “:

$ curlhttp://your-app-name.herokuapp.com/messages/list.jsonT3】

$ curl -d "username=BOB&message=test"

T2http://your-app-name.herokuapp.com/messages/create.json

也可以通过 Mongo shell: $ mongo终端命令,然后是use twitter-clonedb.messages.find()来仔细检查数据库;或通过 MongoHub ( https://github.com/bububa/MongoHub-Mac )、mongoui ( https://github.com/azat-co/mongoui )、mongo-express( https://github.com/andzdroid/mongo-express )或在 MongoLab 的情况下通过其可在 heroku.com 网站访问的网络界面。

如果你想用另一个域名代替 http://your-app-name.herokuapp.com ,你需要做两件事:

Tell Heroku your domain name: $ heroku domains:add www.your-domain-name.com   Add the CNAME DNS record in your DNS manager to point to http://your-app-name.herokuapp.com .  

有关自定义域名的更多信息,请访问 devcenter.heroku.com/articles/custom-domains

提示为了更有效地开发,我们应该尽可能地自动化;也就是说,使用测试代替 CURL 命令。在奖励章节中有一篇关于 Mocha 库的文章,与superagentrequest库一起,为这类任务节省了时间。

摘要

在本章中,我们已经介绍了 MongoDB 数据库及其 shell。MongoDB 使用 JSON 的扩展版本,称为 BSON。然后我们用原生 MongoDB 驱动切换到 Node.js。许多其他 MongoDB Node.js 库依赖于原生驱动程序,并在其上构建。正因如此,知道就好。为了在 Heroku 上使用 MongoDB,我们使用了 MongoLab 插件(神奇的MONGOLAB_URI)。最后,我们使用获得的知识为留言板应用添加持久性。