1、mongodb 数据库
MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。
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字段设置为主键 |
mongodb的使用
1.打开mongodb目录,进入到bin目录,我的在 D:\mongodb\mongodb-win32-x86_64-2008plus-ssl-4.0.9\bin
2 创建数据库存放目录
在任意一个盘的根目录下创建一个data文件夹,文件夹内部创建一个文件夹db,我的在f:\data\db
3 在mongodb的bin目录下打开命令行窗口 ---- 打开数据库的连接池
(shift + 右键),输入如下指令
mongod --dbpath f:\data\db
如果出现 waiting for connections on port 27017 表示成功
- 如果不成功,输入以下指令
./mongod --dbpath d:\data\db
- 如果还不成功,如果报不是内部或者外部命令,说明权限问题
4 在mongodb的bin目录下打开命令行的数据库连接终端
(shift + 右键),输入如下指令,切忌关闭上一个窗口(切记不要关闭上一个窗口)
mongo
如果出现 > 表示成功
- 如果不成功,输入以下指令
./mongo
- 如果还不成功,如果报不是内部或者外部命令,说明权限问题
数据库常用命令
查看帮助文档
help // 帮助文档
db.help() // 数据库帮助文档
db.test.help() // 数据库集合帮助文档
db.test.find().help() // 数据库集合查询帮助文档
创建 或者 切换数据库
db
// 默认数据库
test
use demo
// 有则切换到demo ,无则创建并且切换到demo
switched to db demo
查询数据库
db
// 显示当前的数据库
demo
show dbs
// 显示当前所有的数据库
admin 0.000GB
local 0.000GB
已经创建了demo 的数据库,但是查询时并没有,因为当前的数据库为空
4.4 显示当前DB状态,链接机器地址,版本
db.stats()
// 当前数据库的状态
{
"db" : "demo ", // 数据库
"collections" : 0, // 集合
"views" : 0,
"objects" : 0,
"avgObjSize" : 0,
"dataSize" : 0,
"storageSize" : 0,
"numExtents" : 0,
"indexes" : 0,
"indexSize" : 0,
"fileSize" : 0,
"ok" : 1
}
db.getMongo()
// 链接机器地址
connection to 127.0.0.1:27017
db.version()
// 当前mongodb版本
3.4.2
删除数据库
db.dropDatabase()
// 删除数据库
{ "ok" : 1 }
查询当前所使用的数据库
db
demo
db.getName()
demo
collection 聚集集合操作
创建集合( 创建数据库的表)
db.createCollection(collectionName[, {size: 20, capped: true, max: 100}])
-
collectionName 集合名称
-
[, {size: 20, capped: true, max: 100}] 可选参数,参数说明如下
字段 | 类型 | 描述 |
---|---|---|
capped | 布尔(可选) | 如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。当该值为 true 时,必须指定 size 参数。 |
autoIndexId | 布尔(可选) | 如为 true,自动在 _id 字段创建索引。默认为 false。 |
size | 数值(可选) | 为固定集合指定一个最大值(以字节计)。如果 capped 为 true,也需要指定该字段。 |
max | 数值(可选) | 指定固定集合中包含文档的最大数量。 |
创建一个用户集合
db.createCollection(‘users’)
// 创建用户集合
{ "ok" : 1 }
show dbs
admin 0.000GB
local 0.000GB
demo 0.000GB // +++++++++++++++++++++++
增删改查
1 增
db.users.insert({}) — 插入单条数据
db.users.insert([{}, {}, {}]) — 插入多条数据
db.users.insertOne({}) — 插入单条数据
db.users.insertMany([{}, {}, {}]) — 插入多条数据
插入单条数据
db.users.insertOne({ username: ‘www’, password: ‘123456’, sex: 1, age: 18, city: ‘山西’, lesson: 3})
插入多条数据
db.users.insertMany([{ username: ‘我’, password: ‘78910’, sex: 1, age: 20, city: ‘黑龙江’, lesson: 3}, { username: ‘你’, password: ‘666666’, sex: 1, age: 22, city: ‘安徽’, lesson: 3}])
// 插入多条数据
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("5dd3aca189d960132c628027"),
ObjectId("5dd3aca189d960132c628028")
]
}
插入文档你也可以使用 db.col.save(document) 命令。如果不指定 _id 字段 save() 方法类似于 insert() 方法。如果指定 _id 字段,则会更新该 _id 的数据。
2 查
基本查询语法: db.users.find()
基本查询格式化语法: db.users.find().pretty()
db.users.find() 基本查询方法 ---- 可读性差
db.users.find().pretty() 查询并且格式化代码
3 删
db.users.deleteOne({key: value}) 删除 key 为value的一条数据
db.users.deleteMany({key: value}) 删除 key 为value的多条数据
db.users.deleteMany({}) 删除 所有的 数据
db.users.deleteOne({ username: ‘www’})
db.users.find().pretty()
> db.users.deleteMany({ sex: 1 })
// 删除多条数据 — 只要条件匹配都会删除
{ “acknowledged” : true, “deletedCount” : 2 }
> db.users.find().pretty()
// 没有输出结果
> db.users.deleteMany({})
4 改
直接设置
db.users.updateOne({key: value}, { $set: { key1: value1, key2: value2…} })
db.users.updateMany({key: value}, { $set: { key1: value1, key2: value2…} })
自增自减 num为正数-自增 num为负数-自减
db.users.updateOne({key: value}, { $inc: { key1: num} })
db.users.updateMany({key: value}, { $inc: { key1: num} })
db.users.find()
db.users.updateOne({ username: ‘我’}, { $set: {password: ‘678910’}})
db.users.find()
db.users.updateMany({ lesson: 3 }, { $set: { lesson: 2 } })
db.users.find()
db.users.updateMany({}, { $inc: { age: 1 }})
// 所有的数据自增1
{ "acknowledged" : true, "matchedCount" : 3, "modifiedCount" : 3 }
db.users.find()
5 查
简单查询:db.users.find()
条件查询:db.users.find({key, value})
条件查询限制显示字段: db.uses.find({key: value}, { key1: 1, key2: 0})
db.users.find({}, { _id: 0})
db.users.find({}, { _id: 0, username: 1}) 查询所有的数据,不显示_id字段,只显示username字段
db.users.find({ sex: 1 }, { _id: 0, username: 1, sex: 1}) 查询sex为1的字段,只显示username和sex,不显示_id
6 分页查询
db.users.find({}, {}).limit(num1).skip(num2) 从第num2条数据开始(不包括num2条),查询了num1条数据
db.users.find({}, { _id: 0, username: 1})
db.users.find({}, { _id: 0, username: 1}).limit(1).skip(1) 从第1条数据开始,查询一条数据 ----- 下标是从0开始
db.users.find({}, { _id: 0, username: 1}).limit(2).skip(0) 每页显示2条数据,这里是第一页数据,下标从0开始
db.users.find({}, { _id: 0, username: 1}).limit(2).skip(2) 显示第二页数据
显示某一页数据 db.users.find({}, { _id: 0, username: 1}).limit(num).skip(index * num)num为每页个数,index为页码,页码从0开始
7 排序查询
db.users.find({}, {}).sort({ key: 1}) 升序
db.users.find({}, {}).sort({ key: -1}) 降序
db.users.find({}, { _id: 0, username: 1, age: 1}) 查询所有的数据
db.users.find({}, { _id: 0, username: 1, age: 1}).sort({ age: 1}) 升序排列
db.users.find({}, { _id: 0, username: 1, age: 1}).sort({ age: -1}) 降序排列
8 区间查询
db.users.find({key : { $lt: val1, $gt: val2 }}, {}) 查询的是key字段在val1到val2之间的数据,但是不包括val1和val2
db.users.find({key : { $lte: val1, $gte: val2 }}, {}) 查询的是key字段在val1到val2之间的数据,包括val1和val2
db.users.find({ age: { $gte: 18, $lte: 20}}, {_id: 0, username: 1, age: 1}) 查询年龄在18-20岁之间的数据,包括18和20
9 模糊查询
db.users.find({key: /value/}, {}) 查询key值中包含value的数据
db.users.find({key: /^value/}, {}) 查询key值中以value开头的数据
db.users.find({ username: /大/}, { _id: 0, username: 1}) 查询用户名中含有大的数据
db.users.find({ username: /^韦/}, { _id: 0, username: 1}) 查询用户名,以 韦 开头的数
10 或查询
db.users.find({ $or: [{key1: value1 }, { key2: value2}]}, {}) 查询key1为value1或者key2为value2的值
db.users.find({ $or: [{ username: /大/}, { city: ‘安徽’}] }, {_id: 0, username: 1, city: 1}) 查询用户名含有 大 或者 籍贯为 安徽的数据
11 获取分类
db.users.distinct(‘key’) 检索出所有的key并且去重,以数组形式返回
db.users.distinct(‘age’) 获取年龄,并且去重,以数组形式返回
nodejs结合mongodb
使用数据库,推荐使用 mongoose
1 安装mongoose
cnpm i mongoose@4.11.0 -D
2 连接数据库
创建一个文件 db.js
/**
* 连接数据库
*/
const mongoose = require('mongoose'); // 引入模块
const DB_URL = "mongodb://localhost:27017/sh1910"; // 数据库连接地址以及连接到哪
// 连接数据库
mongoose.connect(DB_URL);
// 连接成功
mongoose.connection.on('connected', () => {
console.log('connect success');
})
// 连接失败断开
mongoose.connection.on('disconnected', () => {
console.log('connect disconnected');
})
// 连接错误
mongoose.connection.on('error', () => {
console.log('connect error');
})
3 创建数据库的集合
- 先将db.js 连接数据库 暴露出来
// db.js处最底下 ---- 第一个自定义模块
module.exports = mongoose;
- 创建users.js文件,引入连接的数据库,创建用户集合 — 暴露
const mongoose = require('./db.js'); // 引入数据库连接模块
// 创建用户集合的通用对象
const Schema = mongoose.Schema;
// 说明集合需要的字段以及数据类型
const userSchema = new Schema({
userid: { type: String },
username: { type: String },
password: { type: String },
age: { type: Number },
sex: { type: Number },
city: { type: String },
lesson: { type: Number },
tel: { type: String }
})
// 创建集合并且将此集合暴露出去
// model('Test') ---- 就会生成集合为 tests
module.exports = mongoose.model('User', userSchema);
将数据的增删改查封装成模块
sql.js
/**
* 封装数据的增删改查
*/
const sql = {
insert () {},
delete () {},
update () {},
find () {}
}
module.exports = sql
1 封装增
- 封装
insert (CollectionName, insertData) {
CollectionName.insertMany(insertData, (err) => {
if (err) throw err
console.log('插入成功')
})
},
虽然显示插入成功,但是我们需要考虑的是,你由md-insert.js发起插入操作,当插入成功时,应该由md-insert.js打印插入成功 A调B,B是异步操作,B返回结果给A,A继续操作 ---- 利用Promise解决此类问题
// sql.js
insert (CollectionName, insertData) {
return new Promise((resolve, reject) => {
CollectionName.insertMany(insertData, (err) => {
if (err) {
reject() // 错误或者失败
} else {
resolve() //成功
}
})
})
},
// md-insert.js
sql.insert(User, { userid: 'user_5', username: 'w2', password: '5465165', age: 25, sex: 1, lesson: 2, city: '山西', tel: '18813007814'}).then(() => {
console.log('插入成功.....')
}).catch(() => {
console.log('插入失败.....')
})
2 封装删
// sql.js
// 默认删除单条数据,如果需要删除多条,传递参数deleteType为1
delete (CollectionName, deleteData, deleteType) {
// 只有传入的第三个参数为1 才是删除多条,否则都是删除单条
let deleteFn = deleteType === 1 ? 'deleteMany' : 'deleteOne'
return new Promise((resolve, reject) => {
// 对象obj的key值如果为变量,那么需要写成obj[key]
CollectionName[deleteFn](deleteData, (err) => {
if (err) {
reject()
} else {
resolve()
}
})
})
},
3 封装改
// sql.js
update (CollectionName, whereData, updateData, updateType) {
// 如果有第四个参数并且值为1 更新多条, 否则为更新单条
let updateFn = updateType === 1 ? 'updateMany' : 'updateOne'
return new Promise((resolve, reject) => {
CollectionName[updateFn](whereData, updateData, (err) => {
if (err) {
reject()
} else {
resolve()
}
})
})
},
4 封装查
// sql.js
find (CollectionName, whereData, showData) {
return new Promise((resolve, reject) => {
CollectionName.find(whereData, showData).exec((err, data) => {
if (err) {
reject()
} else {
resolve(data) // 需要传递查询到的数据
}
})
})
}
4 封装排序
sort(CollectionName,whereData,showData,sortDate){
return new Promise((resolve,reject)=>{
CollectionName.find(whereData,showData).sort(sortDate).exec((err,data)=>{
if(err){
reject()
}else{
resolve(data);
}
})
})
},
5.封装分页
paging(CollectionName,whereData,showData,pageCode,limitNum){
limitNum = limitNum * 1 || 10; //默认每页显示10条数据
pageCode = pageCode * 1 || 0; //默认显示第0页数据
return new Promise((resolve,reject)=>{
CollectionName.find(whereData,showData).limit(limitNum).skip(limitNum * pageCode).exec((err,data)=>{
if(err){
reject()
}else{
resolve(data)
}
})
})
},
封装分类
distinct (CollectionName,type){
return new Promise((resolve,reject)=>{
CollectionName.distinct(type).exec((err,data)=>{
if(err){
reject()
}else{
resolve(data)
}
})
})
}