【MongoDB】MongoDB入门篇,修行靠自学

【MongoDB】入门篇MongoDB,修行靠自学

【此为学习笔记,后续会持续更新】

一 简介

1.1 网址

版本:https://www.mongodb.com/try/download/community

1.2 概念

关系型数据库: 数据库 --> 表 --> 行 -->列 --> 索引 --> 表连接

MongoDB数据库:数据库 --> 集合–>文档 -->字段 --> 索引 --> 嵌入的文档和连接

1.3 数据类型

类型对应数字别名说明
Double1double
String2string
Object3object
Array4array
Binary data5binData
Undefined6undefined弃用
ObjectId7objectId
Boolean8bool
Date9date
Null10null
Regular Expression11regex
DBPointer12dbPointer
JavaScript13javascript
Symbol14symbol
JavaScript(with scope)15javascriptWithScope
32-bit integer16int
Timestamp17timestamp
64-bit integer18long
Min key-1minKey
Max key127maxKey

二 安装

2.1 下载

https://www.mongodb.com/try/download/community

版本:4.4.11,操作系统:macOS

2.2 解压

将下载的文件移动到 /Users/chyzhong/01-worktools/28-mongodb,并进行解压。

bin目录下有以下四个文件:

文件名说明
install_compass
mongo客户端程序,连接MongoDB
mongod服务端程序,启动MongoDB
mongos数据分片程序,支持数据的横向扩展

三 启动

3.1 启动前准备

MongoDB的数据存储在data目录的db目录下,安装包下没有该目录,需要手动创建data/db目录。

# 指定数据数据文件存放目录
mkdir -p /Users/chyzhong/01-worktools/28-mongodb/mongodb-macos-x86_64-4.4.11/data/db
# 日志目录
mkdir -p /Users/chyzhong/01-worktools/28-mongodb/mongodb-macos-x86_64-4.4.11/logs
# 日志文件
touch /Users/chyzhong/01-worktools/28-mongodb/mongodb-macos-x86_64-4.4.11/logs/mongodb.log

3.2 前台启动(不推荐)

> cd /Users/chyzhong/01-worktools/28-mongodb/mongodb-macos-x86_64-4.4.11

# 通过执行 bin/mongod 命令时,报错:Data directory /data/db not found。显然,mongodb默认数据库路径是/data/db。

# 方式一(修改数据库路径):
> bin/mongod --dbpath /Users/chyzhong/01-worktools/28-mongodb/mongodb-macos-x86_64-4.4.11/data/db/
# 这种只有--dbpath参数的,日志会打印在当前终端控制台上。

# 方式二(修改数据库路径、日志文件路径等):
> bin/mongod --dbpath /Users/chyzhong/01-worktools/28-mongodb/mongodb-macos-x86_64-4.4.11/data/db/ --logpath /Users/chyzhong/01-worktools/28-mongodb/mongodb-macos-x86_64-4.4.11/logs/mongodb.log --logappend --port 27017 --bind_ip 0.0.0.0

# 启动完后,成阻塞状态,该窗口无法使用。
# 参数说明:
--dbpath:指定数据数据文件存放目录
--logpath:指定日志文件
--logappend:使用追加的方式记录日志
--port:指定端口,默认为27017
--bind_ip:绑定服务IP,若绑定127.0.0.1,则只能本机访问,默认为本机地址。0.0.0.0表示所有集群可以访问。
--auth:是否需要验证权限登录(用户名和密码)

#【备注】关闭终端窗口后,无法连接mongodb,但是进程还没有退出,仍然占用端口。

3.3 后台启动(不推荐)

在前台启动的情况下,加参数:–fork,表示后台启动,不占用终端窗口。

# 启动命令
/Users/chyzhong/01-worktools/28-mongodb/mongodb-macos-x86_64-4.4.11/bin/mongod --dbpath /Users/chyzhong/01-worktools/28-mongodb/mongodb-macos-x86_64-4.4.11/data/db/ --logpath /Users/chyzhong/01-worktools/28-mongodb/mongodb-macos-x86_64-4.4.11/logs/mongodb.log --logappend --port 27017 --bind_ip 0.0.0.0 --fork

## 启动信息
about to fork child process, waiting until server is ready for connections.
forked process: 56339
child process started successfully, parent exiting

3.4 配置环境变量

vi ~/.bash_profile

##2022-01-07-mongodb
export MONGODB_HOME=/Users/chyzhong/01-worktools/28-mongodb/mongodb-macos-x86_64-4.4.11
export PATH=$PATH:$MONGODB_HOME/bin

