资讯专栏INFORMATION COLUMN

Node_MongoDB

leejan97 / 3517人阅读

摘要:数据库的命名应该遵守操作系统的文件命名规范。使用命令检查当前选定的数据库。假如,第一个是,每页条,所以当前页的查询语句数据总数在中,找寻数据总数获得总数需要向上取整。常用于版本校验。建立索引表示的是正向。损失的插入的时间。

基本使用 概念

SQL和NoSQL

文档 Document

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

每个文档必须有一个特殊的键 _id, 这个键在集合中必须是保证唯一性.

文档中键的命名,不能含有.$

文档中值的额类型,比原生JavaScript更多, 比如:日期,ObjectId(),正则表达式

文档是给用户看的,是JSON的表示模式,但实际存储的时候,是BSON方式(用二进制方式存储)

集合 Collections

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

数据库 DataBase

数据库中存储众多的集合

数据库最终会变成文件系统里的文件,而数据库名字就是相应的文件名。数据库的命名应该遵守操作系统的文件命名规范。

数据库命名不能是admin,local,config

mongod

mongo 使用数据库

mongod 开机

mongoimport 导入数据

</>复制代码

  1. mongod --dbpath c:mongodata
  2. // --dbpath 参数,表示数据库的存放位置,文件夹必须事先创建
  3. // mongoDB 有真实的物理文件,对应一个个数据库。

</>复制代码

  1. db.help(); // 在 mongodb 客户端中获得帮助

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

MongoDB数据模型

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

设计 MongoDB 模式注意问题

根据用户需求来设计模式。

如果想一起使用对象,请将这些对象合并到一个文档中,否则要将它们分开(但是要确保不需要连接)。

经常复制数据(但要有一定限度),因为与计算时间相比,硬盘空间显得非常便宜。

在写入时进行连接,而不能在读取时连接。

针对经常发生的用例来设计模式。

在模式中实现复杂的聚合。


数据库中存储众多集合。

数据库最终会变为文件系统里面的文件,而数据库名字就是相应的文件名,所以数据库的命名,应该遵守操作系统的文件名命名规范。

数据库命名不能是adminlocalconfig

基本命令行操作

列出所有数据库

</>复制代码

  1. show dbs;

使用某个数据库

</>复制代码

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

查看当前所在库

</>复制代码

  1. db

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

</>复制代码

  1. db.student.insert({"name": "xiaoming", "age": 23});
  2. //student就是所谓的集合(collections)。集合中存储着很多json(document)。
  3. //db. 一个未知的集合名字,这个集合将自动创建。
mongodb增删改查 创建数据库

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

</>复制代码

  1. use mydb

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

</>复制代码

  1. db

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

</>复制代码

  1. show dbs

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

删除数据库

</>复制代码

  1. db.dropDatabase();
  2. // 删除当前所在的数据库
导入外部数据

</>复制代码

  1. mongoimport --db test --collection restaurants --dorp --file ffffd.json
  2. // --db test 想往那个数据库中导入
  3. // --collection restaurants 想往那个集合中导入
  4. // --dorp 把集合清空 表示数据库中有默认数据,覆盖原有数据。
  5. // --file ffffd.json 使用的是哪个文件.
  6. mongoimport --db student --collection class1 --dorp --file a.json
创建集合(表)

</>复制代码

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

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

</>复制代码

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

</>复制代码

  1. db.class1.insert({"name": "ting","age": 21});
查看数据(文档)

</>复制代码

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

排序

</>复制代码

  1. db.class.find().sort({"sex": 1}); //1 升序
修改数据

</>复制代码

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

</>复制代码

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

</>复制代码

  1. // 安装 mongodb
  2. npm install mongodb
nodejs 操作 mongodb

