基本使用

概念

SQL和NoSQL

文档 Document

文档就是键值对的一个集合,实际上表达方式和JSON一样
文档就是JSON,但是要比JSON多了一些限制:

  • 每个文档必须有一个特殊的键 _id, 这个键在集合中必须是保证唯一性.
  • 文档中键的命名,不能含有.$
  • 文档中值的额类型,比原生JavaScript更多, 比如:日期,ObjectId(),正则表达式
  • 文档是给用户看的,是JSON的表示模式,但实际存储的时候,是BSON方式(用二进制方式存储)

集合 Collections

集合就是一组文档(document),相当于“表”
集合中可以存储完全不同的结构的文档

数据库 DataBase

  • 数据库中存储众多的集合
  • 数据库最终会变成文件系统里的文件,而数据库名字就是相应的文件名。数据库的命名应该遵守操作系统的文件命名规范。
  • 数据库命名不能是admin,local,config

mongod

mongo 使用数据库

mongod 开机

mongoimport 导入数据

mongod --dbpath c:\mongodata
// --dbpath 参数,表示数据库的存放位置,文件夹必须事先创建
// mongoDB 有真实的物理文件,对应一个个数据库。
db.help(); // 在 mongodb 客户端中获得帮助

db.stats(); 显示数据库名称、集合数目,以及数据库中的文档

MongoDB数据模型

MongoDB 中的数据模式非常灵活。同一集合中的文档不需要具有同一字段或结构,集合文档的公用字段可能包含不同类型的数据。

设计 MongoDB 模式注意问题

  • 根据用户需求来设计模式。
  • 如果想一起使用对象,请将这些对象合并到一个文档中,否则要将它们分开(但是要确保不需要连接)。
  • 经常复制数据(但要有一定限度),因为与计算时间相比,硬盘空间显得非常便宜。
  • 在写入时进行连接,而不能在读取时连接。
  • 针对经常发生的用例来设计模式。
  • 在模式中实现复杂的聚合。

  • 数据库中存储众多集合。
  • 数据库最终会变为文件系统里面的文件,而数据库名字就是相应的文件名,所以数据库的命名,应该遵守操作系统的文件名命名规范。
  • 数据库命名不能是adminlocalconfig

基本命令行操作

列出所有数据库

show dbs;

使用某个数据库

use students;
// 如果想新建,也是use, use一个不存在的库名,就是创建一个数据库。  

查看当前所在库

db

集合没有查看,需要插入数据之后,能够看到。 如果真的想创建刚才未存在的数据库,那么必须插入一个数据。不需要创建集合。
例如:

db.student.insert({'name': 'xiaoming', 'age': 23});
//student就是所谓的集合(collections)。集合中存储着很多json(document)。
//db. 一个未知的集合名字,这个集合将自动创建。    

mongodb增删改查

创建数据库

use + 数据库名称 的方式来创建数据库。use 会创建一个新的数据库,如果该数据库存在,则返回这个数据库。

use mydb

使用命令 db 检查当前选定的数据库。

db

使用命令 show dbs 来检查数据库列表。

show dbs

刚创建的数据库(mydb)没有出现在列表中。为了让数据库显示出来,至少应该插入一个文档。

删除数据库

db.dropDatabase();
// 删除当前所在的数据库

导入外部数据

mongoimport --db test --collection restaurants --dorp --file ddd.json
// --db test 想往那个数据库中导入
// --collection restaurants  想往那个集合中导入
// --dorp 把集合清空  表示数据库中有默认数据,覆盖原有数据。
// --file ddd.json 使用的是哪个文件.
mongoimport --db student --collection class1 --dorp --file a.json    

创建集合(表)

db.class1
//如果集合不存在,帮你创建集合

使用 show collections 来查看创建了的集合。

show collections
// 没有数据,刚创建的 集合 并不显示出来。

插入数据

db.class1.insert({'name': 'ting','age': 21}); 

查看数据(文档)

