MongoDB学习笔记
这次整理以下MongoDB的笔记吧。
Tips:
本文较长,加载时间可能也会比较长
推荐使用PC端查看,因为有目录
mongoDB简介
mongodb是一种介于关系型和非关系型之间的数据库,它是属于nosql数据库,而它确实最像关系型数据库的nosql数据库
mongodb都是以json来存储数据的
安装好mongoDB后还需要记得配置下环境变量
一般路径会放在C盘的program file的mongodb里,我们只需要进入到bin目录下配置即可完成
Linux安装mongoDB
由于Windows太简单了,傻瓜式操作,所以就不再过多赘述
centOS安装mongoDB5.x
这里我用的是yum换源方式安装
创建mongodb的yum源头
vim /etc/yum.repos.d/mongodb-org-5.0.repo
编辑刚刚创建的文件
[mongodb-org-5.0] name=MongoDB Repository baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/5.0/x86_64/ gpgcheck=1 enabled=1 gpgkey=https://www.mongodb.org/static/pgp/server-5.0.asc
yum安装
sudo yum install -y mongodb-org
启动mongodb
sudo systemctl start mongod
查看mongo状态
sudo systemctl status mongod
设置开机自启
sudo systemctl enable mongod
关闭mongo
sudo systemctl stop mongodb
重启
sudo systemctl restart mongodb
centOS安装mongodb文章转自:https://blog.csdn.net/DanielJackZ/article/details/124210456
树莓派(Ubuntu安装mongoDB4.x)
安装依赖包
sudo apt-get install libcurl4 openssl
关闭和卸载原有的mongodb
service mongodb stop sudo apt-get remove mongodb
导入包管理系统使用的公钥
wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -
如果命令执行结果没有显示OK,则执行此命令在把上一句重新执行:
sudo apt-get install gnupg
注册mongodb源
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list
更新源
sudo apt-get update
正式安装
sudo apt-get install -y mongodb-org=4.4.2 mongodb-org-server=4.4.2 mongodb-org-shell=4.4.2 mongodb-org-mongos=4.4.2 mongodb-org-tools=4.4.2
安装过程中如果提示: mongodb-org-tools : 依赖: mongodb-database-tools 但是它将不会被安装
终端下运行以下命令,解决:
sudo apt-get autoremove mongodb-org-mongos mongodb-org-tools mongodb-org sudo apt-get install -y mongodb-org=4.4.2
创建数据存储目录
sudo mkdir -p /data/db
修改配置,开放27017端口 ,以及开发外网链接
sudo nano /etc/mongod.conf
将bindIp改为0.0.0.0
重新加载配置,并启动mongodb
sudo systemctl daemon-reload sudo systemctl start mongod
查看运行状态
sudo systemctl status mongod
如果mongodb状态为stop,则运行:
sudo systemctl enable mongod
停止mongodb
sudo systemctl stop mongod
重启mongodb
sudo systemctl restart mongod
启动开机启动
sudo systemctl enable mongod
mongo开启认证
进入mongo
mongo
添加用户
use admin db.createUser( { user: "admin", pwd: passwordPrompt(), roles: [ { role: "userAdminAnyDatabase", db: "admin" }, { role: "readWriteAnyDatabase", db: "admin" } ] } ) # or db.createUser( { user: "root", pwd: passwordPrompt(), roles: ["root"] } ) #db.createUser({ user: "admin", pwd: "password", roles: [{ role: "userAdminAnyDatabase", db: "admin" }] }) #db.createUser({user: "root",pwd: "password", roles: [ { role: "root", db: "admin" } ]})
如果创建超级管理员请把roles部分替换为 roles:[“root”]
说明:
- pwd后跟的passwordPrompt() ,是交互式输入密码,在执行命令后会提示输入密码,这样是为了保护密码不被泄露。
- 用户名:myUserAdmin
- 角色 role:用户管理权限,读写所有数据库权限
创建用户自己的数据库的管理角色
use yourdatabase db.createUser({user: "user",pwd: "password",roles: [ { role: "dbOwner", db: "yourdatabase" } ]})
密码验证
db.auth('user', 'pwd')
若返回1则用户创建成功且密码正确
编辑开启认证
sudo nano /etc/mongod.conf
将
#security
改为
security: authorization: enabled
注意要有缩进
重启mongo
sudo systemctl restart mongod
密码连接数据库
mongo --port 27017 --authenticationDatabase \ "db" -u "uname" -p
注意:db不能是admin
删除用户–需要删除用户时使用
db.system.users.remove({user:"用户名"})
mongoDB基本操作
数据库
查看数据库
show dbs
使用数据库
use dbName
创建数据库
# 使用数据库(需要创建的数据库)
use dbName
# 给数据库中插入一条数据
db.collectionName.insert({
"name": "linfeng",
"age": 22
})
注意:
- 必须先使用不存在的数据库然后才可以插入数据来创建这个不存在的数据库
- 在插入数据时的db是固定的而不是数据库名
删除数据库
use dbName
db.dropDatabase()
集合
查看集合
show collections
新增集合
db.collectionName.find({"a": "b"})
删除集合
db.collectionName.drop()
数据
查找所有数据
db.collectionName.find()
查找指定数据
基本格式
db.collectionName.find({"你想查找的条件": "放到json中即可"})
可以理解成db.collectionName.find({你想查找的条件})
查找age=20的学生
db.collectionName.find({"age": 20})
查找age>22的学生
db.collectionName.find({"age":{$gt:22}})
这个$gt表示大于的意思
$是特殊符号
小于的话就是$lt
db.collectionName.find({"age":{$lt:22}})
查找age>=22的学生
db.collectionName.find({"age":{$gte:22}})
小于的话是$lte,这里不再展示
查找age>=20&&age<=23的学生
db.collectionName.find({
"age":{
$gte: 20
$lte: 23,
}
})
模糊查询
查询名字中有zhang的学生
db.collectionName.find({
"name": /zhang/
})
注意:这种方式只适用于数据较小时的模糊查询,比较耗费性能
查询名字中以z开头的学生
db.collectionName.find({
"name": /^z/
})
查询名字中以n结尾的学生
db.collectionName.find({
"name": /n$/
})
查询指定列(字段)
db.collectionName.find({}, {
"你需要查出的字段": 1
})
那个1不用管,固定值,记住即可
例如:查询出博客列表,只需要查询出博客文章名字即可
db.collectionName.find({}, { "title": 1 })
顺便一提,指定字段可以不加引号,而且也是可以查多个,用逗号分隔即可
db.collectionName.find({}, { title: 1, time: 1 })
排序
正序排序(升序)
例如:按照学生年龄升序给学生排序
db.collectionName.find().sort({
age: 1
})
倒序排序(降序)
例如:按照学生年龄降序给学生排序
db.collectionName.find().sort({
age: -1
})
分页查询
查询前五条数据limit
db.collectionName.find().limit(5)
跳过前五条数据skip
db.collectionName.find().skip(5)
例如:查询年龄最大的前五个学生且不包括最大的那个学生,最后只保留姓名即可
分析需求:
- 年龄最大:倒序
- 前五个学生:limit(5)
- 不包括最大的学生:skip(1)
- 只保留姓名:find({},{name:1})
综合一下:
db.collectionName.find({}, { name: 1 }).sort({ age: -1 }).skip(1).limit(5)
分页查询的算法:
假设:
- 我需要查询第m页
- 每一页需要展示n条数据
则:
需要跳过的数据k就等于
k = (m-1) * n
例如:我需要查询第四页,每页展示五条数据,需要跳过的数据为15条
db.collectionName.find().skip(15).limit(5)
特殊查询
查询记录的总数count(有多少条记录)
db.collectionName.find().count()
or(或者)查询
例如查询名字为zhangsan或者lisi的学生记录
db.collectionName.find({
$or: [
{"name":"zhangsan"},
{"name": "lisi"}
]
})
findOne查询第一条数据
db.collectionName.findOne({条件})
修改数据
关键字
- update()
- $set
- multi
格式与基本修改数据的用法
db.collectionName.update({查询条件}, {$set: {修改内容}})
例如:将名为zhangsan的同学年龄修改为666岁
db.collectionName.update({ name: "zhangsan" }, { age: 666 })
注意:一定要记得加$set!一定要记得加$set!一定要记得加$set!不然就把这条数据改成修改后的数据了,相当于覆盖!!!
批量修改数据
db.collectionName.update({查询条件}, {$set: {修改内容}}, {multi: true})
例如:将所有年龄为20的学生性别改为男
db.collectionName.update({ age: 20 }, { sex: true }, { multi: true })
删除数据
db.collection.remove({查询条件})
注意:一定要记得写条件,一定要记得写条件,一定要记得写条件,不然会删除所有数据!!!
只删除一条数据的话,第二个参数加个justOne:true即可
db.collectionName.remove({查询条件}, {justOne: true})
与代码语句结合
命令行循环插入数据for
例如:用命令行循环插入姓名为linfeng1到linfeng99且年龄为1到99的数据
for(var i = 1;i < 99;i ++){
db.collectionName.insert({
"name": "linfeng"+i,
"age": i
})
}
mongoDB优化查询速度
一些基本的操作
查询具体的执行时间
db.collectionName.find().explain("executionStats")
执行时间:explain.executionStats.executionTimeMillis
设置索引
当数据很多,达到几十万条时,可以为字段添加索引来极大提升查询速度。(插入、修改、删除速度将会降低)
创建索引命令
db.collectionName.createIndex({"经常查询的字段": 1})
注意:是给你经常用来搜索的字段添加索引,比如id
创建符合索引命令
db.collectionName.createIndex({"字段1":30, "字段2": "stephen"})
复合索引还是不要用命令行来添加了,因为我也不确定记得笔记是否正确
获取当前集合的索引
db.collectionName.getIndexes()
删除索引命令
db.collcetionName.dropIndex({"需要删除索引的字段": 1})
唯一索引添加
唯一索引就是唯一的字段,该字段不可重复
db.collectionName.createIndex({"唯一字段":1}, {"unique":true})
mongoDB用户权限管理
创建超级管理员账户
use admin
db.createUser({
user: "admin",
pwd: passwordPrompt(),
roles: [{
role: 'root',
db: 'admin'
}]
})
开启安全验证
Windows
找到下面的路径的.cfg文件,然后编辑
bin/mongod.cfg
Linux
找到下面的路径
sudo nano /etc/mongod.conf
编辑内容
更改端口,最好别用默认端口
更改下面内容,来开启验证,将
#security
改为
security: authorization: enabled
即可
重启服务
linux重启的话
sudo systemctl restart mongod
用权限认证连接数据库
mongo collectionName -r 用户名 -p 密码
给单独(例:test)数据库创建用户
use test
db.createUser({
user: "test",
pwd: passwordPrompt(),
roles: [{
role: "dbOwner",
db: "test"
}]
})
其它常用命令
# 查看当前库的用户
show users
# 删除用户
db.dropUser("userName")
# 更新密码
db.updateUser("userName", {pwd:"password"})
# 密码认证
db.auth("userName", "password")
mongoDB聚合管道
结构
db.collectionName.aggregate([
{$match: {status: "A"}},
{$group: {_id:"$cust_id", total: {$sum: "$amount"}}},
等等更多条件
])
mongoDB中常用的管道操作符
管道操作符 | desciption |
---|---|
$project | 增加、删除、重命名字段.只显示某些字段,1显示,不写不显示 |
$match | 条件匹配。只满足条件的文档才能进入下一阶段 |
$limit | 限制结果的数量 |
$skip | 跳过文档的数量 |
$sort | 条件排序 |
$group | 条件组合结果 统计 |
$lookup | $lookup操作符 用以引入其它集合的数据 (表关联查询) |
SQL和NOSQL对比
SQL | NOSQL |
---|---|
WHERE | $match |
GROUP BY | $group |
HAVING | $match |
SELECT | $project |
ORDER BY | $sort |
LIMIT | $limit |
SUM() | $sum |
COUNT() | $sum |
join | $lookup |
管道表达式
管道操作符作为“键”,所对应的“值”叫做管道表达式。
例如{$match:{status:”A”}},$match 称为管道操作符,而 status:”A”称为管道表达式,是管道操作符的操作数(Operand)。
每个管道表达式是一个文档结构,它是由字段名、字段值、和一些表达式操作符组成的。
常用表达式操作符 | Description |
---|---|
$addToSet | 将文档指定字段的值去重 |
$max | 文档指定字段的最大值 |
$min | 文档指定字段的最小值 |
$sum | 文档指定字段求和 |
$avg | 文档指定字段求平均 |
$gt | 大于给定值 |
$lt | 小于给定值 |
$eq | 等于给定值 |
案例
利用管道将查询结果显示指定字段
只显示姓名和年龄
db.collectionName.aggregate([
{
$project: {
name: 1,
age: 1
}
}
])
利用管道将年龄大于20的学生显示出指定字段
db.collectionName.aggregate([
{
$project: {
name: 1,
age: 1
}
},{
$match: {
age: {
$gt: 20
}
}
}
])
其它案例不再展示,可查看pdf文档
顺便一提,表关联查询用lookup,比较常用
db.collectionName.aggregate([ { $lookup:{ # 需要关联的表 from: "order_item", # 需要关联的字段 localField: "order_id", foreignField: "order_id", # 重命名 as: "items" } } ])
nodejs操作mongodb
官方文档:http://mongodb.github.io/node-mongodb-native/
安装
npm install mongodb --save
# or
cnpm install mongodb --save
# or
yarn add mongodb
链接数据库
const { MongoClient } = require('mongodb')
const { mongodb: config } = require('./config')
let db = null
const url = `mongodb://${config.username}:${config.password}@${config.mongo_url}:${config.mongo_port}/?authSource=${config.authSource}`
// 这个useUnifiedTopology表示也许会被弃用,加上就不会有问题了
const client = new MongoClient(url, {useUnifiedTopology: true})
client.connect((err, mongo) => {
if(err) throw err
console.log("mongo连接正常");
db = mongo
// 关闭数据库连接
// client.close()
})
代码比较简单,不过多的解释
什么?你觉得那么写很麻烦?这好说,只要稍稍做一些改动即可
const { MongoClient } = require('mongodb')
const { mongodb: config } = require('./config')
let db = null
const url = `mongodb://${config.username}:${config.password}@${config.mongo_url}:${config.mongo_port}/?authSource=${config.authSource}`
MongoClient.connect(url, async (err, mongo) => {
if (err) {
console.log(err);
}
console.log("mongo 链接正常!");
db = mongo.db(config.authSource);
})
module.exports.getdb = () => {
return db
}
嘿嘿,怎么样?是不是感觉比上一个代码简单多了?没戳,就是这么简单
一些废话
enmmm,这些笔记并不是现在写的,而是之前的,只不过都是分散的,然后nodejs对MongoDB的一些详细使用的笔记找不到了。┭┮﹏┭┮,只能先整理这些了。这里主要对MongoDB的基本用法做了整理,像底层原理之类的都没有写,所以还有很多东西等着我们去学习呢(ง •_•)ง。