</>复制代码

  1. // mongo db 驱动
  2. va r MongoClient = require("mongodb").MongoClient;
  3. //数据库的地址 /student 表示数据库
  4. // 假如数据库不存在,没有关系,程序会自动创建数据库
  5. var url = "mongodb://localhsot:27017/student";
  6. // 建立连接
  7. MongoClient.connect(url,function( err,db ){
  8. // db 参数就是连接上数据库 实体 所有数据库操作都建立在 实体上。
  9. if( err ){
  10. console.log("数据库连接失败");
  11. return ;
  12. }
  13. console.log("数据库成功连接");
  14. db.collection("student").insertOne({
  15. "name": "mlln",
  16. "age": 23
  17. },function( err,result ){
  18. if (err) {
  19. console.log("插入失败");
  20. return ;
  21. }
  22. console.log(result);
  23. res.send("1");
  24. db.close();
  25. });
  26. });
  27. // cmd 中查看数据 比较多 可以使用 it 查看下一页
插入数据

</>复制代码

  1. db.collection("class1").isnertOne({"name": "xiaoming", "age": 21},function( err,result ){
  2. if( err )
  3. console.log("数据插入失败");
  4. console.log("数据插入成功");
  5. });
查询数据

</>复制代码

  1. var cousor = db.collection("class1").find({});
  2. // find({}) //可以输出查询条件。find({"score.math": 70});
  3. // 遍历游标
  4. cousor.each(function( err,doc ){
  5. if( doc != null ){
  6. console.log(doc); // 输出每条记录
  7. }
  8. });
  9. var cursor = db.collection("class1").find({"score.math": {$gt: 30}});
  10. var cursor = db.collection("class1").find({ "score.math": {$gt: 20} , "score.cha": {$lt : 70}});
  11. var cursor = db.collection("class1").find({ $or: [ {"score.math": {$gt: 50}}, {"scror.cha": {$lt: 70}} ] });
  12. // 排序 // 1 正序 , -1 反序
  13. var cursor = db.collection("class1").find({}).sort({"score.math": 1});
更新

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

</>复制代码

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

修改字段中的值

</>复制代码

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

替换记录 //replaceOne();

</>复制代码

  1. db.collection("class1").replaceOne({"name": "mlln"}, {"name": "m1", "age": 20});
删除数据

</>复制代码

  1. db.collection("class1").deleteMany({"age",25},function( err,reslut ){
  2. if( err )
  3. console.log("删除失败");
  4. console.log("数据删除成功");
  5. });
DAO层封装

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

</>复制代码

  1. // db模块封装了所有对数据库的常用操作
  2. var MongoClient = require("mongodb").MongoClient;
  3. var setting = require("../settings");
  4. // 连接数据库
  5. function _connectDB(callback) {
  6. var url = setting.dburl; // 配置文件中读取
  7. MongoClient.connect(url, function (err, db) {
  8. callback(err, db);
  9. });
  10. }
  11. // 插入数据
  12. // 往那个集合中增加,增加什么,增加之后的事情。
  13. exports.insertOne = function (collectionName, json, callback) {
  14. _connectDB(function (err, db) {
  15. if (err) {
  16. callback(err, null);
  17. db.close(); // 关闭数据库
  18. return;
  19. }
  20. db.collection(collectionName).insertOne(json, function (err, result) {
  21. callback(err, result);
  22. db.close(); // 关闭数据库
  23. });
  24. });
  25. };
  26. // 查找数据
  27. // 在那个集合查找,查什么,分页设置,查完之后做什么
  28. exports.find = function (collectionName, json, args, callback) {
  29. if (arguments.length == 3) {
  30. callback = args;
  31. args = { "pageamount": 0, "page": 0 }
  32. } else if (arguments.length == 4) {
  33. } else {
  34. throw new Error("find参数是3个或者四个");
  35. }
  36. var result = [];
  37. // 应该省略的条数
  38. var skipNum = args.pageamount * args.page;
  39. // 数目限制
  40. var limitNum = args.pageamount;
  41. _connectDB(function (err, db) {
  42. var cursor = db.collection(collectionName).find(json).skip(skipNum).limit(limitNum);
  43. cursor.each(function (err, doc) {
  44. // each 遍历的时候存在问题,callback 匹配到一条,就执行一次,
  45. // callback 意义上是只执行一次,使用数组解决
  46. if (err) {
  47. callback(err, null);
  48. db.close(); // 关闭数据库
  49. return;
  50. }
  51. if (doc != null) {
  52. result.push(doc); //放入结果数组
  53. } else {
  54. // 遍历结束,没有更多文档
  55. callback(null, result);
  56. db.close(); // 关闭数据库
  57. }
  58. });
  59. });
  60. };
  61. // 删除
  62. exports.deleteMany = function (collectionName, json, callback) {
  63. _connectDB(function (err, db) {
  64. db.collection(collectionName).deleteMany(json, function (err, result) {
  65. callback(err, result);
  66. db.close(); // 关闭数据库
  67. });
  68. });
  69. };
  70. // 修改
  71. exports.updateMany = function (collectionName, json1, json2, callback) {
  72. _connectDB(function (err, db) {
  73. if (err) {
  74. callback(err, null);
  75. return false;
  76. }
  77. db.collection(collectionName).updateMany(json1, json2, function (err, result) {
  78. callback(err, result);
  79. db.close();
  80. });
  81. });
  82. };
