文章目录
一、MongoDB简介
- MongoDB是为快速开发互联网Web应用而设计的数据库系统
- MongoDB的设计目标是简洁、灵活、作为Web应用栈的一部分
- MongoDB的数据模型是面向文档的,所谓文档是一种类似于JSON的结构,简单理解MongoDB这个数据库中存的是各种各样的JSON。(BSON)
二、下载安装
- 官网下载社区版并解压放到/usr/local下
- 配置环境变量
## 1.打开环境配置文件
open .bash_profile
## 2.添加环境配置并保存
export PATH=$PATH:/usr/local/mongodb/bin
## 3.让刚才输入的命令生效
source .bash_profile
## 4.运行命令,查看mongodb版本
mongod -version
## 5.展示以下内容则表示安装成功
db version v4.4.17
Build Info: {
"version": "4.4.17",
"gitVersion": "85de0cc83f4dc64dbbac7fe028a4866228c1b5d1",
"modules": [],
"allocator": "system",
"environment": {
"distarch": "x86_64",
"target_arch": "x86_64"
}
}
- 文件路径下没有关于日志及数据存放的位置,所以要新建两个文件夹(log:日志存储、data:数据存放)。为了方便查找,放在/usr/local/mongodb下。
## 1.进入mongodb目录
cd /usr/local/mongodb
## 2.创建data和log文件夹(名字可以是其他,不强制)
mkdir data log
## 3.由于读写权限的问题,需要给这两个文件夹赋予读写权限
sudo chown yuanyuan /usr/local/mongodb/data
sudo chown yuanyuan /usr/local/mongodb/log
- 启动
## 1.⚠️当前的位置是/usr/local/mongodb, 所以这里的 --dbpath 是 data; --fork表示在后台运行 --logappend 表示追加
mongod --fork -dbpath data --logpath log/mongo.log --logappend
## 出现如下,则表示启动成功
about to fork child process, waiting until server is ready for connections.
forked process: 79014
child process started successfully, parent exiting
## 新开一个终端窗口
mongo
## 展示一个箭头则表示启动成功
## 打开浏览器输入: http://127.0.0.1:27017/
It looks like you are trying to access MongoDB over HTTP on the native driver port.
## 启动成功
- 关闭mongodb服务
## 接上面
## 1.切换到管理员
use admin
## 2.运行命令(参数可写可不写)
db.shutdownServer({force:true});
## 展示以下则关闭成功
server should be down...
## 通过浏览器访问 http://127.0.0.1:27017/ 拒绝连接
- 也可以通过配置文件启动,在mongodb文件夹下新建etc文件夹,在文件夹中新建mongodb.conf文件(将下面拷贝进去)。vi mongodb.conf
#数据库路径
dbpath=/usr/local/mongodb/data
#日志输出文件路径
logpath=/usr/local/mongodb/log/mongo.log
#错误日志采用追加模式,配置这个选项后mongodb的日志会追加到现有的日志文件,而不是从新创建一个新文件
logappend=true
#启用日志文件,默认启用
journal=true
#这个选项可以过滤掉一些无用的日志信息,若需要调试使用请设置为false
quiet=false
#是否后台启动,有这个参数,就可以实现后台运行
fork=true
#端口号 默认为27017
port=27017
#指定存储引擎(默认不需要指定)
#storageEngine=mmapv1
#开启认证
auth = true
- 通过配置文件启动命令
## 启动命令
mongod -f /usr/local/mongodb/etc/mongodb.conf
## 启动成功,可在浏览器中验证
## 关闭服务时,按照上面的方式去关闭,会有问题。因为在配置文件中开启了认证 auth=true,想关闭的时候会报错,告知没有权限
## 解决很简单,没有权限就赋予一个权限
## 如果是新安装的mongodb,默认是没有用户的,所以我们来创建用户
mongo
## 创建用户
db.createUser({user: 'root', pwd: '123456', roles:[{role:'root',db:'admin'}]})
## 登陆用户
db.auth('root','123456')
## 显示 1 说明登陆成功
## 赋予权限
db.grantRolesToUser('root', [{role: 'hostManager',db:'admin'}])
## 关闭服务
db.shutdownServer({force:true});
三、基本操作
1. 三个概念
- 数据库(database)
数据库是一个仓库,在仓库中可以存放文档 - 集合(collection)
集合类似于数组,在集合中可以存放文档 - 文档(document)
文档是数据库中的最小单位,我们存储和操作的内容都是文档
在MongoDB中,数据库和集合都不需要手动创建,当我们创建文档时,如果文档所在的集合或数据库不存在会自动创建数据库和集合
2. 基本指令
- 显示当前的所有数据库
show dbs
show database
- 进入到指定的数据库
use 数据库名
- 表示当前所处的数据库
db
显示数据库中所有集合
show collections
3. 数据库的CRUD(增删改查)的操作
- 先登陆,否则无权限
use admin;
db.auth('root', 'xxxxxx');
插入
- 向集合中插入一个或多个文档(<>中是集合名)
- 当向集合中插入文档时,如果没有给文指定_id属性,则数据库会自动为文档添加_id,该属性用来作为文档的唯一标识
- _id可以自己指定,如果我们指定了数据库就不会再添加了,如果自己指定_id,也必须确保它的唯一性
db.< collection >.insert(doc)
db.stus.insert({"name":"sunwukong","age":18,"gender":"male"});
db.stus.insert([{"name":"a","age":18,"gender":"male"},{"name":"b","age":19,"gender":"male"}]);
- 插入一个或多个对象
db.< collection >.insertOne()
db.< collection >.insertMany()
查询
- 查询当前集合中的所有文档,返回一个数组
db.< collection >.find()
db.< collection >.find({})
- find()可以接收一个对象作为条件参数, {字段名: 值}
db.stus.find({_id: "123"});
- 查询集合中符合条件的第一个文档
db.< collection >.findOne()
db.< collection >.find()[0]
- 查询所有结果的数量
db.< collection >.find({}).count()
db.< collection >.find({}).length()
修改
- update()默认情况下会使用新对象来替换旧对象
- 当存在多条符合条件的记录时,update()默认只改一条记录
db.< collection >.update(查询条件,新对象)
db.stus.update({"name":"sunwukong"},{"age":28})
- 如果需要修改指定的属性,而不是替换,则需要使用“修改操作符”
- $set 可以用来修改文档中的指定属性
- $unset 可以用来删除文档的指定属性
db.stus.update({"_id" : ObjectId("635812327c22648214e938ec")},{$set:{"name":"sunwukong","age": 28,"gender": "male","address": "动物园"}});
db.stus.update({"_id" : ObjectId("635812327c22648214e938ec")},{$unset:{"address": "动物园"}});
db.stus.update({"_id" : ObjectId("635812327c22648214e938ec")},{$unset:{"address": 1}});
- 修改一个或多个符合条件的文档
修改一个文档
db.< collection >.update()
db.< collection >.updateOne()
修改多个文档
db.< collection >.update(查询条件, 新对象, multi: true)
db.< collection >.updateMany()
- 替换一个文档
db.< collection >.replaceOne()
删除
- remove() 可以根据条件来删除文档,传递的条件方式和find() 一样
- 删除符合条件的所有文档(默认情况删除多个)
- 如果remove() 第二个参数传递一个true,则只会删除一个
- remove()必须传参,也可以remove({}) (清空集合,但性能较差,因为是一个一个删的。可直接删除集合drop())
- 一般数据库中的数据都不会删除,所以删除的方法很少调用。一般会在数据中添加一个字段,来表示数据是否被删除
db.< collection >.remove()
db.< collection >.drop()
db.< collection >.deleteOne()
db.< collection >.deleteMany()
db.dropDatabase() – 删除数据库
四、练习
- 向nums中插入20000跳数据
# 执行慢
for(var i=1; i<=20000; i++){
db.nums.insert({num:i});
}
# 执行快
var arr=[];
for(var i=1; i<=20000; i++){
arr.push({num:i});
}
db.numbers.insert(arr);
- 查询nums中num大于5000的文档
db.nums.find({num: {$gt: 5000}});
- 查询nums中num大于40小于50的文档
db.nums.find({num: {$gt: 40, $lt: 50}});
- 查询nums集合中的前10条数据
db.nums.find().limit(10);
- 查看nums集合中的第11条到第20条数据
db.nums.find().skip(10).limit(10);
# 效果一样,MongoDB会自动调整skip和limit的位置
db.nums.find().limit(10).skip(10);
五、文档间的关系
一对一(one to one)
在MongoDB中可以通过内嵌文档的形式来体现出一对一的关系
db.wifeAndHusband.insert([
{
name:"黄蓉",
husband:{
name:"郭靖"
}
},{
name:"潘金莲",
husband:{
name:"武大郎"
}
}
]);
一对多(one to many)/ 多对一(many to one)
db.users.insert([{
username:"swk"
},{
username:"zbj"
}
}]);
db.order.insert([{
list:["苹果","香蕉","草莓"],
user_id:ObjectId("63595e4a7c22648214e938ed")
},{
list:["西瓜","荔枝"],
user_id:ObjectId("63595e4a7c22648214e938ed")
},{
list:["KFC","冰激淋"],
user_id:ObjectId("63595e4a7c22648214e938ee")
}]);
# 查找用户swk的订单
var user_id = db.users.findOne({username:"swk"})._id;
db.order.find({user_id:user_id});
多对多(many to many)
db.teachers.insert([
{name:"洪七公"},
{name:"黄药师"},
{name:"龟仙人"}
]);
db.stus.insert([
{
name:"郭靖",
tech_ids:[
ObjectId("635acc257c22648214e938f2"),
ObjectId("635acc257c22648214e938f3")
]
},{
name:"周杰伦",
tech_ids:[
ObjectId("635acc257c22648214e938f2"),
ObjectId("635acc257c22648214e938f3"),
ObjectId("635acc257c22648214e938f4")
]
}
]);
六、sort和投影
sort
- 查询文档时,默认情况是按照_id的值进行排列(升序)
- sort()可以用来指定文档的排序规则,sort()需要传递一个对象来指定排序规则。
1表示升序,-1表示降序 - limit skip sort 可以以任意的顺序进行调用。(会自动先调用sort)
# 按sal值升序来查询文档
db.emp.find({}).sort({sal:1});
# 按sal值降序来查询文档
db.emp.find({}).sort({sal:-1});
# 当sal一样时,
db.emp.find({}).sort({sal:1, empno:-1});
投影
在查询时,可以在第二个参数的位置来设置查询结果的投影
db.stus.find({},{name:1});
不显示_id
db.stus.find({},{name:1, _id:0});