【MongoDB】入门篇MongoDB,修行靠自学
【此为学习笔记,后续会持续更新】
一 简介
1.1 网址
版本:https://www.mongodb.com/try/download/community
1.2 概念
关系型数据库: 数据库 --> 表 --> 行 -->列 --> 索引 --> 表连接
MongoDB数据库:数据库 --> 集合–>文档 -->字段 --> 索引 --> 嵌入的文档和连接
1.3 数据类型
类型对应数字别名说明Double1doubleString2stringObject3objectArray4arrayBinary data5binDataUndefined6undefined弃用ObjectId7objectIdBoolean8boolDate9dateNull10nullRegular Expression11regexDBPointer12dbPointerJavaScript13javascriptSymbol14symbolJavaScript(with scope)15javascriptWithScope32-bit integer16intTimestamp17timestamp64-bit integer18longMin key-1minKeyMax key127maxKey
二 安装
2.1 下载
https://www.mongodb.com/try/download/community
版本:4.4.11,操作系统:macOS
2.2 解压
将下载的文件移动到 /Users/chyzhong/01-worktools/28-mongodb,并进行解压。
bin目录下有以下四个文件:
文件名说明install_compassmongo客户端程序,连接MongoDBmongod服务端程序,启动MongoDBmongos数据分片程序,支持数据的横向扩展
三 启动
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:(可选)如果设为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关系,或者直接用 (“
a
n
d
"
)
、
(
"
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 中可以使用的类型如下表所示:
类型数字备注Double1String2Object3Array4Binary data5Undefined6已废弃。Object id7Boolean8Date9Null10Regular Expression11JavaScript13Symbol14JavaScript (with scope)1532-bit integer16Timestamp1764-bit integer18Min 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 : {
s
u
m
:
"
sum : "
sum:"likes"}}}])$avg计算平均值db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", num_tutorial : {
a
v
g
:
"
avg : "
avg:"likes"}}}])$min获取集合中所有文档对应值得最小值。db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", num_tutorial : {
m
i
n
:
"
min : "
min:"likes"}}}])$max获取集合中所有文档对应值得最大值。db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", num_tutorial : {
m
a
x
:
"
max : "
max:"likes"}}}])$push将值加入一个数组中,不会判断是否有重复的值。db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", url : {
p
u
s
h
:
"
push: "
push:"url"}}}])$addToSet将值加入一个数组中,会判断是否有重复的值,若相同的值在数组中已经存在了,则不加入。db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", url : {
a
d
d
T
o
S
e
t
:
"
addToSet : "
addToSet:"url"}}}])$first根据资源文档的排序获取第一个文档数据。db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", first_url : {
f
i
r
s
t
:
"
first : "
first:"url"}}}])$last根据资源文档的排序获取最后一个文档数据db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", last_url : {
l
a
s
t
:
"
last : "
last:"url"}}}])
4.2.7.2
m
a
t
c
h
和
match和
match和group
相当于sql语句中的where和group by。
{"KaTeX parse error: Expected 'EOF', got '}' at position 19: …ch":{"字段":"条件"}}̲ ,可以使用任何常用查询操作…gt、
l
t
、
lt、
lt、in等。
{"$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
s
o
r
t
和
sort和
sort和limit和$skip
4.2.7.4 $sample
4.2.7.5
c
o
n
c
a
t
和
concat和
concat和substr和$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.profileuserAdmin允许用户向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场景
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
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());
}
相关阅读
发表评论