mongoDB分页

</>复制代码

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

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

</>复制代码

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

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

</>复制代码

  1. db.student.stats().count; // 获得collections总数 // 需要向上取整。
  2. db.student.find().count();
  3. // find() ,有分页逻辑
  4. exports.find = function( collectionName,json,args,callback ){
  5. if ( arguments.length == 3 ) {
  6. callback = args;
  7. args = {"pageamount": 0, "page": 0}
  8. } else if ( arguments.length == 4 ) {
  9. } else {
  10. throw new Error("find参数是3个或者四个");
  11. return false;
  12. }
  13. // 应该省略的条数
  14. var skipNum = args.pageamount * args.page;
  15. //数目限制
  16. var limitNum = args.pageamount;
  17. _connectDB(function ( err,db ) {
  18. var cursor = db.collection(collectionName).find(json).skip(skipNum).limit(limitNum);
  19. cursor.each(function ( err,doc ) {
  20. // each 遍历的时候存在问题,callback 匹配到一条,就执行一次,
  21. // callback 意义上是只执行一次,使用数组解决
  22. if ( err ) {
  23. callback(err,null);
  24. return ;
  25. }
  26. if ( doc != null ) {
  27. result.push( doc ); //放入结果数组
  28. } else {
  29. //遍历结束,没有更多文档
  30. callback(null,result);
  31. }
  32. });
  33. });
  34. };
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使用

</>复制代码

  1. var express = require("express");
  2. var cookieParser = require("cookie-parser");
  3. var app = express();
  4. app.use(cookieParser());
  5. app.get("/",function ( req,res ) {
  6. // maxAge 在express 是以毫秒为单位
  7. res.cookie("xihao","tfboys",{
  8. "maxAge": 9000,
  9. httpOnly: true
  10. });
  11. res.send(req.cookies);
  12. });
  13. app.listen(80);
猜你喜欢

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

</>复制代码

  1. var express = require("express");
  2. var cookieParser = require("cookie-parser");
  3. var app = express();
  4. app.use(cookieParser());
  5. app.get("/",function ( req,res ) {
  6. // maxAge 在express 是以毫秒为单位
  7. res.send("猜你喜欢" + req.cookies.mudidi );
  8. });
  9. app.get("/gonglve",function ( req,res ) {
  10. var mudidi = req.query.mudidi;
  11. //记录用户的喜好
  12. //读取用户的喜好,然后把新的数据push设置新的数据
  13. var mudidiArr = req.cookies.mudidi || [];
  14. mudidiArr.push( mudidi );
  15. res.cookie("mudidi",mudidiArr,{
  16. "maxAge": 9000,
  17. httpOnly: true
  18. });
  19. res.send(mudidi + "旅游攻略");
  20. });
  21. app.listen(80);