source ~/.bash_profile

3.5 配置文件(重点)

# 创建配置文件目录:
mkdir -p /Users/chyzhong/01-worktools/28-mongodb/mongodb-macos-x86_64-4.4.11/conf/

vi mongodb.conf

#以下是mongodb.conf文件内容
dbpath=/Users/chyzhong/01-worktools/28-mongodb/mongodb-macos-x86_64-4.4.11/data/db
logpath=/Users/chyzhong/01-worktools/28-mongodb/mongodb-macos-x86_64-4.4.11/logs/mongodb.log
logappend=true
port=27017
bind_ip=0.0.0.0
fork=true
#开启身份认证
#auth=true

3.6 配置文件启动(重点)

$ mongod -f /Users/chyzhong/01-worktools/28-mongodb/mongodb-macos-x86_64-4.4.11/conf/mongodb.conf

$ mongod -config /Users/chyzhong/01-worktools/28-mongodb/mongodb-macos-x86_64-4.4.11/conf/mongodb.conf

##启动提示信息
about to fork child process, waiting until server is ready for connections.
forked process: 58056
child process started successfully, parent exiting

备注:生产再可以把该命令写成sh脚本执行即可。

3.7 停止

3.7.1 前台启动的停止

Windows:Crtl+C 关闭,MacOS:Control + Z

# 这种方法停止,虽然无法连接mongodb,但是通过ps -ef|grep mongo 后,发现进程还在,占用端口,更无法通过前台方式启动。需要通过 kill -9 pid 方式后方可前台启动。
$ ps -ef|grep mongo
  501 30813 30795   0  9:20下午 ttys000    0:00.78 bin/mongod --dbpath /Users/chyzhong/01-worktools/28-mongodb/mongodb-macos-x86_64-4.4.11/data/db/
  501 30849 30795   0  9:21下午 ttys000    0:00.00 grep mongo
chyzhong@chyzhong-MacBook-Pro mongodb-macos-x86_64-4.4.11 % kill -9 30813

3.7.2 后台启动的停止(不成功)

mongod --dbpath /Users/chyzhong/01-worktools/28-mongodb/mongodb-macos-x86_64-4.4.11/data/db/ --logpath /Users/chyzhong/01-worktools/28-mongodb/mongodb-macos-x86_64-4.4.11/logs/mongodb.log --logappend --port 27017 --bind_ip 0.0.0.0 --fork --shutdown

/Users/chyzhong/01-worktools/28-mongodb/mongodb-macos-x86_64-4.4.11/bin/mongod --dbpath /Users/chyzhong/01-worktools/28-mongodb/mongodb-macos-x86_64-4.4.11/data/db/ --shutdown

--repair

3.7.3 配置文件启动的停止(不成功)

mongod -f /Users/chyzhong/01-worktools/28-mongodb/mongodb-macos-x86_64-4.4.11/conf/mongodb.conf --shutdown

mongod --shutdown -f /Users/chyzhong/01-worktools/28-mongodb/mongodb-macos-x86_64-4.4.11/conf/mongodb.conf

bin/mongod -f conf/mongodb.conf --shutdown

##--shutdown错误提示:
Error parsing command line: unrecognised option '--shutdown'
try 'mongod --help' for more information

3.7.4 kill命令关闭(不推荐)

备注:不建议使用kill方式杀死进程。

3.7.5 函数关闭

$ mongo
> use admin;
> db.shutdownServer();    ##或者db.runCommand("shutdown");
# 这两种关闭方式都需要在admin数据库上使用,都是安全的关闭方式。

# 关闭后,需要控制台还没退出,但是无法再连接mongodb了。
server should be down...
> show dbs;
Error: socket exception [CONNECT_ERROR] server [couldn't connect to server 127.0.0.1:27017, connection attempt failed: SocketException: Error connecting to 127.0.0.1:27017 :: caused by :: Connection refused] :
runClientFunctionWithRetries@src/mongo/shell/session.js:361:27
runCommand@src/mongo/shell/session.js:455:25
DB.prototype._runCommandImpl@src/mongo/shell/db.js:147:12
DB.prototype.runCommand@src/mongo/shell/db.js:162:16
Mongo.prototype.adminCommand@src/mongo/shell/mongo.js:161:12
Mongo.prototype.getDBs/<@src/mongo/shell/mongo.js:117:21
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:99:12
shellHelper.show@src/mongo/shell/utils.js:937:13
shellHelper@src/mongo/shell/utils.js:819:15
@(shellhelp2):1:1
>

备注:不建议使用kill方式杀死进程。

3.8 客户端使用

3.8.1 非开启身份证

$ mongo
MongoDB shell version v4.4.11
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("627ee8de-876f-4166-a00e-393ae2049417") }
MongoDB server version: 4.4.11
Welcome to the MongoDB shell.
............
............
> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
> show databases
admin   0.000GB
config  0.000GB
local   0.000GB
> db      #当前数据库
test
> db.help()    # 帮助
> db.version() # 版本
4.4.11
> cls     #清屏
> exit
bye

