MongoDB学习笔记


MongoDB学习笔记

这次整理以下MongoDB的笔记吧。

Tips:

本文较长,加载时间可能也会比较长

推荐使用PC端查看,因为有目录

mongoDB简介

mongodb是一种介于关系型和非关系型之间的数据库,它是属于nosql数据库,而它确实最像关系型数据库的nosql数据库

mongodb都是以json来存储数据的

安装好mongoDB后还需要记得配置下环境变量

一般路径会放在C盘的program file的mongodb里,我们只需要进入到bin目录下配置即可完成

Linux安装mongoDB

由于Windows太简单了,傻瓜式操作,所以就不再过多赘述

centOS安装mongoDB5.x

这里我用的是yum换源方式安装

  1. 创建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
  2. yum安装

    sudo yum install -y mongodb-org
  3. 启动mongodb

    sudo systemctl start mongod
  4. 查看mongo状态

    sudo systemctl status mongod
  5. 设置开机自启

    sudo systemctl enable mongod
  6. 关闭mongo

    sudo systemctl stop mongodb
  7. 重启

    sudo systemctl restart mongodb

    centOS安装mongodb文章转自:https://blog.csdn.net/DanielJackZ/article/details/124210456

树莓派(Ubuntu安装mongoDB4.x)

  1. 安装依赖包

    sudo apt-get install libcurl4 openssl
  2. 关闭和卸载原有的mongodb

    service mongodb stop
    sudo apt-get remove mongodb
  3. 导入包管理系统使用的公钥

    wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -

    如果命令执行结果没有显示OK,则执行此命令在把上一句重新执行:

    sudo apt-get install gnupg
  4. 注册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
  5. 更新源

    sudo apt-get update
  6. 正式安装

    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
  7. 创建数据存储目录

    sudo mkdir -p /data/db
  8. 修改配置,开放27017端口 ,以及开发外网链接

    sudo nano /etc/mongod.conf

    将bindIp改为0.0.0.0

  9. 重新加载配置,并启动mongodb

    sudo systemctl daemon-reload
    sudo systemctl start mongod
  10. 查看运行状态

    sudo systemctl status mongod

    如果mongodb状态为stop,则运行:

    sudo systemctl enable mongod
  11. 停止mongodb

    sudo systemctl stop mongod
  12. 重启mongodb

    sudo systemctl restart mongod
  13. 启动开机启动

    sudo systemctl enable mongod

mongo开启认证

  1. 进入mongo

    mongo
  2. 添加用户

    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:用户管理权限,读写所有数据库权限
  3. 创建用户自己的数据库的管理角色

    use yourdatabase
    db.createUser({user: "user",pwd: "password",roles: [ { role: "dbOwner", db: "yourdatabase" } ]})
  4. 密码验证

    db.auth('user', 'pwd')

    若返回1则用户创建成功且密码正确

  5. 编辑开启认证

    sudo nano /etc/mongod.conf

    #security

    改为

    security:
      authorization: enabled

    注意要有缩进

  6. 重启mongo

    sudo systemctl restart mongod
  7. 密码连接数据库

    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的基本用法做了整理,像底层原理之类的都没有写,所以还有很多东西等着我们去学习呢(ง •_•)ง。


文章作者: 林风
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 林风 !
  目录