session

需要express-session中间件支持

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

</>复制代码

  1. var express = require("express");
  2. var app = express();
  3. var session = require("express-session");
  4. app.use(session({
  5. secret: "keyboard cat",
  6. resave: false,
  7. saveUninitialized: true,
  8. cookie: { secure: true }
  9. }));
  10. app.get("/",function( req,res ){
  11. if ( req.session.login == "1" ) {
  12. res.send( "欢迎"+ req.session.username +"的登陆" );
  13. } else {
  14. res.send("没有成功登陆");
  15. }
  16. });
  17. app.get("/login",function ( req,res ) {
  18. req.session.login = "1";
  19. req.session.username = "mlln";
  20. res.send("你已经成功登陆");
  21. });
  22. app.listen(80)
加密

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

不管加密的文字,多长多短,永远都是32位英语字母、数字混合。

那怕只改一个字,密文都会大变。

MD5没有反函数的可能。 网上的破解工具,都是字典模式,通过列出明-密对应的字典找到明码。

MD5常用于版本校验。可以比对两个文件、软件是否完全一致。

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

</>复制代码

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

</>复制代码

  1. console.log( md52( md52("123123").slice(11,7) + md52("123123") ) );
  2. function md52( mingma ) {
  3. var md5 = crypto.createHash("md5");
  4. var password = md5.update(mingma).digest("base64");
  5. return password;
  6. }
GM图像 gm软件

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

nodejs缩略图制作

</>复制代码

  1. var fs = require("fs");
  2. var gm = require("gm");
  3. gm("./axin.jpg")
  4. .resize(50, 50,"!")
  5. .write("./axin.jpg", function (err) {
  6. if (err) {
  7. console.log(err);
  8. }
  9. });
nodejs头像裁切

</>复制代码

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

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

查看检索的过程

</>复制代码

  1. db.student.find({"name": "username33"}).explain();
  2. // 过程显示
  3. {
  4. "cursor" : "BasicCursor",
  5. "isMultiKey" : false,
  6. "n" : 2,
  7. "nscannedObjects" : 19999,
  8. "nscanned" : 19999,
  9. "nscannedObjectsAllPlans" : 19999,
  10. "nscannedAllPlans" : 19999,
  11. "scanAndOrder" : false,
  12. "indexOnly" : false,
  13. "nYields" : 0,
  14. "nChunkSkips" : 0,
  15. "millis" : 16,
  16. "indexBounds" : {
  17. },
  18. "server" : "YOS-01409231922:27017"
  19. }

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

建立索引:

</>复制代码

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

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

复合索引

</>复制代码

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

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

</>复制代码

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

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

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

</>复制代码

  1. function init() {
  2. // 对数据库进行一个初始化
  3. _connectDB(function (err, db) {
  4. if (err) {
  5. console.log(err);
  6. return;
  7. }
  8. // 建立索引
  9. db.collection("users").createIndex(
  10. { "username": 1 },
  11. null,
  12. function (err, results) {
  13. if (err) {
  14. console.log(err);
  15. return;
  16. }
  17. console.log("索引建立成功");
  18. }
  19. );
  20. });
  21. }

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/18857.html

相关文章

  • Node_MongoDB

    摘要:数据库的命名应该遵守操作系统的文件命名规范。使用命令检查当前选定的数据库。假如,第一个是,每页条,所以当前页的查询语句数据总数在中,找寻数据总数获得总数需要向上取整。常用于版本校验。建立索引表示的是正向。损失的插入的时间。 基本使用 概念 SQL和NoSQL showImg(https://segmentfault.com/img/bVzh2M?w=582&h=469); 文档 Doc...

    cucumber 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<