MongoDB常用命令

简介: 本文介绍MongoDB中文章评论数据的存储与操作,涵盖数据库创建、集合管理及文档的增删改查。使用articledb数据库,评论数据包含ID、内容、用户信息、点赞数等字段,支持嵌套回复。通过insert()插入数据,find()查询,update()更新,remove()删除,并实现分页、排序与统计功能,适用于高效管理非结构化评论数据。

3.1 案例需求
存放文章评论的数据存放到MongoDB中,数据结构参考如下: 数据库:articledb

如果为0表示文章的顶级评论

评论的日期时间

CREATEDATETIME

MONGO的主键的字段

0:不可见;1:可见;

评论人呢称

栏兰文章评论

评论内容

OBJECTLDSTRING

REPLYNUM

回复数

PARENTID

COMMENT

STRING

点赞数

字段名称

IKENUM

STRING

评论人ID

字段含义

字段类型

LNT32

CONTENT

NICKNAME

文章ID

上级ID

STRING

STRING

USERID

RTICLEID

STRING

状态

STATE

STRING

DATE

1INT32

备注

ID

ID


3.2 数据库操作
3.2.1 选择和创建数据库
选择和创建数据库的语法格式:

use 数据库名称

如果数据库不存在则自动创建,例如,以下语句创建 spitdb 数据库:

use articledb

查看有权限查看的所有的数据库命令

show dbs

show databases

注意: 在 MongoDB 中,集合只有在内容插入后才会创建! 就是说,创建集合(数据表)后要再插入一个文档(记录),集合才会真正创建。
查看当前正在使用的数据库命令

db

MongoDB 中默认的数据库为 test,如果你没有选择数据库,集合将存放在 test 数据库中。 另外:
数据库名可以是满足以下条件的任意UTF-8字符串。
不能是空字符串("")。
不得含有' '(空格)、.、$、/、\和\0 (空字符)。
应全部小写。
最多64字节。
有一些数据库名是保留的,可以直接访问这些有特殊作用的数据库。
admin:从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合
config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。
3.2.2 数据库的删除
MongoDB 删除数据库的语法格式如下:

db.dropDatabase()

提示:主要用来删除已经持久化的数据库
3.3 集合操作
集合,类似关系型数据库中的表。 可以显示的创建,也可以隐式的创建。
3.3.1 集合的显式创建(了解)
基本语法格式

db.createCollection(name)

参数说明: name: 要创建的集合名称
例如:创建一个名为 mycollection 的普通集合。

db.createCollection("mycollection")

查看当前库中的表:show tables命令

show collections

show tables

集合的命名规范:
集合名不能是空字符串""。
集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。
集合名不能以"system."开头,这是为系统集合保留的前缀。
用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。
除非你要访问这种系统创建的集合,否则千万不要在名字里出现$。
3.3.2 集合的隐式创建
当向一个集合中插入一个文档的时候,如果集合不存在,则会自动创建集合。
提示:通常我们使用隐式创建文档即可。
3.3.3 集合的删除
集合删除语法格式如下:

db.collection.drop()

db.集合.drop()

返回值
如果成功删除选定集合,则 drop() 方法返回 true,否则返回 false。
例如:要删除mycollection集合

db.mycollection.drop()

3.4 文档基本CRUD
文档(document)的数据结构和 JSON 基本一样。 所有存储在集合中的数据都是 BSON 格式。
3.4.1 文档的插入
(1)单个文档插入
使用insert() 或 save() 方法向集合中插入文档,语法如下:

db.collection.insert(
<document or array of documents>,
{
writeConcern: <document>,
ordered: <boolean>
}
)

【示例】
要向comment的集合(表)中插入一条测试数据:

db.comment.insert(
{
"articleid":"100000",
"content":"今天天气真好,阳光明媚",
"userid":"1001",
"nickname":"Rose",
"createdatetime":new Date(),
"likenum":NumberInt(10),
"state":null
}
)

提示:
1)comment集合如果不存在,则会隐式创建
2)mongo中的数字,默认情况下是double类型,如果要存整型,必须使用函数NumberInt(整型数字),否则取出来就有问题了。
3)插入当前日期使用 new Date()
4)插入的数据没有指定 _id ,会自动生成主键值
5)如果某字段没值,可以赋值为null,或不写该字段。
执行后,如下,说明插入一个数据成功了。