3.8.2 开启身份认证后

$ mongo
MongoDB shell version v4.4.11
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("a6648604-54a3-4ae8-849b-22c9f26276da") }
MongoDB server version: 4.4.11
> use admin
switched to db admin
> db.auth("uaad","uadd");
Error: Authentication failed.
0
> use admin
switched to db admin
> db.auth("uaad","uaad");
1
>

四 数据库

4.1 操作数据库

4.1.1 默认数据库test

$ mongo
MongoDB shell version v4.4.11
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("adddc352-91e6-412a-9fa8-f4277444a983") }
MongoDB server version: 4.4.11
> db
test
> show dbs
> use admin
switched to db admin
> db.auth("uaad","uaad")
1
> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
>

虽然test是默认数据库,但是show dbs时却不显示test库,因为test库没有数据。

4.1.2 创建数据库

mongodb没有具体的创建数据库命令,在use切换数据库后,如果没有数据库,则自动创建并切换到该数据库。

> use abc
switched to db abc
> use abc2
switched to db abc2
> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
> db
abc2

4.1.3 删除数据库

# 切换到要删除的数据库test
> use test
> db.dropDatabase();
{ "dropped" : "test", "ok" : 1 }
> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB

4.2 操作集合

4.2.1 查看集合

如果集合内有值会显示集合名称,否则不显示。

> use test
switched to db test
> show tables
user
> show collections
user
>

4.2.2 创建集合

集合没有明显声明的语法。在插入数据时,自动创建。

4.2.3 单条插入

插入文档时如果没有指定 _id 则默认为ObjectId类型, _id不能重复,且在插入后不可变。 _id为固定字段。

4.2.3.1 insert
> use test
> db.user.insert({name:"张三"})
WriteResult({ "nInserted" : 1 })
> show tables;
user
4.2.3.2 insertOne
> db.user.insertOne({name:"张三", age:45})
{
	"acknowledged" : true,
	"insertedId" : ObjectId("61d807d6faf3e64f2663438f")
}
4.2.3.3 save
> db.user.save({name:"张三", address:"广东省广州市"})
WriteResult({ "nInserted" : 1 })

> db.user.save({_id:1, name:"aa"})
> db.user.save({_id:1, name:"aa", address:"广东省广州市"})  # 启动更新作用
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

区别:save对于_id来说,如果 _id没值,则新增;如果 _id有值,则更新。

4.2.3.4 使用客户端工具执行

右键选择数据库,点击”Open shell“

# 先定义对象,再执行插入:
user1 = {name:"张三", age:50}
db.user.insert(user1)

4.2.4 批量插入

将前面的单个数据组合成数组后,再插入即可。

4.2.4.1 insert
> db.user.insert([{name:"张三1"},{name:"张三2"}])
BulkWriteResult({
	"writeErrors" : [ ],
	"writeConcernErrors" : [ ],
	"nInserted" : 2,
	"nUpserted" : 0,
	"nMatched" : 0,
	"nModified" : 0,
	"nRemoved" : 0,
	"upserted" : [ ]
})
4.2.4.2 insertMany
> db.user.insertMany([{name:"王五1"},{name:"王五2"}])
{
	"acknowledged" : true,
	"insertedIds" : [
		ObjectId("61d80b2dfaf3e64f26634393"),
		ObjectId("61d80b2dfaf3e64f26634394")
	]
}
4.2.4.3 save
> db.user.save([{name:"王五3"},{name:"王五4"}])
BulkWriteResult({
	"writeErrors" : [ ],
	"writeConcernErrors" : [ ],
	"nInserted" : 2,
	"nUpserted" : 0,
	"nMatched" : 0,
	"nModified" : 0,
	"nRemoved" : 0,
	"upserted" : [ ]
})