db.class1.find({});   //db.class1.find();
//find() 方法会以非结构化的方式来显示所有文档。
db.class1.find().pretty();
//用格式化方式显示结果//在 find() 方法中,如果传入多个键,并用逗号(,)分隔它们,那么 MongoDB 会把它看成是 AND 条件。
db.class1.find({'key1': 'val1', 'key2': 'val2'}); //若基于 OR 条件来查询文档,可以使用关键字 $or。  //或 的条件
db.class1.find({$or: [{key1: val1, key2: val2}]});

排序

db.class.find().sort({'sex': 1});  //1 升序

修改数据

// update暗含查找,修改谁,修改结果  update默认只会修改第一个document,需要第三个参数支持: {'multi': true}
db.class1.update({'name': 'xiaoming'},{$set: {'age': 16}});
// 批量修改
db.class1.update({'score.math': '60'},{$set: {'age': 20}}, {'multi': true});
db.class1.update({},{$set: {'age': 20}},{'multi': true});  //第一个参数为空,表示全部数据修改。
// 替换document, 没有使用$set关键字,完整替换
db.class1.uodate({'name': 'xiaoming'},{'age': 12});

删除数据

db.student1.drop(); // 删除集合 (篮子都删除)
db.studnet1.remove({}) //删除全部 (篮子还存在)
db.student1.remove({'score.math': 80}); //会删除全部匹配得到的
db.student1.remove({'score.math': 80},{justOne: true}); //删除匹配的第一个

nodeJs 使用 mongodb

// 安装 mongodb
npm install mongodb

nodejs 操作 mongodb

// mongo db 驱动
va r MongoClient = require('mongodb').MongoClient;
//数据库的地址  /student 表示数据库
// 假如数据库不存在,没有关系,程序会自动创建数据库
var url = 'mongodb://localhsot:27017/student';
// 建立连接
MongoClient.connect(url,function( err,db ){
// db 参数就是连接上数据库 实体 所有数据库操作都建立在 实体上。        if( err ){console.log('数据库连接失败');return ;}console.log('数据库成功连接');db.collection('student').insertOne({'name': 'mlln','age': 23},function( err,result ){if (err) {console.log('插入失败');return ;}console.log(result);res.send('1');db.close();});
});// cmd 中查看数据 比较多 可以使用 it  查看下一页

插入数据

db.collection('class1').isnertOne({'name': 'xiaoming', 'age': 21},function( err,result ){if( err )console.log('数据插入失败');console.log('数据插入成功');
});

查询数据

