MongoDB相关概念

业务应用场景



MongoDB简介

体系结构

数据模型

MongoDB特点

基本常用命令

案例

数据库操作

选择和创建数据库

选择和创建数据库的语法:

use 数据库名称

如果数据库不存在则自动创建并选择,数据库存在则选择

  • 创建并选择articledb

发现articledb没有显示出来

虽然没有显示,但是articledb已经在内存中了,在MongoDB中,集合只有在内容插入后才会创建! 就是说,创建集合(数据表)后要再插入一个文档(记录),集合才会真正创建。

查看当前正在使用的数据库命令

db

可以看到articledb正在被使用

MongoDB 中默认的数据库为 test,如果你没有选择数据库,集合将存放在 test 数据库中。

另外:

数据库名可以是满足以下条件的任意UTF-8字符串。

  • 不能是空字符串(“”)。
  • 不得含有’ '(空格)、.、$、/、\和\0 (空字符)。
  • 应全部小写。
  • 最多64字节。

有一些数据库名是保留的,可以直接访问这些有特殊作用的数据库。

  • admin: 从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特 定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
  • local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合
  • config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。

数据库的删除

db.dropDatabase()

集合操作

集合的显示创建(了解)

db.createCollection(name)
  • 参数说明

name:要创建的集合名称

如图成功创建 my 集合

查看当前库中的集合

show collections
或
show tables

集合的命名规范:

  • 集合名不能是空字符串""。
  • 集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。
  • 集合名不能以"system."开头,这是为系统集合保留的前缀。
  • 用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含 ,这是因为某些系统生成的集合中包含该字符。除非你要访问这种系统创建的集合,否则千万不要在名字里出现。保留字符包括:#、。保留字符包括:\#、。保留字符包括:#、、%、^、&、_、{、}、~、\

集合的隐式创建

当向一个集合中插入一个文档的时候,如果集合不存在,则会自动创建集合。 详见 文档的插入 章节。 提示:通常我们使用隐式创建文档即可。

集合的删除

db.集合名.drop()

成功删除my集合

文档基本CRUD

文档(document)的数据结构和 JSON 基本一样。

所有存储在集合中的数据都是 BSON 格式。

文档的插入

单个文档插入

使用insert() 或 save() 方法向集合中插入文档,语法如下:

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

参数:

提示:

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

出现如下,说明插入一个数据成功。

WriteResult({ "nInserted" : 1 })
  1. 文档中的键/值对是有序的。
  2. 文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。
  3. MongoDB区分类型和大小写。
  4. MongoDB的文档不能有重复的键。
  5. 文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。

批量插入

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"}]);

批量插入时由于数据较多,容易出现失败,可以使用try catch进行异常捕捉处理

文档的查询

基本格式

db.collection.find(<query>, [projection])
查询所有
db.comment.find()
或
db.comment.find({})
按一定条件查询

如查询userid为1003的记录

db.comment.find({userid:'1003'})
只返回符合条件的第一条数据
db.comment.findOne({userid:'1003'})

投影查询(Projection Query)

db.collection_name.find(query,{key1:1, key2:1, ...})

语法说明如下:

  • query:可选参数,使用查询操作符指定的查询条件;
  • key1、key2、…:为要查询或者隐藏的字段,当值为 1 时表示显示该字段,值为 0 时表示隐藏该字段。

如:查询结果只显示 _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})

统计查询

统计查询使用count()方法,语法如下:

db.collection.count(query, options)

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

db.comment.count()

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

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

分页查询

可以使用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)

查询第4、5条记录

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

排序查询

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(),和命令编写顺序无关。

比较查询

db.集合名称.find({ "field" : { $gt: value }}) // 大于: field > value
db.集合名称.find({ "field" : { $lt: value }}) // 小于: field < value
db.集合名称.find({ "field" : { $gte: value }}) // 大于等于: field >= value
db.集合名称.find({ "field" : { $lte: value }}) // 小于等于: field <= value
db.集合名称.find({ "field" : { $ne: value }}) // 不等于: field != value

例子:查询评论点赞数量大于700的记录

db.comment.find({likenum:{$gt:NumberInt(700)}})

包含查询

包含使用$in操作符。 示例:查询评论的集合中userid字段包含1003或1004的文档

db.comment.find({userid:{$in:["1003","1004"]}})

不包含使用$nin操作符。 示例:查询评论集合中userid字段不包含1003和1004的文档

db.comment.find({userid:{$nin:["1003","1004"]}})

条件连接查询

我们如果需要查询同时满足两个以上条件,需要使用$and操作符将条件进行关联。(相 当于SQL的and) 格式为:

$and:[ { },{ },{ } ]

示例:查询评论集合中likenum大于等于700 并且小于2000的文档:

db.comment.find({$and:[{likenum:{$gte:NumberInt(700)}},{likenum:{$lt:NumberInt(2000)}}]})

如果两个以上条件之间是或者的关系,我们使用$or操作符进行关联,与前面 and的使用方式相同 格式为:

$or:[ { },{ },{ } ]

示例:查询评论集合中userid为1003,或者点赞数小于1000的文档记录

db.comment.find({$or:[ {userid:"1003"} ,{likenum:{$lt:1000} }]})

文档的更新

MongoDB更新文档 (biancheng.net)

update() 方法用于更新现有文档中的值,其语法格式如下:

db.collection_name.update(<query>,<update>,{upsert: <boolean>,multi: <boolean>,writeConcern: <document>}
)

参数说明如下:

  • query:update 的查询条件,类似 SQL 中 update 语句内 where 后面的内容;
  • update:update 的对象和一些更新的操作符(如 、、、inc…)等,也可以理解为 SQL 中 update 语句内 set 后面的内容;
  • upsert:可选参数,默认值为 false,用来定义当要更新的记录不存在时,是否当作新记录插入到集合中,当值为 true 时表示插入,值为 false 时不插入;
  • multi:可选参数,默认值为 false,用来表示只更新找到的第一条记录,当值为 true 时,则把按条件查出来的多条记录全部更新;
  • writeConcern:可选参数,用来定义抛出异常的级别。

覆盖修改

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

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

执行后,我们会发现,这条文档除了likenum字段其它字段都不见了

局部修改

为了解决这个问题,我们需要使用修改器$set来实现,命令如下:

我们想修改_id为2的记录,浏览量为889,输入以下语句:

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

批量修改

更新所有用户为 1003 的用户的昵称为 凯撒大帝

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

列值增长的修改

如果我们想实现对某列值在原有值的基础上进行增加或减少,可以使用 $inc 运算符来实现。

需求:对3号数据的点赞数,每次递增1

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

文档的删除

删除文档的语法结构:

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

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

db.comment.remove({})

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

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

索引-Index

概述

索引支持在MongoDB中高效地执行查询。如果没有索引,MongoDB必须执行全集合扫描,即扫描集合中的每个文档,以选择与查询语句匹配的文档。这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。

如果查询存在适当的索引,MongoDB可以使用该索引限制必须检查的文档数。 索引是特殊的数据结构,它以易于遍历的形式存储集合数据集的一小部分。索引存储特定字段或一组字段的值,按字段值排序。索引项的排 序支持有效的相等匹配和基于范围的查询操作。此外,MongoDB还可以使用索引中的排序返回排序结果。

官网文档:https://docs.mongodb.com/manual/indexes/

了解:

MongoDB索引使用B树数据结构(确切的说是B-Tree,MySQL是B+Tree)

1.索引的类型

单字段索引

MongoDB支持在文档的单个字段上创建用户定义的升序/降序索引,称为单字段索引(Single Field Index)。 对于单个字段索引和排序操作,索引键的排序顺序(即升序或降序)并不重要,因为MongoDB可以在任何方向上遍历索引。

复合索引

MongoDB还支持多个字段的用户定义索引,即复合索引(Compound Index)。 复合索引中列出的字段顺序具有重要意义。例如,如果复合索引由 { userid: 1, score: -1 } 组成,则索引首先按userid正序排序,然后 在每个userid的值内,再在按score倒序排序。

其他索引

地理空间索引(Geospatial Index)、文本索引(Text Indexes)、哈希索引(Hashed Indexes)。

  • 地理空间索引(Geospatial Index)

为了支持对地理空间坐标数据的有效查询,MongoDB提供了两种特殊的索引:返回结果时使用平面几何的二维索引和返回结果时使用球面 几何的二维球面索引。

  • 文本索引(Text Indexes)

MongoDB提供了一种文本索引类型,支持在集合中搜索字符串内容。这些文本索引不存储特定于语言的停止词(例如“the”、“a”、“or”), 而将集合中的词作为词干,只存储根词。

  • 哈希索引(Hashed Indexes)

为了支持基于散列的分片,MongoDB提供了散列索引类型,它对字段值的散列进行索引。这些索引在其范围内的值分布更加随机,但只支 持相等匹配,不支持基于范围的查询。

2.索引的管理操作

索引的查看

返回一个集合中的所有索引的数组。

db.collection.getIndexes()
  • 示例

查看comment集合中所有的索引情况

db.comment.getIndexes()
[{"v" : 2,"key" : {"_id" : 1},"name" : "_id_","ns" : "articledb.comment"}
]