# 批量方式不能执行更新(_id=1的数据已经存在)
> db.user.save([{_id:1, name:"aa", address:"广东省广州市2"}])
BulkWriteResult({
	"writeErrors" : [
		{
			"index" : 0,
			"code" : 11000,
			"errmsg" : "E11000 duplicate key error collection: test.user index: _id_ dup key: { _id: 1.0 }",
			"op" : {
				"_id" : 1,
				"name" : "aa",
				"address" : "广东省广州市2"
			}
		}
	],
	"writeConcernErrors" : [ ],
	"nInserted" : 0,
	"nUpserted" : 0,
	"nMatched" : 0,
	"nModified" : 0,
	"nRemoved" : 0,
	"upserted" : [ ]
})
4.2.4.4 使用客户端工具执行

右键选择数据库,点击”Open shell“

user1 = {_id:3, name:"王五7"}
user2 = {_id:4, name:"王五8"}
db.user.save([user1, user2])

4.2.4 更新文档

通过update系列函数或者save函数可以更新集合中的文档。

update()函数语法格式如下:

db.collection_name.update(query, update, options);

query:update查询条件,类型sql update中的where部分。

update:update的对象和一些更新的操作符(如:$, $inc…)等,可以理解为sql update中的set部分。

upsert:可选,如果不存在update的文档,是否插入该文档。true为插入,默认false,不插入。

multi:可选,是否批量更新。true标识按条件查询出来的多条记录全部更新,false只更新找到的第一条记录,默认false。

【注意】更新文档是更新整个文档的操作,如果修改的值只有name和age,除了_id以外其他属性将会被删除。

4.2.4.1 update
# 更新name=王五8的数据
user1 = {name:"王五8", age:23, address:"广东省广州市天河区"};
# 如果匹配多条,只会修改第一条
db.user.update({name:"王五8"}, user1);
# 修改多条
db.user.update({name:"王五8"}, {"$set": user1}, false, true);
4.2.4.2 updateOne

修改单条

user1 = {name:"王五8", age:23, address:"广东省广州市天河区"};
db.user.updateOne({name:"王五8"}, {"$set": user1});
4.2.4.3 updateMany
user1 = {name:"王五8", age:55, address:"广东省广州市天河区"};
db.user.updateMany({name:"王五8"}, {"$set": user1});
4.2.4.4 更新操作符

$set 操作符

$inc 操作符

$unset 操作符

$push 操作符

$pop 操作符

$pull 操作符

$pullAll 操作符

$rename 操作符

4.2.5 删除文档

格式:

db.user.remove(<query>, {justOne: <boolean>});

参数说明:

query:(可选)删除文档的条件。

justOne:(可选)如果设为true,则只删一个文档,false删除所有匹配的数据

等价于

db.user.deleteOne():删除符合条件的第一个文档。

