目录:
1 | 1. MongoDB介绍 |
1.mongodb介绍
开源,高性能的NoSQL数据库;支持索引、集群、复制和故障转移、各种语言的驱动程序;高伸缩性;
2. mongodb本地安装
官方安装说明: http://docs.mongodb.org/manual/tutorial/install-mongodb-on-windows/
安装成功后启动:
我本地是:mongod –dbpath “f:\data\db”
MongoDB默认端口是27017;
3. mongodb本地操作
成功启动MongoDB后,再打开一个命令行窗口输入mongo,就可以进行数据库的一些操作
a. 库操作
新建数据库:第一步:use 新建数据库名;第二步:进行此库相关的操作;如果不进行第二步,该数据库不会被创建
- 查看数据库:show dbs;
- 新建表:db.createCollection(‘要新建的表名’);
- 查看当前数据库下表: show collections;
- 删除当前数据库指定表:db.表名.drop();
- 删除当前数据库:db.dropDatabase();
提示:
- 默认为存在“admin”和“local”两个数据库;admin数据库是存放管理员信息的数据库,认证会用到;local是存放replication相关的数据;这两处本篇都没有涉及到;
- find();是个查询操作,后面会讲到,上面用到主要是为了演示use不存在的库后,进行相关操作会创建出这个库;
- MongoDB没有像MySQL或MSSQL等数据库这么严格的规定,不是非得要先建库、建表、建各种字段,以后的操作中慢慢的会体会到^_^!
b. 表操作
1. 插入
方法一:db.表名.insert(数据);
- 没有去创建新表,其实通过插入操作也会自动创建
- _id,是mongodb自已生成的,每行数据都会存在,默认是ObjectId,可以在插入数据时插入这个键的值(支持mongodb支持的所有数据类型)
方法二:db.表名.save(数据);
- save也可达到insert一样的插入效果
- _id可以自已插入
- 一个表中不一定要字段都相同
那它们有什么区别?
虽然insert和save方法都可以插入数据,当默认的“_id”值已存在时,调用insert方法插入会报错;而save方法不会,会更新相同的_id所在行数据的信息
2. 查询
- 查询表中所有数据:db.表名.find();
- 按条件查询(支持多条件):db.表名.find(条件);
- 查询第一条(支持条件):db.表名.findOne(条件);
- 限制数量:db.表名.find().limit(数量);
- 跳过指定数量:db.表名.find().skip(数量);
查询不止这些,还有些高级查询,自行去了解一下^_^!
3. 修改
- 前面save在_id字段已存在是就是修改操作,按指定条件修改语法如下:
- db.表名.update({“条件字段名”:”字段值”},{$set:{“要修改的字段名”:”修改后的字段值”}});
4. 删除
- db.表名.remove(条件);
5. 存储过程
1 | // 创建存储过程: |
所有存储过程都存放在db.system.js中
4. node-mongodb安装
- npm install mongodb
5. node-mongodb连接
- 创建连接对象,需要传入连接数据库的一些连接参数
1 | const mongodbClient = require('mongodb').MongoClient; |
- 关闭连接
关闭一个连接使用close();
6. node-mongodb语法和执行
a. 插入
1 | const insertData = function(collection, callback) { |
b. 查询
1 | const selectData = function(collection, callback) { |
c. 修改
1 | const updateData = function(collection, callback) { |
d: 删除
1 | var delData = function(db, callback) { |
e: 存储过程
1 | const invokeProcData = function(db, callback) { |
7. mongoose介绍和使用
一般我们不直接用MongoDB的函数来操作MongoDB数据库,针对它的进行再次封装的东西很多,且更利于编程实现,比如:mongoose、mongoskin、mongolian等等,应用性不错;
Mongoose就是一套操作MongoDB数据库的接口,且应用较多。
1. 名词解释
Schema: 一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力
Schema.Type:是由Mongoose内定的一些数据类型,基本数据类型都在其中,他也内置了一些Mongoose特有的Schema.Type。当然,你也可以自定义Schema.Type,只有满足Schema.Type的类型才能定义在Schema内。NodeJS中的基本数据类型都属于Schema.Type,另外Mongoose还定义了自己的类型
// 从官网截取过来的,举例: var ExampleSchema = new Schema({ name:String, binary:Buffer, living:Boolean, updated:Date, age:Number, mixed:Schema.Types.Mixed, //该混合类型等同于nested _id:Schema.Types.ObjectId, //主键 _fk:Schema.Types.ObjectId, //外键 array:[], arrOfString:[String], arrOfNumber:[Number], arrOfDate:[Date], arrOfBuffer:[Buffer], arrOfBoolean:[Boolean], arrOfMixed:[Schema.Types.Mixed], arrOfObjectId:[Schema.Types.ObjectId] nested:{ stuff:String, } });
- Model: 由Schema发布生成的模型,具有抽象属性和行为的数据库操作对
- Entity: 由Model创建的实体,他的操作也会影响数据库
Schema生成Model,Model创造Entity,Model和Entity都可对数据库操作造成影响,但Model比Entity更具操作性
2. node-mongoose安装
npm install mongoose
3. 连接mongoose
创建一个文件db.js:
1 | const mongoose = require('mongoose'), |
4. mongoose使用
举例,创建了一个用户登录信息表,对此数据进行增删改查
- 创建文件user.js, 创建Schema,Model
1 | const mongoose = require('./db.js'), |
上面有提到几个定义
- 索引和默认值,即 index和default
- 验证器,即
- required 非空验证
- min/max 范围验证(边值验证)
- enum/match 枚举验证/匹配验证
- validate 自定义验证规则
- 进行数据库操作
- a. 插入
1 | const User = require("./user.js"); |
- b. 修改
1 | const User = require("./user.js"); |
修改器和更新器:
为了更快进行更新的操作。在update中需要写很多选择器
1 | $inc增减修改器,只对数字有效.下面的实例: 找到 age=22的文档,修改文档的age值自增1 |
- c. 删除
1 | const User = require("./user.js"); |
另外,删除和更新的其他方法,常用方法有:
- Model.findByIdAndUpdate(id, [update], [options], [callback]) // 找到指定id记录并更新
- Model.findOneAndUpdate([conditions], [update], [options], [callback]) // 找到一条记录并更新
* Model.findByIdAndRemove(id, [options], [callback]) // 找到指定id记录并删除 - Model.findOneAndRemove(conditions, [options], [callback]) // 找到一条记录并删除
1 | const User = require("./user.js"); |
- d. 查询
查询有直接查询和链式查询,链式查询只有在执行exec方法时才执行查询,而且必须有回调
条件查询
Model.find(conditions, [fields], [options], [callback])
//fields和options是可选参数, field的值中,1为包括,0为不包括,options: 选项参数
//fields: 参数用于字段映射,默认情况下,MongoDB会返回匹配文档的所有字段,使用映射(projection)设置希望返回的字段,用于取文档字段的子集,相当于SQL中SELECT后面我们需要的字段- User.find({‘username’ : ‘zhangsn’}, {“username”: 1 ,”_id”: 0}, callback); // 输出只会有username字段,设置方法如上,1表示查询输出该字段,0表示不输出
User.find({userage: {$gte: 21, $lte: 65}}, callback); // 这表示查询年龄大于等21而且小于等于65岁
参数还有:
$or 或关系 $nor 或关系取反 $gt 大于 $gte 大于等于 $lt 小于 $lte 小于等于 $ne 不等于 $in 在多个值范围内 $nin 不在多个值范围内 $all 匹配数组中多个值 $regex 正则,用于模糊查询 $size 匹配数组大小 $maxDistance 范围查询,距离(基于LBS) $mod 取模运算 $near 邻域查询,查询附近的位置(基于LBS) $exists 字段是否存在 $elemMatch 匹配内数组内的元素 $within 范围查询(基于LBS) $box 范围查询,矩形范围(基于LBS) $center 范围醒询,圆形范围(基于LBS) $centerSphere 范围查询,球形范围(基于LBS) $slice 查询字段集合中的元素(比如从第几个之后,第N到第M个元素
- User.find({‘username’:{$regex:/m/i}}, [callback]) // 模糊查询,正则匹配有’m’的名字,且不区分大小写
数量查询
Model.count(conditions, [callback]) // res结果会输出数量,也可以传入条件做条件查询。根据id查询
Model.findById(id, [fields], [options], [callback]) // 要据ID得到数据分页查询
1 | const User = require("./user.js"); |
- e. aggregate
在MongoDB中,聚合(aggregate)主要用于进行处理数据,比如统计求和,求平均数等,并返回计算后的数据结果,这给我们带来了很多便捷之处,因为可以在读取数据的同时进行数据处理
例如:
1 | // $match用于获取年龄大于20小于或等于40记录,然后将符合条件的记录送到下一阶段$group管道操作符进行处理。 |
下面列举一些:
- $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
- $match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
- $limit:用来限制MongoDB聚合管道返回的文档数。
- $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
- $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
- $group:将集合中的文档分组,可用于统计结果。
- $sort:将输入文档排序后输出。
- $geoNear:输出接近某一地理位置的有序文档。
更多参数可以参考下方参考链接。
8. 其他
注意:
- 表”应该描述为“collection(集合)”;“行”应该描述为“文档(document)”,一个database中可以有多个collection,一个collection中又可以有多个document
- 用CMD中使用mongo.exe操作时,插入中文遇一了问题,原因是MongoDB默认编辑是utf-8,而CMD是GBK,所以在CMD窗口中执行这个命令修改编辑即可:chcp 65001
- 注意mongodb严格区分大小写,比如查询 db.tb2.find({“name”:”wilson0”})和 db.tb2.find({“Name”:”wilson0”}) 并不是用的同一字段做的条件;
参考:
mongodb: https://docs.mongodb.com/manual/reference/operator/aggregation/addFields/
mongodb查询参数: https://mongodb-documentation.readthedocs.io/en/latest/reference/operator/gt.html
mongoose: http://mongoosejs.com/docs/api.html#Aggregate
blog:
http://www.cnblogs.com/zhongweiv/p/node_mongodb.html
https://cnodejs.org/topic/504b4924e2b84515770103dd