node连接--MongoDB
简介:
- 传统关系类型(ORM:Object-Relational Mapper),MongoDB(ODM:Object Document Mapper);
- MongoDB是一个面向文档,schme无关(可以将任意类型的文档数据存储到集合中)的数据库;
- MongoDB中可以将数据都看作文档,文档可以是任意深度的;
- 当有数据存储后,这些文档会以十分接近JSON格式的形式存储;
- 文档数据的数据类型可以是混合的,Node.js获取储存文档数据后,其类型和储存时候的类型是一样的;
例子:
- package.json:
{
"name": "user-auth-example",
"version": "0.0.1",
"dependencies": {
"express": "2.5.8",
"mongodb": "1.3.19",
"jade": "0.20.3"
}
} - views/layout.jade:
doctype 5
html
head
title MongoDB example
body
h1 My first MongoDB app
hr
block body - views/index.jade:
extends layout
block body
if (authenticated)
p Welcome back, #{me.email}
a(href="/logout") Logout
else
p Welcome new visitor!
ul
li: a(href="/login") Login
li: a(href="/signup") Signup - views/login.jade:
extends layout
block body
form(action="/login", method="POST")
fieldset
legend Log in
if (signupEmail)
#{signupEmail}
p Congratulations on signing up! Please login below
p
label Email
input(name="user[email]", type="text", value=signupEmail)
p
label Password
input(name="user[password]", type="password")
p
button submit
p
a(href="/") Go back - views/signup.jade:
extends layout
block body
form(action="/signup", method="POST")
fieldset
legend Sign up
p
label First
input(name="user[first]", type="text")
p
label Last
input(name="user[last]", type="text")
p
label Email
input(name="user[email]", type="text")
p
label Password
input(name="user[password]", type="password")
p
button Submit
p
a(href="/") Go back - server.js:
var express = require('express');
var mongodb = require('mongodb');
var ObjectId = mongodb.ObjectID; var app = express.createServer(); //加入中间件
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({secret: 'my secret'}));
app.use(function(req, res, next) { //身份验证中间件
if (req.session.loggedIn) {
res.local('authenticated', true); //express 的res.local API
app.users.findOne({"_id": ObjectId(req.session.loggedIn)}, function(err, doc) {
if (err) return next(err);
res.local('me', doc);
next()
})
} else {
res.local('authenticated', false);
next()
}
}); app.set('view engine', 'jade');
//express 3不需要这段代码
app.set('view options', {layout: false}); //创建mongodb.Server 初始化服务器
var server = new mongodb.Server('127.0.0.1', 27017); //告诉驱动器连接数据库'my-website',不存在会创建
new mongodb.Db('my-website', server, {w: 1}).open(function(err, client) {
if (err) {
throw err
}
console.log('\033[96m + \033[39m connected to mongodb'); //创建数据库操作集合的快捷方式
app.users = new mongodb.Collection(client, 'users');
// 不管索引是否存在,都可以调用这个命令来确保在查询前建立了索引
client.ensureIndex('users', 'email', function(err) {
if (err) throw err
client.ensureIndex('users', 'password', function() {
if (err) throw err
});
console.log('\033[96m + \033[39m ensured indexes');
app.listen(3000, function() {
console.log('\033[96m + \033[39m app listening on *:3000');
})
})
}); app.get('/', function(req, res) {
res.render('index')
});
app.get('/login', function(req, res) {
if (req.session.loggedIn) {
res.redirect('/');
} else {
res.render('login', {signupEmail: ''});
}
});
app.get('/login/:signupEmail', function(req, res) {
res.render('login', {signupEmail: req.params.signupEmail});
});
app.post('/login', function(req, res) {
//文档查找
app.users.findOne({email: req.body.user.email, password: req.body.user.password}, function(err, doc) {
if (err) return next(err)
if (!doc) return res.send('User not found. Go back and try again');
req.session.loggedIn = doc._id.toString();
res.redirect('/');
})
});
app.get('/logout', function(req, res) {
req.session.loggedIn = null
res.redirect('/');
});
app.get('/signup', function(req, res) {
res.render('signup');
});
app.post('/signup', function(req, res, next) {
//创建文档
app.users.insert(req.body.user, function(err, doc) {
if (err) {
return next(err)
}
res.redirect('/login/' + doc[0].email);
})
});
使用jade: //缩进,默认两个空格 ; //注意tab和space不要混着用
问题:
- 校验://表单校验类型,大小等; mongoose通过在应用层定义scheme(模型)来解决;
- 原子性://多个用户同时对同一文档进行了操作; mongoose通过检查要对文档做的修改,并只修改受影响的字段来解决;
- 安全模式:在使用驱动时,对文档的操作中有一个可选参数: app.users.insert({},{<options>});其中safe选项对在对数据库进行修改时启动安全模式;默认情况下,在操作完成后,如果有错误发生,MongoDB不会及时通知;驱动器需要早操作后调用db.getLastError,来验证数据修改是否成功; mongoose默认会对所有操作启用安全模式;
Mongoose://mongoose假定绝大部分应用程序都是用一个数据库;使用mongoose的时候无需关系连接是否建立,它会把数据库操作指令缓存起来,在连上数据库后发送出去;
- 定义模型:类型包括Date,String,Number,Array,Object,ObjectId(MongiDB提供);例子:
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId; //创建模型
var PostSchema = new Schema({
author : ObjectId,
title: {type : String, default: 'default' }, //选项格式
body : String,
date : Date
}); //注册模型 var Post = mongoose.model("BlogPost', PostSchema); //获取模型
var Post = mongoose.modek('BlogPost'); //操作模型:创建 new Post({title: “My Title"}).save(function (err) {
....
}); - 定义嵌套的键:
var BlogPost = new Schema({
title : String,
meta : {
votes : Number,
favs : Number
}
});
//特定查找
db.blogposts.find({'meta.votes':5}); - 定义嵌套的文档:
var Comments = new Schema({......});
var BlogPost = new Schema({
.....
comments : [Comments],
.....
}); - 构建索引:要对指定的键做索引,需要传递一个index选项,并将值设置为true;
//设置title键做索引,并将uid键设置为唯一; var BlogPost = new Schema({
author : ObjectId,
title : {type: String, index : true},
uid : {type : Number, unique : true}
}) - 中间件:有时候会在不同的地方以不同的方式对同样的数据进行修改,通过模型接口对这部分对数据库的交互集中避免代码重复;
//定义一操作在特定动作前执行,如在删除博文时发送电子邮件给作者;
Blogpost.prev('remove', function (next) {
emailAuthor(this.email, 'Blog post removed!');
next();
}); - 探测模型状态:根据要对当前模型做的不同更改进行不同操作
Blogpost.prev('save', function(next) {
if(this.isNew) {
....
} else {
.....
}
}); - 查询:
- find
- findOne
- findById //根据ObjectId
- remove
- update
- count
- 扩展查询:如果对某个查询不提供回调函数,那么直到调用run才会执行;
Post.find({autor: '...'})
.where('title','My title')
.sort('content', -1)
.limit(5)
.run(function(err, post) {
...............
}) - 排序:
query.sort('key', 1);
query.sort('some.key',-1); - 选择:若文档大,只想要指定部分;
Post.find().select('field', 'field2');
- 限制:现在查询结果的数量;
query.limit(5);
- 跳过:跳过指定数量的文档数据
query.skip(10);
- 自动产生键:
//查询一个博文的时候,还获取对应的作者;为ObjectId类型提供一个href属性;
var BlogPost = new Schema({
author : {type : ObjectId, ref : 'Author'},
title : String,
body : String,
meta : {
votes : Number,
favs : Number
}
}) //对指定键调用populate就可自动生成;
BlogPost.find({title : 'My title'})
.populate('author')
.run(function (err, doc) {
console.log(doc.ahthor.email);
}); - 对上一个server.js使用mongoose之后:
var express = require('express');
var mongoose = require('mongoose'); //建立模型
var Schema = mongoose.Schema;
var User = mongoose.model('User', new Schema({
first: String,
last: String,
email: {type: String, unique: true},
password: {type: String, index: true}
})); var app = express.createServer(
express.bodyParser(),express.cookieParser(),express.session({secret: 'my secret'})
); app.use(function(req, res, next) {
if (req.session.loggedIn) {
res.local('authenticated', true);
User.findById(req.session.loggedIn, function(err, doc) {
if (err) return next(err);
res.local('me', doc);
next();
});
} else {
res.local('authenticated', false);
next();
}
}); app.set('view engine', 'jade');
app.set('view options', {layout: false}); app.get('/', function(req, res) {
res.render('index')
}); app.get('/login', function(req, res) {
if (req.session.loggedIn) {
res.redirect('/');
} else {
res.render('login', {signupEmail: ''});
}
}); app.get('/login/:signupEmail', function(req, res) {
res.render('login', {signupEmail: req.params.signupEmail});
}); app.post('/login', function(req, res) {
//文档查找
User.findOne({email: req.body.user.email, password: req.body.user.password}, function(err, doc) {
if (err) return next(err)
if (!doc) return res.send('User not found. Go back and try again');
req.session.loggedIn = doc._id.toString();
res.redirect('/');
})
}); app.get('/logout', function(req, res) {
req.session.loggedIn = null
res.redirect('/')
}); app.get('/signup', function(req, res) {
res.render('signup')
}); app.post('/signup', function(req, res, next) {
var user = new User(req.body.user);
user.save(function(err) {
if (err) return next(err);
res.redirect('/login/' + user.email);
});
}); //连接数据库
mongoose.connect('mongodb://127.0.0.1/my-website');
app.listen(3000, function() {
console.log('\033[96m + \033[39m app listening on *: 3000');
});
node连接--MongoDB的更多相关文章
- 使用node连接MongoDB数据 综本地及linux服务器记
gitee地址 启动mongo D:\MongoDB> ./bin/mongod --dbpath ./data/db MongoDB 提供了简单的 HTTP 用户界面. 如果你想启用该功能,需 ...
- node连接mongoDB篇
一般介绍: 由于mongodb数据库在javascript脚本环境中支持bson对象(json对象的二进制形式)的存取,因此对于数据的存取的效率是非常高的.在mongodb数据库中,将每一条等待插入的 ...
- node连接mongodb(简略版)
1.先通过配置启动mongodb,然后新建db.js 已经对相对应的数据库操作增删改查封装完成. //这个模块里面封装了所有对数据库的常用操作 var MongoClient = requir ...
- 跟我一起用node-express搭建一个小项目(node连接mongodb)[三]
数据库虽然安装并启动成功了,但我们需要连接数据库后才能使用数据库. 怎么才能在 Node.js 中使用 MongoDB 呢? 我们使用官方提供的 node-mongodb-native 驱动模块,打开 ...
- 【node】node连接mongodb操作数据库
1.下载第三方模块mongodb cnpm install mongodb --save 2.检测是否连接成功 1.引入第三方模块mongodb并创建一个客户端 const MongoClient = ...
- 【node】------node连接mongodb操作数据库------【巷子】
1.下载第三方模块mongodb cnpm install mongodb --save 2.检测是否连接成功 1.引入第三方模块mongodb并创建一个客户端 const MongoClient = ...
- 【Node.js】二、基于Express框架 + 连接MongoDB + 写后端接口
在上节,我们讲了如何搭建express环境,现在我们说说如何通过node.js写服务接口给前端调用 1. 首先通过MongoDB建好数据库与表格 例如,我的数据库名字为db_demo,数据库表格为go ...
- 初学node.js-nodejs连接MongoDB(5)
一.吧MongoDB的驱动程序添加到Node.js中 Node.js 连接 MongoDB 连接
- docker node项目 连接mongodb
在弄docker部署node项目的时候遇到了连接mongdb的问题,记录一下问题解决办法 一.Docker 安装 MongoDB 1.查找Docker Hub上的mongo镜像 [root@VM_49 ...
随机推荐
- C#集合接口的继承关系图
- editplus快捷键大全之editplus编辑快捷键
前面我们说了editplus快捷键大全之editplus文件快捷键和editplus快捷键大全之editplus光标快捷键,这里我们讲一下editplus快捷键大全之editplus编辑快捷键 删除光 ...
- MySQL目录
MySQL的学习总结目录 Mysql5.7安装及配置 教你如何3分钟玩转MYSQL MySQL使用详解--根据个人学习总结 Mysql增删改 Mysql_以案例为基准之查询 MySQL之扩展(触发器, ...
- 使用ifconfig命令给网卡配置ip别名
给网卡eth0配置一个ip别名 sudo ifconfig eth0:0 10.108.125.6/22 up 若想保存该配置,以便每次开机都可以使用该ip别名,则应 sudo vim /etc/ne ...
- kettle job通过javascript进行循环控制
任何一种编程语言都少不了循环,kettle中的job也一样.那么kettle中的job是怎么通过JavaScript来达到类似于编程语言中的for循环呢? var max = parent_job.g ...
- Java构造方法的含义和使用
我们实例化对象时,一般使用"类名 对象名 = new 类名()"来实例化,其实这样并不是十分严谨,只是编译器帮我们自动补全了一个空的构造方法,当实例化对象时,构造方法会被自动调用, ...
- 【贪心】最大乘积-贪心-高精度-java
问题 G: [贪心]最大乘积 时间限制: 1 Sec 内存限制: 128 MB提交: 34 解决: 10[提交][状态][讨论版] 题目描述 一个正整数一般可以分为几个互不相同的自然数的和,如3 ...
- codeforces A. Strange Addition 解题报告
题目链接:http://codeforces.com/problemset/problem/305/A 题目意思:给出一个序列,需要从中选择一些数,这些数需要满足:任意的两个数中每一位至少有一个数满足 ...
- Java性能优化权威指南-读书笔记(四)-JVM性能调优-延迟
延迟指服务器处理一个请求所花费的时间,单位一般是ms.s. 本文主要讲降低延迟可以做的服务器端JVM优化. JVM延迟优化 新生代 新生代大小决定了应用平均延迟 如果平均Minor GC持续时间大于应 ...
- Android procrank , showmap 内存分析
(一)DDMS 的Heap Dump 1) Data Object:java object. 2) Class Object:object of type Class, e.g. what you'd ...