4.2.5.1 remove
# 删除第一条匹配的数据
db.user.remove({"name":"王五8"}, {justOne: true});
# 删除所有匹配的数据
db.user.remove({"name":"王五8"}, {justOne: false});
# 删除所有数据
db.user.remove({});
4.2.5.2 deleteOne
db.user.deleteOne({"name":"王五8})
4.2.5.2 deleteMany
# 删除_id大于等于2的数据
> db.user.deleteMany({"_id":{"$gte": 2}})
{ "acknowledged" : true, "deletedCount" : 2 }

# 删除name为张三1的所有数据
> db.user.deleteMany({"name":{"$eq": "张三1"}})
{ "acknowledged" : true, "deletedCount" : 3 }

# 删除所有
> db.user.deleteMany({})
{ "acknowledged" : true, "deletedCount" : 3 }

4.2.6 查询文档

4.2.6.1 查询所有
> db.user.find();
> db.user.find({});
{ "_id" : 2, "name" : "张三1" }
{ "_id" : 3, "name" : "张三2" }
{ "_id" : 1, "name" : "张三1" }
{ "_id" : ObjectId("61d846f9faf3e64f266343a3"), "name" : "张三2" }

## pretty不是方法???
db.user.find.pretty({});
4.2.6.2 去重
# 数据是数组形式
> db.user.distinct("name");
[ "张三1", "张三2" ]
4.2.6.3 比较运算

运算符:

= ("$eq")!= ("$ne")> ("$gt")>= ("$gte")< ("$lt")<= ("$lte")

查询语句:

#1、select * from user where id = 3;
> db.user.find({"_id": 3});
{ "_id" : 3, "name" : "张三2" }

#2、select * from user where id != 3;
> db.user.find({"_id": {"$ne": 3}});
{ "_id" : 1, "name" : "张三1" }
{ "_id" : 2, "name" : "张三1" }
{ "_id" : ObjectId("61d846f9faf3e64f266343a3"), "name" : "张三2" }
4.2.6.4 逻辑运算

MongoDB中字段内用逗号分割多个条件是and关系,或者直接用 (“and")、("and")、 ("and")("or”)、("$not"),而且数据是数组形式。

#1. select * from user where id >= 2 and id <= 3;
db.user.find({"_id":{"$gte":2,"$lte":3}});
{ "_id" : 2, "name" : "张三1" }
{ "_id" : 3, "name" : "张三2" }

#2. select * from user where id >= 2 and id <= 3 and age >= 4;
db.user.find({"_id": {"$gte": 2, "$lte": 3}, "age":{"$gte": 4}});
db.user.find({"$and": [{"_id": {"$gte": 2, "$lte": 3}}, {"age":{"$gte": 4}}]});

#3. select * from user where id >= 0 and id <= 1 or id >= 4 or name = "tianqi";
db.user.find({
"$and":[{"_id":{"gte":0}},{"_id":{"$lte":1}}],
"$or":[{"_id":{"gte":4}}],
"$or":[{"name":{"eq":"tianqi"}}]
});

#4. 模除
# select * from user where id % 2 = 1;
db.user.find({"_id":{"$mod": [2,1]}});   ## $mod对应数组第一个是除数,第二个是余数
{ "_id" : 1, "name" : "张三1" }
{ "_id" : 3, "name" : "张三2" }

#5. 取反
db.user.find({"_id":{"$not": {"$mod": [2,1]}}});
{ "_id" : 2, "name" : "张三1" }
{ "_id" : ObjectId("61d846f9faf3e64f266343a3"), "name" : "张三2", "age" : 5 }
4.2.6.5 $type操作符

MongoDB 中可以使用的类型如下表所示:

类型数字备注
Double1
String2
Object3
Array4
Binary data5
Undefined6已废弃。
Object id7
Boolean8
Date9
Null10
Regular Expression11
JavaScript13
Symbol14
JavaScript (with scope)15
32-bit integer16
Timestamp17
64-bit integer18
Min key255Query with -1.
Max key127

查询语句:

# 查询id类型是Double的
> db.user.find({"_id":{$type:1}});
{ "_id" : 1, "name" : "张三1" }
{ "_id" : 2, "name" : "张三1" }
{ "_id" : 3, "name" : "张三2" }

# 查询id类型是Object id的
> db.user.find({"_id":{$type:7}});
{ "_id" : ObjectId("61d846f9faf3e64f266343a3"), "name" : "张三2", "age" : 5 }
4.2.6.6 正则

正则定义在 / /内

#1. select * from user where name regexp '^z.*?(n|u)$';
# 匹配规则:z开头,n或u结尾,不区分大小写
> db.user.find({"name": /^z.*?(n|u)$/i});
{ "_id" : ObjectId("61d916adfaf3e64f266343a4"), "name" : "z张三n", "age" : 45 }
4.2.6.7 投影

查询需要的字段

#1. select name, age from user where id > 2;
# 0:隐藏,1:显示,_id默认显示。
db.user.find({"_id":{"$gt":2}},{"name":1});
db.user.find({"_id":3},{"_id":0,"name":1});
4.2.6.8 数组

4.2.6.9 排序
#1. 按name顺序排序
> db.user.find().sort({"name":1});
{ "_id" : ObjectId("61d916adfaf3e64f266343a4"), "name" : "z张三n", "age" : 45 }
{ "_id" : 1, "name" : "张三1" }
{ "_id" : 2, "name" : "张三2" }
{ "_id" : 3, "name" : "张三3" }
{ "_id" : ObjectId("61d846f9faf3e64f266343a3"), "name" : "张三4", "age" : 5 }

#1. 按name倒序排序
> db.user.find().sort({"name": -1});
{ "_id" : ObjectId("61d846f9faf3e64f266343a3"), "name" : "张三4", "age" : 5 }
{ "_id" : 3, "name" : "张三3" }
{ "_id" : 2, "name" : "张三2" }
{ "_id" : 1, "name" : "张三1" }
{ "_id" : ObjectId("61d916adfaf3e64f266343a4"), "name" : "z张三n", "age" : 45 }
4.2.6.10 分页

limit表示取多少个document,skip代表跳过几个document

  • 分页公式:db.user.find().skip((pageNum-1)*pageSize).limit(pagesize);
pageNum = 1;
pagesize = 2;
db.user.find().skip((pageNum-1)*pageSize).limit(pagesize);
4.2.6.11 统计
#1. 统计所有
> db.user.count({});
5

#2. 查询_id大于等于3的人数
# 方式1
> db.user.count({"_id":{"$gte":3}});
1

#方式2
> db.user.find({"_id":{"$gte":3}}).count();
1

4.2.7 聚合

4.2.7.1 Aggregate语法

下表展示了一些聚合的表达式(摘抄菜鸟教程):

表达式描述实例
$sum计算总和。db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", num_tutorial : {sum:"sum : "sum:"likes"}}}])
$avg计算平均值db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", num_tutorial : {avg:"avg : "avg:"likes"}}}])
$min获取集合中所有文档对应值得最小值。db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", num_tutorial : {min:"min : "min:"likes"}}}])
$max获取集合中所有文档对应值得最大值。db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", num_tutorial : {max:"max : "max:"likes"}}}])
$push将值加入一个数组中,不会判断是否有重复的值。db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", url : {push:"push: "push:"url"}}}])
$addToSet将值加入一个数组中,会判断是否有重复的值,若相同的值在数组中已经存在了,则不加入。db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", url : {addToSet:"addToSet : "addToSet:"url"}}}])
$first根据资源文档的排序获取第一个文档数据。db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", first_url : {first:"first : "first:"url"}}}])
$last根据资源文档的排序获取最后一个文档数据db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", last_url : {last:"last : "last:"url"}}}])
4.2.7.2 match和match和matchgroup

相当于sql语句中的where和group by。

{"KaTeX parse error: Expected 'EOF', got '}' at position 19: …ch":{"字段":"条件"}}̲ ,可以使用任何常用查询操作…gt、lt、lt、ltin等。

{"$group":{"_id":分组字段, “新的字段名”:聚合操作符}}

#1. select * from db.user where sex = 1;
db.user.aggregate([
{"$match":{"sex":1}}
]);
{ "_id" : 2, "name" : "张三2", "age" : 40, "sex" : 1 }
{ "_id" : 3, "name" : "张三3", "age" : 44, "sex" : 1 }
{ "_id" : ObjectId("61d916adfaf3e64f266343a4"), "name" : "z张三n", "age" : 45, "sex" : 1 }

#2. select id, avg(age) from user where id>=1 group by sex;
db.user.aggregate([
{"$match":{"_id":{"$gte":1}}},
{"$group":{"_id":"$sex", 'avg_age':{"$avg":"$age"}}}
]);

{ "_id" : 0, "avg_age" : 28 }
{ "_id" : 1, "avg_age" : 42 }

#3. select id, max(age) from user where id>=1 group by sex;
db.user.aggregate([
{"$match":{"_id":{"$gte":1}}},
{"$group":{"_id":"$sex", 'max_age':{"$max":"$age"}}}
]);

{ "_id" : 0, "max_age" : 28 }
{ "_id" : 1, "max_age" : 44 }

#4. select id, max(age), min(age) from user where id>=1 group by sex;
db.user.aggregate([
{"$match":{"_id":{"$gte":1}}},
{"$group":{"_id":"$sex", 'max_age':{"$max":"$age"}, 'min_age':{"$min":"$age"}}}
]);

{ "_id" : 0, "max_age" : 28, "min_age" : 28 }
{ "_id" : 1, "max_age" : 44, "min_age" : 40 }

#5. select * from user where id>=1 group by sex having avg(age) > 30;
db.user.aggregate([
{"$match":{"_id":{"$gte":1}}},
{"$group":{"_id":"$sex", 'avg_age':{"$avg":"$age"}}},
{"$match":{"avg_age":{"$gt":40}}}
]);

{ "_id" : 1, "avg_age" : 42 }

#6. select id, age_count sum(age) from user where id>=1 group by sex order by age;
db.user.aggregate([
{"$match":{"_id":{"$gte":1}}},
{"$group":{"_id":"$sex", "age_count":{"$sum":"$age"}}},
{"$sort":{"count":1}}
]);

{ "_id" : 0, "age_count" : 28 }
{ "_id" : 1, "age_count" : 84 }

#7. select id, count sum(1) from user where id>=1 group by sex order by age;
db.user.aggregate([
{"$match":{"_id":{"$gte":1}}},
{"$group":{"_id":"$sex", "count":{"$sum":1}}},
{"$sort":{"count":1}}
]);

{ "_id" : 0, "count" : 1 }
{ "_id" : 1, "count" : 2 }

4.2.7.3 sort和sort和sortlimit和$skip
4.2.7.4 $sample
4.2.7.5 concat和concat和concatsubstr和$toLower和toUpper

4.2.8 删除集合

> db.user.drop();
true
> show tables;
>

4.2.9 索引

4.2.9.1 创建索引
4.2.9.2 查询索引
4.2.9.3 删除索引

五 权限、用户

5.1 权限

5.1.1 常用权限

权限说明
read允许用户读取指定数据库
readWrite允许用户读写指定数据库
dbAdmin允许用户在指定数据库中执行管理函数,如:索引创建、删除、查看统计或访问system.profile
userAdmin允许用户向system.profile集合写入,可以在指定数据库里创建、删除、和管理用户
clusterAdmin必须在admin数据库的定义,赋予用户所有分片和复制集相关函数的管理权限
readAnyDatabase必须在admin数据库的定义,赋予用户所有数据库的读权限
readWriteAnyDatabase必须在admin数据库的定义,赋予用户所有数据库的读写权限
userAdminAnyDatabase必须在admin数据库的定义,赋予用户所有数据库的userAdmin权限
dbAdminAnyDatabase必须在admin数据库的定义,赋予用户所有数据库的dbAdmin权限
root必须在admin数据库的定义,超级账号,超级权限

5.2 用户

5.2.1 管理用户的创建和使用

在配置未使用认证的情况下创建该用户:

$ mongo
> use admin
# 显示用户
> show users;

# 创建用户(需要在admin数据库下创建)
> db.createUser({user:"uaad", pwd:"uaad", roles:[{role:"userAdminAnyDatabase", db:"admin"}]});

Successfully added user: {
	"user" : "uaad",
	"roles" : [
		{
			"role" : "userAdminAnyDatabase",
			"db" : "admin"
		}
	]
}

5.2.2 普通用户的创建和使用

5.2.2.1 使用管理员来创建
> use test
> db.createUser({user:"testuser", pwd:"123456", roles:[{role:"readWrite", db:"test"}]});

Successfully added user: {
	"user" : "testuser",
	"roles" : [
		{
			"role" : "readWrite",
			"db" : "test"
		}
	]
}

# 显示用户
> show users
{
	"_id" : "test.testuser",
	"userId" : UUID("6f5a5b90-b774-4dab-afb4-d139bd1c804e"),
	"user" : "testuser",
	"db" : "test",
	"roles" : [
		{
			"role" : "readWrite",
			"db" : "test"
		}
	],
	"mechanisms" : [
		"SCRAM-SHA-1",
		"SCRAM-SHA-256"
	]
}

5.2.2.2 使用普通用户登录
chyzhong@chyzhong-MacBook-Pro conf % mongo
MongoDB shell version v4.4.11
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("27e4086f-e9bb-4615-9fc6-b0bc3c3f8ed0") }
MongoDB server version: 4.4.11
> use test
switched to db test
> db.auth("testuser","123456");
1
> db
test
> show users
uncaught exception: Error: not authorized on test to execute command { usersInfo: 1.0, lsid: { id: UUID("27e4086f-e9bb-4615-9fc6-b0bc3c3f8ed0") }, $db: "test" } :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
DB.prototype.getUsers@src/mongo/shell/db.js:1659:15
shellHelper.show@src/mongo/shell/utils.js:914:9
shellHelper@src/mongo/shell/utils.js:819:15
@(shellhelp2):1:1

# 没有查看权限,需要userAdmin权限才行。
5.2.2.3 验证读写权限

插入数据(写权限)

# db表示当前数据库,user是一个集合(相当于mysql中的表),insert表示插入一条数据。
> db.user.insert({name:"张三"})
WriteResult({ "nInserted" : 1 })
> db.user.insert({name:"张三", age: 30})

查询数据(读权限)

# 相当于mysql中的 select * from user;
> db.user.find();
{ "_id" : ObjectId("61d7f0066f85544f2ded8810"), "name" : "张三" }
{ "_id" : ObjectId("61d7f0a56f85544f2ded8811"), "name" : "张三", "age" : 30 }

> db.user.find({age:30})
> db.getCollection('user').find({age:30})
> { "_id" : ObjectId("61d7f0a56f85544f2ded8811"), "name" : "张三", "age" : 30 }

5.2.3 更新用户角色

对已存在的用户进行角色修改,可以使用db.updateUser函数来更新用户角色。注意:执行该函数需要当前用户具有userAdmin或者userAdminAnyDatabase、root角色。

> use admin
switched to db admin
> db.auth("uaad","uaad");
> db.updateUser("uaad", {"roles":[{"role":"userAdminAnyDatabase", db:"admin"},{"role":"readWriteAnyDatabase", db:"admin"},{"role":"dbAdminAnyDatabase", db:"admin"}]});
> show users;
{
	"_id" : "admin.uaad",
	"userId" : UUID("a16c0720-74b1-4a3a-97c7-35cefeb8d7d1"),
	"user" : "uaad",
	"db" : "admin",
	"roles" : [
		{
			"role" : "userAdminAnyDatabase",
			"db" : "admin"
		},
		{
			"role" : "readWriteAnyDatabase",
			"db" : "admin"
		},
		{
			"role" : "dbAdminAnyDatabase",
			"db" : "admin"
		}
	],
	"mechanisms" : [
		"SCRAM-SHA-1",
		"SCRAM-SHA-256"
	]
}

5.2.4 更新密码

使用函数更新密码

> db.updateUser("testuser",{"pwd":"123456789"});
> db.changeUserPassword("testuser","123456");

5.2.5 删除用户

切换到当前对应的数据库

> user test
> db.dropUser("testuser");
true
> show users
>

六 GUI可视化管理工具

6.1 Studio 3T【付费】

https://studio3t.com/download/

6.2 Robo 3T(Robomong)【免费】

https://robomongo.org/download

6.3 Navicat for MongoDB

6.4 NoSQLBooster from MongoDB

6.5 NoSQL Manager from MongoDB Professional

6.6 MongoDB Compass

七 SpringDataMongoDB

7.1 项目

/Users/chyzhong/eclipse-study-workspace/11-springboottools/SpringBootMongoDB-01

7.1.1 pom.xml加入mongodb场景

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-mongodb</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

7.1.2 application.yml配置

spring:
  data:
    mongodb:
      host: 127.0.0.1
      password: uaad
      username: uaad
      authentication-database: admin
      database: test

7.1.3 document

import java.io.Serializable;
import java.util.Date;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import lombok.Data;

@Document("d_student")
@Data
public class Student implements Serializable {

	private static final long serialVersionUID = 1954786077909844690L;

	@Id
	private String id;

	private String userName;

	private String password;

	private Integer sex;

	private Date birthdate;

	private String address;

}

7.1.4 测试类

import java.util.Date;
import java.util.List;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import com.mongodb.client.result.DeleteResult;
import com.tiannan.springdatamongodb.document.Student;

@SpringBootTest(classes = { SpringBootMongoDb01Application.class })
class SpringBootMongoDb01ApplicationTests {

	@Autowired
	private MongoTemplate mongoTemplate;

  //TODO	

}
7.1.4.1 save添加
@Test
	public void test01_save() {
		Student student = new Student();
		student.setUserName("zhangsan");
		student.setPassword("123456");
		student.setSex(1);
		student.setBirthdate(new Date());
		mongoTemplate.save(student);

		System.out.println(student.getId());
	}
7.1.4.2 findById单个查询
@Test
	public void test02_getOne() {
		String id = "61da62833986677908378914";
		Query query = new Query();
		query.addCriteria(Criteria.where("id").is(id));
//		Student student = mongoTemplate.findOne(query, Student.class);
		Student student = mongoTemplate.findById(id, Student.class);
		System.out.println(student.getUserName());
	}
7.1.4.3 find查询更多
@Test
	public void test03_getMore() {
		Query query = new Query();
		Criteria criteria = Criteria.where("sex").is(1);
		query.addCriteria(criteria);
		List<Student> students = mongoTemplate.find(query, Student.class);
		System.out.println(students.size());
	}
7.1.4.4 save更新
@Test
	public void test04_update() {
		String id = "61da62833986677908378914";
		Query query = new Query();
		query.addCriteria(Criteria.where("id").is(id));
		Student student = mongoTemplate.findById(id, Student.class);
		student.setAddress("天河区");
		mongoTemplate.save(student); // 根据id修改值
	}
7.1.4.5 remove删除
@Test
	public void test05_remove() {
		String id = "61da6a107b7e42601171d60d";
//		Query query = new Query();
//		query.addCriteria(Criteria.where("id").is(id));
//		DeleteResult deleteResult = mongoTemplate.remove(query, Student.class);
//		System.out.println(deleteResult.getDeletedCount());
		
		Student student = mongoTemplate.findById(id, Student.class);
		DeleteResult deleteResult = mongoTemplate.remove(student);
		System.out.println(deleteResult.getDeletedCount());
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值