WriteResult({ "nInserted" : 1 })

注意:
1文档中的键/值对是有序的。
2文档中的值不仅可以是在双引号里面的字符串,还可以是其他数据类型(甚至可以是整个嵌入文档)。
3MongoDB区分类型和大小写。
4MongoDB的文档不能有重复的键。
5文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。
文档键命名规范:
键不能含有\0 (空字符)。这个字符用来表示键的结尾。
.和$有特别的意义,只有在特定环境下才能使用。
以下划线"_"开头的键是保留的(不是严格要求的)。
(2)批量插入
语法:

db.collection.insertMany(
[ <document 1> , <document 2>, ... ],
{
writeConcern: <document>,
ordered: <boolean>
}
)

【示例】
批量插入多条文章评论:

db.comment.insertMany(
[
{"_id":"1","articleid":"100001","content":"我们不应该把清晨浪费在手机上,健康很重要,一杯温水幸福你我
他。","userid":"1002","nickname":"相忘于江湖","createdatetime":new Date("2019-08-
05T22:08:15.522Z"),"likenum":NumberInt(1000),"state":"1"},
{"_id":"2","articleid":"100001","content":"我夏天空腹喝凉开水,冬天喝温开水","userid":"1005","nickname":"伊人憔
悴","createdatetime":new Date("2019-08-05T23:58:51.485Z"),"likenum":NumberInt(888),"state":"1"},
{"_id":"3","articleid":"100001","content":"我一直喝凉开水,冬天夏天都喝。","userid":"1004","nickname":"杰克船
长","createdatetime":new Date("2019-08-06T01:05:06.321Z"),"likenum":NumberInt(666),"state":"1"},
{"_id":"4","articleid":"100001","content":"专家说不能空腹吃饭,影响健康。","userid":"1003","nickname":"凯
撒","createdatetime":new Date("2019-08-06T08:18:35.288Z"),"likenum":NumberInt(2000),"state":"1"},
{"_id":"5","articleid":"100001","content":"研究表明,刚烧开的水千万不能喝,因为烫
嘴。","userid":"1003","nickname":"凯撒","createdatetime":new Date("2019-08-
06T11:01:02.521Z"),"likenum":NumberInt(3000),"state":"1"}
]
);

提示: 插入时指定了_id ,则主键就是该值。 如果某条数据插入失败,将会终止插入,但已经插入成功的数据不会回滚掉。 因为批量插入由于数据较多容易出现失败,因此,可以使用try catch进行异常捕捉处理,测试的时候可以不处理。如(了解):

try {
db.comment.insertMany([
{"_id":"1","articleid":"100001","content":"我们不应该把清晨浪费在手机","userid":"1002","nickname":"相忘于江湖","createdatetime":new Date("2019-08-
05T22:08:15.522Z"),"likenum":NumberInt(1000),"state":"1"},
{"_id":"2","articleid":"100001","content":"我夏天空腹喝凉开水,冬天喝温开水","userid":"1005","nickname":"伊人憔
悴","createdatetime":new Date("2019-08-05T23:58:51.485Z"),"likenum":NumberInt(888),"state":"1"},
{"_id":"3","articleid":"100001","content":"我一直喝凉开水,冬天夏天都喝。","userid":"1004","nickname":"杰克船
长","createdatetime":new Date("2019-08-06T01:05:06.321Z"),"likenum":NumberInt(666),"state":"1"},
{"_id":"4","articleid":"100001","content":"专家说不能空腹吃饭,影响健康。","userid":"1003","nickname":"凯
撒","createdatetime":new Date("2019-08-06T08:18:35.288Z"),"likenum":NumberInt(2000),"state":"1"},
{"_id":"5","articleid":"100001","content":"研究表明,刚烧开的水千万不能喝,因为烫
嘴。","userid":"1003","nickname":"凯撒","createdatetime":new Date("2019-08-
06T11:01:02.521Z"),"likenum":NumberInt(3000),"state":"1"}
]);
} catch (e) {
print (e);
}

3.4.2 文档的基本查询
查询数据的语法格式如下:

db.collection.find(<query>, [projection])

(1)查询所有
如果我们要查询spit集合的所有文档,我们输入以下命令

db.comment.find()

db.comment.find({})

这里你会发现每条文档会有一个叫_id的字段,这个相当于我们原来关系数据库中表的主键,当你在插入文档记录时没有指定该字段, MongoDB会自动创建,其类型是ObjectID类型。
如果我们在插入文档记录时指定该字段也可以,其类型可以是ObjectID类型,也可以是MongoDB支持的任意类型。
如果我想按一定条件来查询,比如我想查询userid为1003的记录,怎么办?很简单!只 要在find()中添加参数即可,参数也是json格式,如下:

db.comment.find({userid:'1003'})

如果你只需要返回符合条件的第一条数据,我们可以使用findOne命令来实现,语法和find一样。如:查询用户编号是1003的记录,但只最多返回符合条件的第一条记录:

db.comment.findOne({userid:'1003'})

(2)投影查询(Projection Query):
如果要查询结果返回部分字段,则需要使用投影查询(不显示所有字段,只显示指定的字段)。如:查询结果只显示 _id、userid、nickname :

db.comment.find({userid:"1003"},{userid:1,nickname:1})
{ "_id" : "4", "userid" : "1003", "nickname" : "凯撒" }
{ "_id" : "5", "userid" : "1003", "nickname" : "凯撒" }

默认 _id 会显示。如:查询结果只显示 、userid、nickname ,不显示 _id :

db.comment.find({userid:"1003"},{userid:1,nickname:1,_id:0})
{ "userid" : "1003", "nickname" : "凯撒" }
{ "userid" : "1003", "nickname" : "凯撒" }

再例如:查询所有数据,但只显示 _id、userid、nickname :

db.comment.find({},{userid:1,nickname:1})

3.4.3 文档的更新
更新文档的语法:

db.collection.update(query, update, options)
//或
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ],
hint: <document|string> // Available starting in MongoDB 4.2
}
)

(1)覆盖的修改
如果我们想修改_id为1的记录,点赞量为1001,输入以下语句:

db.comment.update({_id:"1"},{likenum:NumberInt(1001)})

执行后,我们会发现,这条文档除了likenum字段其它字段都不见了,
(2)局部修改
为了解决这个问题,我们需要使用修改器$set来实现,命令如下,我们想修改_id为2的记录,浏览量为889,输入以下语句:

db.comment.update({_id:"2"},{$set:{likenum:NumberInt(889)}})

(3)批量的修改
更新所有用户为 1003 的用户的昵称为凯撒大帝 。提示:如果不加后面的参数,则只更新符合条件的第一条记录

//默认只修改第一条数据
db.comment.update({userid:"1003"},{$set:{nickname:"凯撒2"}})
//修改所有符合条件的数据
db.comment.update({userid:"1003"},{$set:{nickname:"凯撒大帝"}},{multi:true})

(3)列值增长的修改
如果我们想实现对某列值在原有值的基础上进行增加或减少,可以使用 $inc 运算符来实现。
需求:对3号数据的点赞数,每次递增1

db.comment.update({_id:"3"},{$inc:{likenum:NumberInt(1)}})

3.4.4 删除文档
删除文档的语法结构:

db.集合名称.remove(条件)

以下语句可以将数据全部删除,请慎用

db.comment.remove({})

如果删除_id=1的记录,输入以下语句

db.comment.remove({_id:"1"})

3.5 文档的分页查询
3.5.1 统计查询
统计查询使用count()方法,语法如下:

db.collection.count(query, options)

(1)统计所有记录数
统计comment集合的所有的记录数:

db.comment.count()

(2)按条件统计记录数
例如:统计userid为1003的记录条数

db.comment.count({userid:"1003"})

提示: 默认情况下 count() 方法返回符合条件的全部记录条数。
3.5.2 分页列表查询
可以使用limit()方法来读取指定数量的数据,使用skip()方法来跳过指定数量的数据。 基本语法如下所示:

db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)

如果你想返回指定条数的记录,可以在find方法后调用limit来返回结果(TopN),默认值20,例如:

db.comment.find().limit(3)

skip方法同样接受一个数字参数作为跳过的记录条数。(前N个不要),默认值是0

db.comment.find().skip(3)

分页查询:需求:每页2个,第二页开始:跳过前两条数据,接着值显示3和4条数据

//第一页
db.comment.find().skip(0).limit(2)
//第二页
db.comment.find().skip(2).limit(2)
//第三页
db.comment.find().skip(4).limit(2)

3.5.3 排序查询
sort() 方法对数据进行排序,sort() 方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。
语法如下所示:

db.COLLECTION_NAME.find().sort({KEY:1})

db.集合名称.find().sort(排序方式)

例如:
对userid降序排列,并对访问量进行升序排列

db.comment.find().sort({userid:-1,likenum:1})

提示:
skip(), limilt(), sort()三个放在一起执行的时候,执行的顺序是先 sort(), 然后是 skip(),最后是显示的 limit(),和命令编写顺序无关。

目录
相关文章
lyL
|
21小时前
|
敏捷开发 Java 测试技术
为什么要单元测试
单元测试看似拖慢进度,实则是提升研发效率的关键。本文剖析测试体系演进,揭示为何高质量单测能加速开发、保障代码质量,助力软件从“爬行”迈向“奔跑”。
lyL
15 1
 为什么要单元测试
lyL
|
20小时前
|
Kubernetes NoSQL 应用服务中间件
物理部署图
物理部署图描述系统运行时的硬件配置与软件部署结构,展现节点、构件、物件及连接关系,帮助开发与运维人员理解分布式系统的部署架构与网络通信。
lyL
23 3
 物理部署图
lyL
|
21小时前
|
uml C语言
系统时序图
时序图是UML中描述对象间消息传递时间顺序的交互图,横轴为对象,纵轴为时间。它用于展示交互流程、强调时序、体现并发过程。主要元素包括角色、对象、生命线、控制焦点和消息(同步、异步、返回)等,直观呈现系统动态协作过程。
lyL
19 1
lyL
|
18小时前
|
Java 大数据
ArrayList扩容机制
本文深入解析Java中ArrayList的add及扩容机制。首次添加元素时,容量从0扩至10;后续通过ensureCapacityInternal和grow方法实现动态扩容,每次扩容为原容量的1.5倍,借助位运算提升性能,并详解size、length等易混淆概念。
lyL
25 1
lyL
|
22小时前
|
算法 架构师 程序员
技术人对抗焦虑的加减法
本文探讨技术人如何破局成长焦虑,提出“减法”分离外界焦虑、“加法”实现认知与技能螺旋上升,并强调心力、脑力、体力三大核心能力,助力突破职业瓶颈,实现自我驱动的持续成长。
lyL
18 1
技术人对抗焦虑的加减法
lyL
|
22小时前
|
Java 测试技术 Linux
生产环境发布管理
本文介绍大型团队中基于自动化部署平台的多环境发布流程,涵盖DEV、TEST、PRE、PROD各环境职责,结合CI/CD实现高效部署与日志追踪,提升发布效率与系统稳定性。
lyL
22 0
lyL
|
22小时前
|
运维 Devops 开发工具
生产环境缺陷管理
git-poison基于go-git实现分布式bug追踪,通过“投毒-解毒-银针”机制,自动化管理多分支开发中的bug修复与发布卡点,降低协同成本,避免漏修漏发,提升发布安全性与效率。
lyL
17 0
lyL
|
22小时前
|
项目管理 开发者
业务架构图
本文介绍了业务架构图的核心概念与绘制方法,涵盖业务定义、架构分层(组织层、基础能力层、业务能力层、业务应用层)、模块划分与功能分解,并强调通过分层、分模块、分功能三步法实现业务的抽象与结构化表达,提升客户理解与开发效率。
lyL
18 0
业务架构图
lyL
|
22小时前
|
数据采集 数据建模 领域建模
领域模型图(数据架构/ER图)
本文介绍如何通过四色原型法构建领域模型,并逐步推导出数据架构中的ER图。以风控系统为例,运用时标性(MI)、参与方-地点-物品(PPT)、角色(Role)和描述(DESC)四类原型,从关键流程出发,提炼实体与关系,最终形成简洁清晰的ER图,助力数据建模。
lyL
25 0
领域模型图(数据架构/ER图)
lyL
|
20小时前
|
存储 安全 Java
One Trick Per Day
初始化Map时应避免直接指定容量,建议使用Guava的`newHashMapWithExpectedSize`或手动计算容量。禁止使用Executors创建线程池,以防OOM,推荐通过ThreadPoolExecutor或Guava方式构建。Arrays.asList返回的列表不可修改,遍历Map优先使用entrySet或forEach。SimpleDateFormat非线程安全,不应定义为static,可使用ThreadLocal或Java 8新时间API替代。
lyL
20 0
One Trick Per Day