var cousor = db.collection('class1').find({});
// find({}) //可以输出查询条件。find({'score.math': 70});// 遍历游标
cousor.each(function( err,doc ){if( doc != null ){console.log(doc);  // 输出每条记录}
});
var cursor = db.collection('class1').find({'score.math': {$gt: 30}});
var cursor = db.collection('class1').find({ 'score.math': {$gt: 20} , 'score.cha': {$lt : 70}});
var cursor = db.collection('class1').find({ $or: [ {'score.math': {$gt: 50}}, {'scror.cha': {$lt: 70}} ] });
// 排序   // 1 正序 , -1 反序
var cursor = db.collection('class1').find({}).sort({'score.math': 1});

更新

覆盖匹配的记录 //updateOne();

db.collection('class1').updateOne({'name': 'mm'}, {'age': 23},function( err,result ){if( err )console.log('修改失败');console.log('修改成功');
});

修改字段中的值

db.collection.('class1').updateOne({'name': 'mlln'}, { $set: {'age': 24} }, function( err,result ){if ( err ) console.log('修改失败');console.log('修改成功');
});

替换记录 //replaceOne();

db.collection('class1').replaceOne({'name': 'mlln'}, {'name': 'm1', 'age': 20});

删除数据

db.collection('class1').deleteMany({'age',25},function( err,reslut ){if( err )console.log('删除失败');console.log('数据删除成功');
});

DAO层封装

mongooose 对象与数据对应,产生ODM思想 , 一个对象new出来之后,数据库中就存在。


// db模块封装了所有对数据库的常用操作
var MongoClient = require('mongodb').MongoClient;
var setting = require('../settings');// 连接数据库
function _connectDB(callback) {var url = setting.dburl;  // 配置文件中读取MongoClient.connect(url, function (err, db) {callback(err, db);});
}// 插入数据
// 往那个集合中增加,增加什么,增加之后的事情。
exports.insertOne = function (collectionName, json, callback) {_connectDB(function (err, db) {if (err) {callback(err, null);db.close(); // 关闭数据库return;}db.collection(collectionName).insertOne(json, function (err, result) {callback(err, result);db.close(); // 关闭数据库});});};// 查找数据
// 在那个集合查找,查什么,分页设置,查完之后做什么
exports.find = function (collectionName, json, args, callback) {if (arguments.length == 3) {callback = args;args = { 'pageamount': 0, 'page': 0 }} else if (arguments.length == 4) {} else {throw new Error('find参数是3个或者四个');}var result = [];// 应该省略的条数var skipNum = args.pageamount * args.page;// 数目限制var limitNum = args.pageamount;_connectDB(function (err, db) {var cursor = db.collection(collectionName).find(json).skip(skipNum).limit(limitNum);cursor.each(function (err, doc) {// each 遍历的时候存在问题,callback 匹配到一条,就执行一次,// callback 意义上是只执行一次,使用数组解决if (err) {callback(err, null);db.close(); // 关闭数据库return;}if (doc != null) {result.push(doc); //放入结果数组} else {// 遍历结束,没有更多文档callback(null, result);db.close(); // 关闭数据库}});});};// 删除
exports.deleteMany = function (collectionName, json, callback) {_connectDB(function (err, db) {db.collection(collectionName).deleteMany(json, function (err, result) {callback(err, result);db.close(); // 关闭数据库});});
};// 修改
exports.updateMany = function (collectionName, json1, json2, callback) {_connectDB(function (err, db) {if (err) {callback(err, null);return false;}db.collection(collectionName).updateMany(json1, json2, function (err, result) {callback(err, result);db.close();});});
};

mongoDB分页

// limit() 表示读取的条数
// skip() 表示略过的条数  

limit和skip配合使用就是分页查询。
假如,第一个是page=0,每页10条,所以当前页的查询语句

db.student.find().limit(10).skip(page*10);

数据总数
在shell中,找寻数据总数

db.student.stats().count; // 获得collections总数 // 需要向上取整。
db.student.find().count();
// find() ,有分页逻辑
exports.find = function( collectionName,json,args,callback ){if ( arguments.length == 3 ) {callback = args;args = {'pageamount': 0, 'page': 0}} else if ( arguments.length == 4 ) {} else {throw new Error('find参数是3个或者四个');return false;}// 应该省略的条数var skipNum = args.pageamount * args.page;//数目限制var limitNum = args.pageamount;_connectDB(function ( err,db ) {var cursor = db.collection(collectionName).find(json).skip(skipNum).limit(limitNum);cursor.each(function ( err,doc ) {// each 遍历的时候存在问题,callback 匹配到一条,就执行一次,// callback 意义上是只执行一次,使用数组解决if ( err ) {callback(err,null);return ;}if ( doc != null ) {result.push( doc ); //放入结果数组} else {//遍历结束,没有更多文档callback(null,result);}});});
}; 

cookie & session

cookie

需要cookie-parser中间件支持

  • HTTP是无状态协议。简单地说,当你浏览了一个页面,然后转到同一个网站的另一个页面,服务器无法认识到,这是同一个浏览器在访问同一个网站。每一次的访问,都是没有任何关系的。
  • Cookie是一个简单到爆的想法:当访问一个页面的时候,服务器在下行HTTP报文中,命令浏览器存储一个字符串;浏览器再访问同一个域的时候,将把这个字符串携带到上行HTTP请求中。
  • 第一次访问一个服务器,不可能携带cookie。 必须是服务器得到这次请求,在下行响应报头中,携带cookie信息,此后每一次浏览器往这个服务器发出的请求,都会携带这个cookie。

特点

  • cookie是不加密的,用户可以自由看到;
  • 用户可以删除cookie,或者禁用它
  • cookie可以被篡改
  • cookie可以用于攻击
  • cookie存储量很小。未来实际上要被localStorage替代,但是后者IE9兼容。

作用:
记录用户的信息,购买习惯,猜你喜欢。

express中的cookie, res负责设置cookie, req负责识别cookie。
cookie是没有跨域限制

cookie使用

var express = require('express');
var cookieParser = require('cookie-parser');
var app = express();
app.use(cookieParser());
app.get('/',function ( req,res ) {// maxAge 在express 是以毫秒为单位res.cookie('xihao','tfboys',{'maxAge': 9000,httpOnly: true});res.send(req.cookies);
});
app.listen(80);

猜你喜欢

页面中获取原先的值,push到数组中,然后再次设置回来。供首页访问。

var express = require('express');
var cookieParser = require('cookie-parser');
var app = express();
app.use(cookieParser());
app.get('/',function ( req,res ) {// maxAge 在express 是以毫秒为单位res.send('猜你喜欢' + req.cookies.mudidi );
});
app.get('/gonglve',function ( req,res ) {var mudidi = req.query.mudidi;//记录用户的喜好//读取用户的喜好,然后把新的数据push设置新的数据var mudidiArr = req.cookies.mudidi || [];mudidiArr.push( mudidi );res.cookie('mudidi',mudidiArr,{'maxAge': 9000,httpOnly: true});res.send(mudidi + '旅游攻略');
});
app.listen(80);

session

需要express-session中间件支持

会话,session并不是天生的就有的技术,而是依赖cookie。
用于登陆。当一个浏览器禁用cookie的时候,登陆效果消失,或者用户清除了cookie,登陆也消失。
session比cookie不一样的地方,session下发的是乱码,并且服务器自己缓存一些东西。下次浏览器的请求,带着乱码上来。此时与缓存(缓存是存在服务器内存中,一旦服务器关了,缓存就消失)进行比较,看看匹配的是哪一个。
所以,一个乱码,可以对应无限大的数据。(理论上),但是受内存限制。
任何语言中,session的使用,是“机理透明”的,它帮你设置cookie的.

var express = require('express');
var app = express();
var session = require('express-session');
app.use(session({secret: 'keyboard cat',resave: false,saveUninitialized: true,cookie: { secure: true }
}));app.get('/',function( req,res ){if ( req.session.login == '1' ) {res.send( '欢迎'+ req.session.username +'的登陆' );} else {res.send('没有成功登陆');}
});app.get('/login',function ( req,res ) {req.session.login = '1';req.session.username = 'mlln';res.send('你已经成功登陆');
});
app.listen(80)

加密

md5 加密 是函数型加密。每次加密的结果相同,没有随机位 //永远不要用明文写密码。
特点:

  • 不管加密的文字,多长多短,永远都是32位英语字母、数字混合。
  • 那怕只改一个字,密文都会大变。
  • MD5没有反函数的可能。 网上的破解工具,都是字典模式,通过列出明-密对应的字典找到明码。
  • MD5常用于版本校验。可以比对两个文件、软件是否完全一致。

node中,自带了一个模块 crypto模块,负责加密。

//创建hash
var md5 = crypto.createHash('md5');  //创建一个hash对应
//然后update 和  digest
var password = md5.update(fields.password).digest('base64');

console.log( md52( md52('123123').slice(11,7) + md52('123123') ) );
function md52( mingma ) {var md5 = crypto.createHash('md5');var password = md5.update(mingma).digest('base64');return password;
}

GM图像

gm软件

只要服务器需要处理图片,那么这个服务器就需要安装graphicsmagick软件 , 还有其它的图像处理软件。ImageMagick 。
GM软件API
GM-API
nodejs 使用graphicsmagick。需要第三方npm的gm包
GM包运行环境 链接描述

nodejs缩略图制作

var fs = require('fs');
var gm = require('gm');
gm('./axin.jpg').resize(50, 50,"!").write('./axin.jpg', function (err) {if (err) {console.log(err);}
});

nodejs头像裁切

gm("./axin.jpg").crop(141,96,152,181).write("./2.jpg",function(err){//141  96 是宽高 。  152  181是坐标
});

索引

index
数据库中,根据一个字段的值,来寻找一个文档,是很常见的操作。

查看检索的过程

db.student.find({'name': 'username33'}).explain();// 过程显示
{"cursor" : "BasicCursor","isMultiKey" : false,"n" : 2,"nscannedObjects" : 19999,"nscanned" : 19999,"nscannedObjectsAllPlans" : 19999,"nscannedAllPlans" : 19999,"scanAndOrder" : false,"indexOnly" : false,"nYields" : 0,"nChunkSkips" : 0,"millis" : 16,"indexBounds" : {},"server" : "YOS-01409231922:27017"
} 

为了快速进行检索,可以把唯一字段,建立成"索引".
每个collection是已经有一个索引(默认索引_id),再创建另外索引会具备两条索引。

建立索引:

db.student.createIndex({ 'name': 1 }); // 1 表示的是正向。

索引的优缺点:
好处:通过索引查询的速度会更快,因为可以从索引表中找到,当前个文档。
坏处:当数据库中的数据不存在的时候,已经建立的索引会存在。以后插入的数据会变慢。 损失的插入的时间。得到的是查询的时间。

复合索引

db.student.createIndex({ 'name': 1, 'address': -1 }); // 1 表示的是正向。 -1 表示负向

先以第一个条件排序,然后相同的时候以第二个条件再进行排序。(插入数据之前是一条默认的索引,索引建立之后是3条索引)

db.student.createIndex({ 'name': 1 }, {unique: true}); // unique 所有的collection都不能相同,如果相同会报错。

适用范围:网站并没有大量插入的操作。(例如:同一时段并没有大量的人在注册)

DAO层中添加init函数使用索引:

function init() {// 对数据库进行一个初始化_connectDB(function (err, db) {if (err) {console.log(err);return;}// 建立索引db.collection('users').createIndex({ 'username': 1 },null,function (err, results) {if (err) {console.log(err);return;}console.log('索引建立成功');});});
}

Node_MongoDB相关推荐

  1. nodejs(1)---mongodb

    1.Mongodb一般安装: http://www.cnblogs.com/lzrabbit/p/3682510.html 2.nodejs-mongodb: http://www.cnblogs.c ...

  2. node+express+mongodb初体验

    从去年11月份到现在,一直想去学习nodejs,在这段时间体验了gulp.grunt.yeomen,fis,但是对于nodejs深入的去学习,去开发项目总是断断续续. 今天花了一天的时间,去了解整理整 ...

最新文章

  1. 博客入驻阿里“云栖社区”
  2. 通信保障:世博会看不到的展品
  3. python3爬虫实例-python3爬虫实例(采集淘宝商品数据)
  4. pcb二次钻孔_线路板中的二次孔是什么?线路板钻孔有哪些常见问题?
  5. 推荐一个一分钟就可以搭建好的静态文件服务器,基于nodejs
  6. onenote快捷键_高效飞快地使用onenote快捷键:快捷键功能架构解析
  7. html 经常会用到的英语名词
  8. nginx rewrite php参数,Nginx泛域名解析及Rewrite重定向普通页面及带参数的页面
  9. DLAN 连接和使用体验——Twonky
  10. iphone 模拟滑动_如何在iPhone或iPad上滑动输入
  11. 【力扣题解】分式化简
  12. MarkDownPad2实用教程及MarkDown常用语法
  13. 再见!杭州!再见!阿里巴巴
  14. java访问服务器中的文件,java 访问远程服务器文件
  15. 码元、码元速率、波特率、比特率理解
  16. 软考中级怎么选?如何备考?
  17. Centos7系或中标麒麟ifconfig/ip addr无法显示ip地址的详细解决方法
  18. 服务器设计系列 网络模型,网络服务器的结构模型
  19. 每日一题----空瓶子喝可乐问题
  20. 基于JAVA高校学生综合素质测评系统计算机毕业设计源码+数据库+lw文档+系统+部署

热门文章

  1. m_Orchestrate learning system---六、善用组件插件的好处是什么
  2. Linux协议栈(7)——网络层实现
  3. 哥本哈根能效中心:阿里云用清洁的计算能力改变世界
  4. 【递推DP】POJ1163The Triangle
  5. NYOJ(21),BFS,三个水杯
  6. String类中toCharArray()方法的用法
  7. sublime快捷键整理
  8. HTML5 Web 客户端五种离线存储方式汇总
  9. DedeCms织梦发布文章时输入Tag标签逗号自动变成英文标点的方法
  10. 硬盘FAT32转NTFN格式的命令