结果中显示的是默认 _id 索引。

默认_id索引:

MongoDB在创建集合的过程中,在 _id 字段上创建一个唯一的索引,默认名字为 id ,该索引可防止客户端插入两个具有相同值的文 档,您不能在_id字段上删除此索引。

注意:该索引是唯一索引,因此值不能重复,即 _id 值不能重复的。在分片集群中,通常使用 _id 作为片键。

索引的创建

在集合上创建索引。

db.collection.createIndex(keys, options)

参数说明如下:

  • keys:由键/值对组成,其中键用来定义要创建索引的字段,值用来定义创建索引的顺序,1 表示按升序创建索引,-1 表示按降序来创建索引;
  • options:可选参数,其中包含一组控制索引创建的选项,可选值如下表所示。
参数 类型 描述
background Boolean 可选参数,当值为 true 时,表示在后台构建索引,避免在创建索引的过程阻塞其它数据库操作,默认值为 false
unique Boolean 创建唯一索引,当值为 true 时表示创建唯一索引,以避免重复数据的插入,默认为 false
name string 索引的名称。如果未指定,MongoDB 将通过连接索引的字段名和排序顺序生成一个索引名称
dropDups Boolean 在建立唯一索引时是否删除重复记录,设置为 true 则表示创建唯一索引,默认值为 false,3.0 版本之后废弃
sparse Boolean 对文档中不存在的字段数据不启用索引,这个参数需要特别注意,如果设置为 true 的话,则在索引字段中不会查询出不包含对应字段的文档。默认值为 false
expireAfterSeconds integer 指定一个以秒为单位的数值,完成 TTL 设定,设定集合的生存时间
v index version 索引的版本号,默认的索引版本取决于 mongod 创建索引时运行的版本
weights document 索引权重值,数值在 1 到 99999 之间,表示该索引相对于其他索引字段的得分权重
default_language string 对于文本索引,该语言用于确定停用词列表以及词干分析器和令牌生成器的规则,默认为英语
language_override string 对于文本索引,指定文档中包含要替代默认语言的语言的字段名称,默认值为 language
单字段索引
> db.comment.createIndex({userid:1})
{"createdCollectionAutomatically" : false,"numIndexesBefore" : 1,"numIndexesAfter" : 2,"ok" : 1
}
复合索引
> db.comment.createIndex({userid:1,nickname:-1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 2,
"numIndexesAfter" : 3,
"ok" : 1
}

索引的移除

db.collection.dropIndex(index)

其中 index 用来指定要删除的索引,可以是索引名称key的形式,也可以是{key:1}的形式。

删除除了_id的所有索引

dropIndexes() 方法同样用来删除索引,与 dropIndex() 方法不同 dropIndexes() 方法可以同时删除集合中的多个索引,其语法格式如下:

db.collection_name.dropIndexes()

索引的使用

db.collection.find(query,options).explain(options)

示例:

> db.comment.find({userid:"1003"}).explain()
{"queryPlanner" : {"plannerVersion" : 1,"namespace" : "articledb.comment","indexFilterSet" : false,"parsedQuery" : {"userid" : {"$eq" : "1003"}},"winningPlan" : {"stage" : "COLLSCAN","filter" : {"userid" : {"$eq" : "1003"}},"direction" : "forward"},"rejectedPlans" : [ ]},"serverInfo" : {"host" : "9ef3740277ad","port" : 27017,"version" : "4.0.10","gitVersion" : "c389e7f69f637f7a1ac3cc9fae843b635f20b766"},"ok" : 1
}

“stage” : “COLLSCAN”, 表示全集合扫描,即扫描集合中的每个文档
ollection.find(query,options).explain(options)


示例:

db.comment.find({userid:“1003”}).explain()
{
“queryPlanner” : {
“plannerVersion” : 1,
“namespace” : “articledb.comment”,
“indexFilterSet” : false,
“parsedQuery” : {
“userid” : {
“KaTeX parse error: Expected 'EOF', got '}' at position 17: …q" : "1003" }̲ }, "winnin…eq” : “1003”
}
},
“direction” : “forward”
},
“rejectedPlans” : [ ]
},
“serverInfo” : {
“host” : “9ef3740277ad”,
“port” : 27017,
“version” : “4.0.10”,
“gitVersion” : “c389e7f69f637f7a1ac3cc9fae843b635f20b766”
},
“ok” : 1
}


"stage" : "COLLSCAN", 表示全集合扫描,即扫描集合中的每个文档

MongoDB基础-快速入门相关推荐

  1. Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 4. 函数

    什么样的程序员才是优秀的程序员?咪博士认为"慵懒"的程序员才是真正优秀的程序员.听起来不合逻辑?真正优秀的程序员知道如何高效地工作,而不是用不止境的加班来完成工作任务.函数便是程序 ...

  2. 零基础快速入门web学习路线(含视频教程)

    下面小编专门为广大web学习爱好者汇总了一条完整的自学线路:零基础快速入门web学习路线(含视频教程)(绝对纯干货)适合初学者的最新WEB前端学习路线汇总! 在当下来说web前端开发工程师可谓是高福利 ...

  3. python海龟教程_Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 7. 条件循环...

    条件循环能够让程序在条件成立时(即为真时)重复执行循环体中的语句.如果条件一直成立(即永远不会为假),则循环会一直进行下去,不会停止.如果初始时,条件不成立,则循环 1 次也不会执行.Python 中 ...

  4. 【Python零基础快速入门系列 | 03】AI数据容器底层核心之Python列表

    • 这是机器未来的第7篇文章 原文首发地址:https://blog.csdn.net/RobotFutures/article/details/124957520 <Python零基础快速入门 ...

  5. 【Python零基础快速入门系列 | 07】浪漫的数据容器:成双成对之字典

    这是机器未来的第11篇文章 原文首发链接:https://blog.csdn.net/RobotFutures/article/details/125038890 <Python零基础快速入门系 ...

  6. ROS2零基础快速入门

    ROS2入门最快需要多少时间?3天: ROS2开发一款基础机器人需要多久?3个星期: ROS2怎么才能算"精通"?不可能,3年也不行-- 如何判断一款通用性软件成熟并可以投入精力去 ...

  7. 零基础快速入门SpringBoot2.0教程 (三)

    一.SpringBoot Starter讲解 简介:介绍什么是SpringBoot Starter和主要作用 1.官网地址:https://docs.spring.io/spring-boot/doc ...

  8. 【PR】零基础快速入门教程

    [PR]零基础快速入门教程 PR(Premiere)能做什么? PR欢迎界面及新建项目 工作区及窗口说明 导入文件 建立序列 视频剪辑 添加字幕 导出视频 使用软件:Premiere2020 新年卷起 ...

  9. 0基础快速入门CSS技术栈(4)—图解详细阐述CSS的复合选择器、标签显示模式、行高、CSS背景,及最为重要的CSS三大特性附带权重计算笔试题(附详细案例源码解析过程)

    文章目录 1. 0基础快速入门CSS技术栈(4) 2. 重点提炼 3. CSS复合选择器 3.1 后代选择器(重点) 3.1.1 example01 3.2 子元素选择器 3.2.1 exmaple0 ...

最新文章

  1. 终于有人把Python讲清楚了!
  2. 虚拟内存——Windows核心编程学习手札之十四
  3. vector相关习题
  4. 蛤玮打扫教室(区间覆盖)
  5. Kotlin实战指南七:单例模式
  6. json字符串中key值下划线命名转换为驼峰命名
  7. python 多维list 排序_一行代码的优雅| Python列表生成式
  8. Android学习之在Eclipse看源代码的技巧
  9. Python稳基修炼之计算机等级考试易错概念题6(含答案)
  10. java.io.StreamCorruptedException: invalid type code: AC错误的解决方法
  11. 使用Redis的有序集合实现排行榜功能
  12. mysql 历史记录查询
  13. javascript中的this指向问题
  14. win10、Ubuntu双系统删除Ubuntu的方法
  15. 利用googlemap查询经纬度
  16. 自定义打卡签到view
  17. java神雕侠侣1古墓情缘游戏攻略_《神雕侠侣》古墓派加点详解攻略
  18. 2022年12月蓝桥STEMA评测C++中级组编程题
  19. 郝夫曼(Huffman)树及其应用
  20. 柱状图标签在柱的上方怎么进行展示

热门文章

  1. 虚幻4配置AUTODESK 3DS MAX
  2. 北京国家会计学院副教授王亚星:智能会计和价值财务有力支撑企业高质量发展
  3. 第十一届泰迪杯数据挖掘挑战赛-产品订单数据分析B题(完整代码)--数据处理--第一部分(下一部分请看下一博客)
  4. 给java语言实现移位密码加密过程
  5. 算法导论NO.1:算法基础
  6. 三边测量法:通过三点坐标和到三点的距离,返回第4点位置
  7. Windows PC、 Linux、 Android、 iOS多平台支持H5无插件播放RTSP摄像机解决方案
  8. esp8266 wifi模块固件烧写说明
  9. Xcode报错:No such module SwiftyJSON
  10. i love you 浪漫字体复制_六个字的简短情话 我姓王配一句情话