【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(, {justOne: });

参数说明:

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场景

org.springframework.boot

spring-boot-starter-data-mongodb

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-devtools

runtime

true

org.projectlombok

lombok

true

org.springframework.boot

spring-boot-starter-test

test

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 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());

}

相关阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: