一、mongodb的介绍
MongoDB 是一个基于分布式文件存储的数据库。
由 C++ 语言编写。
旨在为 WEB 应用提供可扩展的高性能数据存储解决方案.
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的
在高负载的情况下,添加更多的节点,可以保证服务器性能。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。
MongoDB 文档类似于 JSON 对象。
字段值可以包含其他文档,数组及文档数组。
二、关系型数据库和非关系型数据库区别
sql术语/概念 mongodb术语/概念 解释/说明
database database 数据库
table collection 数据库表/集合
row document 数据记录行/文档
column field 数据字段/域
index index 索引
table joins 表连接,mongodb不支持
primary key primary key 主键,mongdb自动将_id字段设置为主键
关系型数据库
特性:1、关系型数据库,是指采用了关系模型来组织数据的数据库;2、关系型数据库的最大特点就是事务的一致性;3、简单来说,关系模型指的就是二维表格模型,而一个关系型数据库就是由二维表及其之间的联系所组成的一个数据组织。
优点:1、容易理解:二维表结构是非常贴近逻辑世界一个概念,关系模型相对网状、层次等其他模型来说更容易理解;2、使用方便:通用的SQL语言使得操作关系型数据库非常方便;3、易于维护:丰富的完整性(实体完整性、参照完整性和用户定义的完整性)大大减低了数据冗余和数据不一致的概率;4、支持SQL,可用于复杂的查询。
缺点:1、为了维护一致性所付出的巨大代价就是其读写性能比较差;2、固定的表结构;3、高并发读写需求;4、海量数据的高效率读写;
非关系型数据库
特性:1、使用键值对存储数据;2、分布式;3、一般不支持ACID特性;4、非关系型数据库严格上不是一种数据库,应该是一种数据结构化存储方法的集合。
优点:1、无需经过sql层的解析,读写性能很高;2、基于键值对,数据没有耦合性,容易扩展;3、存储数据的格式:nosql的存储格式是key,value形式、文档形式、图片形式等等,而关系型数据库则只支持基础类型。
缺点:1、不提供sql支持,学习和使用成本较高;2、无事务处理,附加功能和报表等支持也不好。
三、 Mongodb命令行的操作
D盘mongodb文件夹内解压下载好的mongodb文件
D盘根目录下创建一个文件夹data,在data内部再创建一个文件夹db
进入到mongodb的bin目录
按住shift,点击鼠标的右键,打开命令行窗口,输入如下指令打开数据库连接池
mongod --dbpath d:\data\db
再在此目录中,按住shift,点击鼠标的右键,打开命令行窗口,输入如下指令打开一个连接数据库的客户端,不要关闭上一个窗口
mongo
如果这样丛不成功,说明是管理员权限的问题,那就需要多走几步路
以管理员身份运行命令行窗口打开数据库连接池
d:
cd mongodb (注意文件夹的名称不要出现中文)
cd mongodb-win32-x86_64-2008plus-ssl-4.0.9
cd bin
mongod --dbpath d:\data\db
以管理员身份运行命令行窗口打开客户端
d:
cd mongodb (注意你自己的文件夹的名称)
cd mongodb-win32-x86_64-2008plus-ssl-4.0.9
cd bin
mongo
四、数据库常用命令
4.1 help查看命令提示
help
db.help()
db.test.help()
db.test.find().help()
4.2 创建切换数据库
db // test
use project // switched to db project
db // project
4.3 查询数据库
这时你会发现明明已经创建了数据库project,但是查询不出来,是因为现在你的数据库是空的,admin和local数据库是系统默认的数据库
show dbs
/**
admin
local
*/
4.4 显示当前DB状态
db.stats()
/**
{
"db" : "project",
"collections" : 0,
"views" : 0,
"objects" : 0,
"avgObjSize" : 0,
"dataSize" : 0,
"storageSize" : 0,
"numExtents" : 0,
"indexes" : 0,
"indexSize" : 0,
"fileSize" : 0,
"ok" : 1
}
*/
4.5 查看当前DB版本
db.version()
/*
4.0.9
*/
4.6 查看当前DB的链接机器地址
db.getMongo() // connection to 127.0.0.1:27017
4.7 删除数据库(删库跑路 慎用!!!)
虽然数据库删除成功,但是通过db还是可以访问到
> db
project
> db.dropDatabase()
{ "ok" : 1 }
> db
project
4.8 查询当前所使用的数据库
> db.getName()
project
五、collection 聚集集合操作
5.1 创建一个聚集集合
db.createCollection(name, options)
db.createCollection("collName", {size: 20, capped: true, max: 100});
参数说明:
字段 类型 描述
capped 布尔(可选) 如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。当该值为 true 时,必须指定 size 参数。
autoIndexId 布尔(可选) 如为 true,自动在 _id 字段创建索引。默认为 false。
size 数值(可选) 为固定集合指定一个最大值(以字节计)。如果 capped 为 true,也需要指定该字段。
max 数值(可选) 指定固定集合中包含文档的最大数量。
5.1.1 创建一个集合course
> db.createCollection("course")
{ "ok" : 1 }
> show dbs
admin 0.000GB
local 0.000GB
project 0.000GB // 因为现在数据库不再是空的了,所以现在可以查询到了
5.2 得到指定名称的聚集集合
> db.getCollection('course')
project.course
5.3 得到当前DB的所有的聚集集合
> db.createCollection("users")
{ "ok" : 1 }
> db.getCollectionNames()
[ "course", "users" ]
5.4 显示当前db所有集合的状态
db.printCollectionStats();
六、document文档操作(增删改查)
6.1 插入文档
MongoDB 使用 insert() 或 save() 方法向集合中插入文档,语法如下:
db.COLLECTION_NAME.insert(document)
db.collection.insertOne(document) // 向指定集合中插入一条文档数据
db.collection.insertMany(document) // 向指定集合中插入多条文档数据
> db.course.insert({
week1: 'node',
week2: 'vue基础',
week3: 'vue应用',
week4: 'vue高级应用',
})
WriteResult({ "nInserted" : 1 })
db.users.insertOne({
username: '张三',
password: '123456',
age: 18,
tel: '18655558888',
sex: '男'
})
{
"acknowledged" : true,
"insertedId" : ObjectId("5cda35212f11bdac31760139")
}
db.users.insertMany([{
username: '李四',
password: '123',
age: 25,
tel: '18455556666',
sex: '男'
},{
username: '王五',
password: '456',
age: 16,
tel: '15533336666',
sex: '女'
}])
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("5cda36372f11bdac3176013a"),
ObjectId("5cda36372f11bdac3176013b")
]
}
插入文档你也可以使用 db.col.save(document) 命令。如果不指定 _id 字段 save() 方法类似于 insert() 方法。如果指定 _id 字段,则会更新该 _id 的数据。
6.2 查询数据
db.course.find() // 使用 pretty() 方法以格式化的方式来显示所有文档
{
"_id" : ObjectId("5cda34232f11bdac31760138"),
"week1" : "node",
"week2" : "vue基础",
"week3" : "vue应用",
"week4" : "vue高级应用",
}
db.course.find().pretty()
{
"_id" : ObjectId("5cda34232f11bdac31760138"),
"week1" : "node",
"week2" : "vue基础",
"week3" : "vue应用",
"week4" : "vue高级应用",
}
> db.users.find().pretty()
{
"_id" : ObjectId("5cda35212f11bdac31760139"),
username: '张三',
password: '123456',
age: 18,
tel: '18655558888',
sex: '男'
}
{
"_id" : ObjectId("5cda36372f11bdac3176013a"),
username: '李四',
password: '123',
age: 25,
tel: '18455556666',
sex: '男'
}
{
"_id" : ObjectId("5cda36372f11bdac3176013b"),
username: '王五',
password: '456',
age: 16,
tel: '15533336666',
sex: '女'
}
6.3 删除数据
db.users.deleteOne({password: '123'})
{ "acknowledged" : true, "deletedCount" : 1 }
db.users.find().pretty()
{
"_id" : ObjectId("5cda35212f11bdac31760139"),
username: '张三',
password: '123456',
age: 18,
tel: '18655558888',
sex: '男'
}
{
"_id" : ObjectId("5cda36372f11bdac3176013b"),
username: '王五',
password: '456',
age: 16,
tel: '15533336666',
sex: '女
}
> db.users.deleteMany({})
{ "acknowledged" : true, "deletedCount" : 2 }
> db.users.find().pretty()
6.4 修改数据
参照 6.1步骤,新添加了3条记录给users集合
db.col.updateOne({key: value}, {$set: {key: value}})
db.col.updateMany({key: value}, {$set: {key: value}})
db.col.updateOne({key: value}, { $inc: {key: num}}) 修改某一条数据的某一个字段key的自增num
db.users.updateOne({username: '张三'}, {
$set: {
password: 'abcd'
}
})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.users.find().pretty() })
{
"_id" : ObjectId("5cda5fda2f11bdac3176013c"),
"username" : "张三",
"password" : "abcd",
"age" : 18,
"tel" : "18655558888",
"sex" : "男"
}
{
"_id" : ObjectId("5cda5fe32f11bdac3176013d"),
"username" : "李四",
"password" : "123",
"age" : 25,
"tel" : "18455556666",
"sex" : "男"
}
{
"_id" : ObjectId("5cda5fe32f11bdac3176013e"),
"username" : "王五",
"password" : "456",
"age" : 16,
"tel" : "15533336666",
"sex" : "女"
}
db.users.updateMany({}, {
$set: {
lesson: '3',
city: '上海'
}
})
{ "acknowledged" : true, "matchedCount" : 3, "modifiedCount" : 3 }
db.users.find().pretty() } })
{
"_id" : ObjectId("5cda5fda2f11bdac3176013c"),
"username" : "张三",
"password" : "abcd",
"age" : 18,
"tel" : "18655558888",
"sex" : "男",
"lesson" : "3",
"city" : "上海"
}
{
"_id" : ObjectId("5cda5fe32f11bdac3176013d"),
"username" : "李四",
"password" : "123",
"age" : 25,
"tel" : "18455556666",
"sex" : "男",
"lesson" : "3",
"city" : "上海"
}
{
"_id" : ObjectId("5cda5fe32f11bdac3176013e"),
"username" : "王五",
"password" : "456",
"age" : 16,
"tel" : "15533336666",
"sex" : "女",
"lesson" : "3",
"city" : "上海"
}
db.users.updateOne({username: '张三'}, {
$inc: {
age: 1
}
})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.users.find().pretty() }})
{
"_id" : ObjectId("5cda5fda2f11bdac3176013c"),
"username" : "张三",
"password" : "abcd",
"age" : 19,
"tel" : "18655558888",
"sex" : "男",
"lesson" : "3",
"city" : "上海"
}
{
"_id" : ObjectId("5cda5fe32f11bdac3176013d"),
"username" : "李四",
"password" : "123",
"age" : 25,
"tel" : "18455556666",
"sex" : "男",
"lesson" : "3",
"city" : "上海"
}
{
"_id" : ObjectId("5cda5fe32f11bdac3176013e"),
"username" : "王五",
"password" : "456",
"age" : 16,
"tel" : "15533336666",
"sex" : "女",
"lesson" : "3",
"city" : "上海"
}
> db.users.updateMany({}, {
$inc: {
age: 1
}
})
{ "acknowledged" : true, "matchedCount" : 3, "modifiedCount" : 3 }
db.users.find().pretty()
{
"_id" : ObjectId("5cda5fda2f11bdac3176013c"),
"username" : "张三",
"password" : "abcd",
"age" : 20,
"tel" : "18655558888",
"sex" : "男",
"lesson" : "3",
"city" : "上海"
}
{
"_id" : ObjectId("5cda5fe32f11bdac3176013d"),
"username" : "李四",
"password" : "123",
"age" : 26,
"tel" : "18455556666",
"sex" : "男",
"lesson" : "3",
"city" : "上海"
}
{
"_id" : ObjectId("5cda5fe32f11bdac3176013e"),
"username" : "王五",
"password" : "456",
"age" : 17,
"tel" : "15533336666",
"sex" : "女",
"lesson" : "3",
"city" : "上海"
}
6.4 查询数据
db.users.find({},{}).pretty() // 查询所有的数据,显示所有的字段
{
"_id" : ObjectId("5cda5fda2f11bdac3176013c"),
"username" : "张三",
"password" : "abcd",
"age" : 20,
"tel" : "18655558888",
"sex" : "男",
"lesson" : "3",
"city" : "上海"
}
{
"_id" : ObjectId("5cda5fe32f11bdac3176013d"),
"username" : "李四",
"password" : "123",
"age" : 26,
"tel" : "18455556666",
"sex" : "男",
"lesson" : "3",
"city" : "上海"
}
{
"_id" : ObjectId("5cda5fe32f11bdac3176013e"),
"username" : "王五",
"password" : "456",
"age" : 17,
"tel" : "15533336666",
"sex" : "女",
"lesson" : "3",
"city" : "上海"
}
db.users.find({},{_id: 0}).pretty() // 不显示_id字段
{
"username" : "张三",
"password" : "abcd",
"age" : 20,
"tel" : "18655558888",
"sex" : "男",
"lesson" : "3",
"city" : "上海"
}
{
"username" : "李四",
"password" : "123",
"age" : 26,
"tel" : "18455556666",
"sex" : "男",
"lesson" : "3",
"city" : "上海"
}
{
"username" : "王五",
"password" : "456",
"age" : 17,
"tel" : "15533336666",
"sex" : "女",
"lesson" : "3",
"city" : "上海"
}
db.users.find({},{_id: 0, username: 1}).pretty() // 不显示_id字段,只显示username字段'
{ "username" : "张三" }
{ "username" : "李四" }
{ "username" : "王五" }
db.users.find({},{_id: 0, username: 1, age: 1}).pretty() // 不显示_id字段,显示username字段'和age字段
{ "username" : "张三", "age" : 20 }
{ "username" : "李四", "age" : 26 }
{ "username" : "王五", "age" : 17 }
db.users.find({username: '张三'},{_id: 0}).pretty()
{
"username" : "张三",
"password" : "abcd",
"age" : 20,
"tel" : "18655558888",
"sex" : "男",
"lesson" : "3",
"city" : "上海"
}
db.users.find({lesson: '3'},{_id: 0}).pretty()
{
"username" : "张三",
"password" : "abcd",
"age" : 20,
"tel" : "18655558888",
"sex" : "男",
"lesson" : "3",
"city" : "上海"
}
{
"username" : "李四",
"password" : "123",
"age" : 26,
"tel" : "18455556666",
"sex" : "男",
"lesson" : "3",
"city" : "上海"
}
{
"username" : "王五",
"password" : "456",
"age" : 17,
"tel" : "15533336666",
"sex" : "女",
"lesson" : "3",
"city" : "上海"
}
(登录时可以用邮箱、账户民、手机号登录)
db.users.find({
$or: [
{password: '123'},
{password: '456'}
]
}, {_id: 0}).pretty()
{
"username" : "李四",
"password" : "123",
"age" : 26,
"tel" : "18455556666",
"sex" : "男",
"lesson" : "3",
"city" : "上海"
}
{
"username" : "王五",
"password" : "456",
"age" : 17,
"tel" : "15533336666",
"sex" : "女",
"lesson" : "3",
"city" : "上海"
}
查询年龄在24岁以上的数据用 gt, 大于等于用gte
db.users.find({age: {$gt: 24} }, {_id:0}).pretty()
{
"username" : "李四",
"password" : "123",
"age" : 26,
"tel" : "18455556666",
"sex" : "男",
"lesson" : "3",
"city" : "上海"
}
查询年龄在24岁以下的数据用 lt, 小于等于用lte
db.users.find({age: {$lt: 24} }, {_id:0}).pretty()
{
"username" : "张三",
"password" : "abcd",
"age" : 20,
"tel" : "18655558888",
"sex" : "男",
"lesson" : "3",
"city" : "上海"
}
{
"username" : "王五",
"password" : "456",
"age" : 17,
"tel" : "15533336666",
"sex" : "女",
"lesson" : "3",
"city" : "上海"
}
查询18-20之间的数据(查询价格500-1000之间的产品)
db.users.find({age: { $gte: 18, $lte: 20}}, {_id:0}).pretty()
{
"username" : "张三",
"password" : "abcd",
"age" : 20,
"tel" : "18655558888",
"sex" : "男",
"lesson" : "3",
"city" : "上海"
}
按照年龄排序 .sort({key:num}) num为1表示按照key值升序,为-1表示降序
db.users.find({}, {_id: 0}).sort({age: 1}).pretty()
{
"username" : "王五",
"password" : "456",
"age" : 17,
"tel" : "15533336666",
"sex" : "女",
"lesson" : "3",
"city" : "上海"
}
{
"username" : "张三",
"password" : "abcd",
"age" : 20,
"tel" : "18655558888",
"sex" : "男",
"lesson" : "3",
"city" : "上海"
}
{
"username" : "李四",
"password" : "123",
"age" : 26,
"tel" : "18455556666",
"sex" : "男",
"lesson" : "3",
"city" : "上海"
}
查询数据并且计数 .count()
db.users.find({}, {_id: 0}).count() // 3
db.users.find({age: { $gte: 18, $lte: 20}}, {_id:0}).count() // 1
模糊查询 ---- 搜索框搜索产品
db.users.find({username:'三'}, {_id:0}).pretty() // 精确查询,没有数据
db.users.find({username: /三/}, {_id:0}).pretty()
{
"username" : "张三",
"password" : "abcd",
"age" : 20,
"tel" : "18655558888",
"sex" : "男",
"lesson" : "3",
"city" : "上海"
}
查询名字中含有三 或者 含有四的 *
db.users.find({ $or: [{username: /三/}, {username: /四/}]}, {_id:0}).pretty()
{
"username" : "张三",
"password" : "abcd",
"age" : 20,
"tel" : "18813007814",
"sex" : "男",
"lesson" : "3",
"city" : "上海"
}
{
"username" : "李四",
"password" : "123",
"age" : 26,
"tel" : "18455556666",
"sex" : "男",
"lesson" : "3",
"city" : "上海"
}
七、nodejs结合Mongodb
7.1 mongoose的安装(这里使用的是淘宝镜像)
cnpm i mongoose -S
-S --save
-D --save-dev
7.2 连接数据库
新建一个db.js文件
const mongoose = require('mongoose');
const DB_URL = 'mongodb://127.0.0.1:27017/sh1902';
mongoose.connect(DB_URL, { useNewUrlParser: true });
mongoose.connection.on('connected', () => {
console.log('数据库已经连接成功');
});
mongoose.connection.on('disconnected', () => {
console.log('数据库连接失败');
});
mongoose.connection.on('error', () => {
console.log('数据库连接异常');
});
首先确保数据库连接池是打开的,如果未打开,请参照2.2.1步骤,然后运行 node db.js 指令,发现打印出了 ‘数据库已经连接成功’ 字样
此时数据库连接已经搞定,接下来就是去处理后续的业务逻辑,按照模块化的开发思想,需要将db.js连接数据库的文件暴露出去 ----- 自定义模块
const mongoose = require('mongoose');
const DB_URL = 'mongodb://127.0.0.1:27017/sh1902';
mongoose.connect(DB_URL, { useNewUrlParser: true });
mongoose.connection.on('connected', () => {
console.log('数据库已经连接成功');
});
mongoose.connection.on('disconnected', () => {
console.log('数据库连接失败');
});
mongoose.connection.on('error', () => {
console.log('数据库连接异常');
});
module.exports = mongoose;
7.3 设计用户数据表 --- 暴露数据模型,并且在数据库中创建集合
mongoose.model('User', UserSchema); 就会创建users集合
mongoose.model('Product',ProductSchema); 就会创建products集合
mongoose.model('MyBanner', BannerSchema); 就会创建mybanners集合
const mongoose = require('./db.js');
const Schema = mongoose.Schema;
const UserSchema = new Schema({
username: { type: String },
password: { type: String },
age: { type: Number },
tel: { type: String },
sex: { type: String },
lesson: { type: String },
city: { type: String }
});
// 执行时 会在数据库中创建users集合
module.exports = mongoose.model('User', UserSchema);
const mongoose = require('./db.js');
const Schema = mongoose.Schema;
const ProductSchema = new Schema({
title: { type: String }
});
// 执行时 会在数据库中创建products集合
module.exports = mongoose.model('Product', ProductSchema);
const mongoose = require('./db.js');
const Schema = mongoose.Schema;
const BannerSchema = new Schema({
img: { type: String }
});
// 执行时 会在数据库中创建mybanners集合
module.exports = mongoose.model('MyBanner', BannerSchema);
7.4 增删改查操作
7.4.1 增
// 插入用户
const User = require('./Users');
const user = new User({
username: '张三',
password: '123',
age: 22,
tel: '13248099856',
sex: '男',
lesson: '3',
city: '山西'
})
user.save((err) => {
if (err) throw err;
console.log('用户插入成功')
})
// 插入产品
const Product = require('./pp')
const prouct = new Product({
title: '方便面'
})
prouct.save((err) => {
if (err) throw err;
console.log('产品插入成功')
})
// 插入轮播图
const My = require('./banner');
const ban = new My({
img: 'https://www.baidu.com'
})
ban.save((err) => {
if (err) throw err;
console.log('轮播图插入成功')
})
7.4.2 删除数据
User.deleteOne({key:value}, err => {})
新建delete.js
const User = require('./users');
// User.deleteOne({username: '张三'}, err => {
// if (err) throw err;
// console.log('删除成功')
// })
// style.display = 'flex' <==> style['display'] = 'flex'
User['deleteOne']({username: '张三'}, err => {
if (err) throw err;
console.log('删除成功')
})
7.4.3 修改数据
User.updateOne({key, value}, {$set: {}}, err => {}) // $inc
新建update.js
const User = require('./users');
User.updateOne({username: '张三'}, {$set: {age: 20}}, err => {
if (err) throw err;
console.log('修改成功')
})
User.updateMany({}, {$set: {age: '25'}}, err => {
if (err) throw err;
console.log('修改成功')
})
7.4.4 查询数据的另一种写法
User.find({},{},(err,data) => {})
User.find({},{}).exec((err, data) => {})
const User = require('./users');
// User.find({}, {_id: 0, __v: 0}, (err, data) => {
// if (err) throw err;
// console.log(data)
// })
// User.find({}, {_id: 0, __v: 0}).exec((err, data) => {
// if (err) throw err;
// console.log(data)
// })
User.find({}, {_id: 0, __v: 0}).sort({age: 1}).exec((err, data) => {
if (err) throw err;
console.log(data)
})