MongoDB-操作语法基础版V1.0.0

MongoDB-基本操作语法

1.MongoDB概念

1.1.业务场景

  • 回顾:传统的关系型数据库(Mysql),在数据操作的’三高’需求以及应对Web2.0网站需求面前,显得力不从心。
  • 解释:三高
    • 对数据库高并发读写的需求 - High performance;
    • 对海量数据的高效存储和访问的需求 - Huge Storage;
    • 对数据库的高可扩展和高可用性的需求 - High Scalability && High Avallability;
  • 解决:MongoDB应对三高
    • 应用场景
      • 社交场景:存储用户信息,用户发表朋友圈信息,通过地理位置索引实现附近的人,地点等功能。
      • 游戏场景:用户信息,用户装备,积分等直接以内嵌文档的形式存储,高效存储和访问
      • 物流场景:存储订单信息,订单状态在运送过程中会不断更新,以MongoDB内嵌数组的形式存储,一次查询可以将订单所有的变更读取出来。
      • 物联网场景:存储智能设备信息,设备的日志信息,并对这些信息多维度分析。
      • 视频直播:存储用户信息,点赞互动信息等。
    • 场景特点
      • 数据量大
      • 读写操作频繁
      • 价值较低,事务性要求不高
  • 选择:何时选择MongoDB(满足2条以上即可选择)
    • 不需要事务,复杂的join-----可使用MongoDB内嵌的形式
    • QPS达到3000+
    • 数据存储在TB-PB级别
    • 大量文本查询操作
    • 应用需要99.99%高可用

1.2.MongoDB简介

  • MongoDB是一个非关系型数据库,开源,高性能,无模式的文档型数据库;
  • MongoDB数据结构类似于JSON格式的BSON,可存比较复杂的数据类型;
  • MongoDB记录的是一个文档,是由字段和值对(filed:value)组成的数据结构,filed为字符型,value为基本数据类型,文档,普通数组,文档数据等等。

1.3.MongoDB与Mysql

1.3.1数据结构区别

在这里插入图片描述

SQLMongoDB说明
databasedatabase数据库
tablecollection数据库/集合
rowdocument数据记录行/文档
columnfield数据字段/域
indexindex索引
table joins表连接,MongoDB不支持
嵌入文档MongoDB通过嵌入式文档代替多表连接
primary keyprimary key主键,MongoDB自动将id字段设置为主键

2.常用命令

2.1选择和创建数据库

2.1.1.选择和创建数据库的语法格式

use 数据库名称 --如果数据库不存在则自动创建

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

show dbs
show databases

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

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

注意:数据库命名规则:满足以下条件的任意UTF-8字符串

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

自带三个库:

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

2.2删除数据库

2.2.1.删除数据库的语法格式

db.dropDatabase()   -- 主要用来删除已经持久化的数据库 db泛指当前使用数据库,删除的是当前使用db

2.3集合操作

2.3.1.集合显式创建(了解即可)

db.createCollection(name)  -- 基本语法
例如:db.createCollection("mycollection") -- 创建名为mycollection的普通集合
  • 参数说明:name-要创建的集合名称
  • 查看当前库中的表:
show collection
show tables
  • 集合命名规范:
    • 集合名不能是空字符串""
    • 集合名不能含有\0字符(空字符),这个字符表示集合名的结尾
    • 集合名不能以"system."开头,这是为系统集合保留的前缀

2.3.2.集合的隐式创建

  • 当向一个集合中插入一个文档的时候,如果集合不存在,则会自动创建集合。
  • 注意:通常使用隐式创建

2.3.3.删除集合

db.collection.drop() -- 删除集合语法格式
例如:db.douglascollection.drop() --删除名为douglascollection集合
注意:如果成功删除选定集合,则drop()方法返回true,否则返回false

2.4文档CURD

  • 文档(document)的数据结构和JSON基本一致,所有存储在集合中的数据都是BSON格式。
2.4.1.插入单个文档
  • 单个文档插入
    • 使用insert()或save()方法向集合中插入文档,语法如下:
db.collection.insert(
    <document or array of documents>
    {
    	writeConcern:<document>,
    	ordered:<boolean>
    }
)
  • 参数说明:
参数类型说明
documentdocument/array要插入到集合中的文档或文档数组(json格式)
writeConcerndocument选择插入的性能级别,详情可见:
orderedboolean可选,如果为true,则按顺序插入数组中的文档,如果其中一个文档出现错误,MongoDB将返回而不处理数组中其余文档。如果为false,则执行无序插入,如果其中一个文档出现错误,则继续处理数组中的主文档。在2.6+版本中默认true
  • 【案例】:向douglas集合(表)中插入一条数据:
db.douglas.insert(
	{
        "number":"516300284106",
        "name":"LD",
        "content":"好好学习,天天向上",
        "workNo":"1001",
        "createtime":new Date(),
        "likenum":NumberInt(10),
        "state":null
	}
)
  • 【注意】:

    • douglas集合如果不存在,则会隐式创建;
    • mongoDB中的数字,默认是double类型,如果存整型,必须使用函数NumberInt(整型数字),否则取出会产生问题;
    • 插入当前日期使用new Date()函数;
    • 插入的数据没有指定_id,会自动生成主键值;
    • 如果某字段没有值,可以赋值null,或不写该字段
  • 【执行结果】

WriteResult({"nInserted":1})

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YA4xMpUL-1650702905411)(C:\Users\代高成\AppData\Roaming\Typora\typora-user-images\1650344841326.png)]

2.4.2.插入批量文档
  • 【语法】
db.collection.insertMany(
	[<document 1>,<document 2>,...]
	{
        writeConcern:<document>,
        ordered:<boolean>
	}
)
  • 【参数】
    • 与单个插入参数一致
  • 【案例】
db.douglas.insertMany([
    {
        _id:"1",
        "number":"516300284107",
        "name":"YMWM",
        "content":"以梦为马,不负韶华",
        "workNo":"1003",
        "createtime":new Date(),
        "likenum":NumberInt(99),
        "state":"离线"
	},
	{
        _id:"2",
        "number":"516300284108",
        "name":"WLKQ",
        "content":"少年-未来可期",
        "workNo":"1004",
        "createtime":new Date(),
        "likenum":NumberInt(88),
        "state":"在线"
	},
	{
        _id:"3",
        "number":"516300284109",
        "name":"LS",
        "content":"请问你今天努力了么?",
        "workNo":"1005",
        "createtime":new Date(),
        "likenum":NumberInt(66),
        "state":"连接中"
	}
]);
  • 【注意】
    • 插入时指定了_id,则逐渐就是该指定值。
    • 如果某条数据插入失败,将会终止插入,但是已经插入成功的数据不会回滚。
    • 因此批量插入由于数据较多容易出现失败,因此,可以使用try catch进行异常捕获处理,如下:
try{
    db.douglas.insertMany([
    {
        _id:"1",
        "number":"516300284107",
        "name":"YMWM",
        "content":"以梦为马,不负韶华",
        "workNo":"1003",
        "createtime":new Date(),
        "likenum":NumberInt(99),
        "state":"离线"
	},
	......
]);
}catch(e){
    print(e)
}

在这里插入图片描述

2.4.3.查询文档
db.collection.find(<query>,[projection])  -- 查询数据的语法格式
  • 【参数】:
参数类型说明
querydocument可选,查询指定的筛选器,若要返回集合中的所有文档,请省略此参数或传递空文档({})。
projectiondocument可选,指定要在与查询筛选器匹配的文档中返回的字段(投影)。若要返回匹配文档中的所有字段,请省略此参数。
  • 【案例】:
    • 1.查询所有:两种方式
db.douglas.find()
db.douglas.find({})
2.4.3.1.单个条件查询
  • 【语法】两种方式:
db.douglas.find({"workNo":"1005"}) -- 查询workNo为1005的信息

2.4.3.2.投影查询
  • 【语法】 Projection Query
db.douglas.find({workNo:"1005"},{number:1,name:1}) -- 查询结果只显示 _id,number,name
  • 【作用】

    • 查询返回部分字段,则选择投影查询(不显示所有字段,只显示指定的字段)
  • 【注意】默认_id会显示

    • 查询只显示结果,不需要_id
db.douglas.find({workNo:"1005"},{number:1,name:1,_id:0})
2.4.4.更新文档
2.4.4.1.更新文档语法
  • 【语法】两种方式
db.collection.update(query,update,options)
db.collection.update(
	<query>,
	<update>,
	{
        upsert:<boolean>,
        multi:<boolean>,
        writeConcern:<document>,
        collation:<document>,
        arrayFilters:[<filterdocument>,...],
        hint:<document|string>
	}
)
  • 【参数】:
参数类型说明
querydocument更新的选择条件,可以使用与find()方法中相同的查询选择器,类似sql的update查询内where后面的。
updatedocument ||pipeline要应用的修改,该值可以是:包含更新运算符表达式的文档,或仅包含:对的替换文档。
upsertboolean可选,如果为true,则在没有与查询条件匹配的文档时创建新文档。默认为false,如果找不到匹配项,则不会插入新文档。
multiboolean可选,如果为true,则更新符合查询条件的多个文档。如果为false,则更新一个文档,默认值为false。
writeConcerndocument可选,表示写问题的文档,抛出异常的级别。
collectiondocument可选,
arrayFiltersarray可选,一个筛选文档数组,用于确定要为数组字段上的更新操作修改哪些数组元素。
hintdocument||string可选,指定用于支持查询谓词的索引的文档或字符串。该选项可以采用索引规范文档或索引名称字符串。如果指定的索引不存在,则说明操作错误。
2.4.4.2.覆盖修改
  • 【语法】修改id为1的数据,字段likenum=55,如下:
db.douglas.update({_id:"1"},{likenum:NumberInt(55)})
  • 【结果】数据只剩下likenum字段了,其余字段不见了,因为覆盖修改,相当于给id=1重新写入数据。
2.4.4.3.局部修改
  • 【语法】为了解决覆盖修改造成其余字段丢失,需要用局部修改命令如下:
db.douglas.update({_id:2},{$set:{likenum:NumberInt(999)}})
  • 【结果】符合需求
2.4.4.4.批量修改
  • 【语法】更新所有用户workNo为1003的name值为:douglas
-- 如下命令默认只会修改符合条件的第一条数据
db.douglas.update({workNo:"1003"},{$set:{name:"douglas"}})
-- 修改所有符合条件的数据
db.douglas.updateMany({workNo:"1003"},{$set:{name:"douglas"}}),{multi:true}
  • 【结果】如果不加后面参数,则只更新符合条件的第一条记录
2.4.4.5.列值增长修改
  • 【语法】:实现在某列值的原有值的基础上进行增加或减少,可以使用$inc运算符实现
  • 【需求】:对id=3数据的likenum值每次递增1
db.douglas.update({_id:"3"},{$inc:{likenum:NumberInt(1)}})
2.4.5.删除文档
  • 【语法】
db.集合名称.remove(条件)
  • 【案例】删除整个数据库 慎用
db.douglas.remove({})
  • 【案例】删除id=1的记录,如下:
db.douglas.remove({_id:"1"})  -- 目前新版本已经弃用
db.douglas.deleteOne({_id:"1"}) -- 新版本语法-删除单条数据
db.douglas.deleteMany({workNo:"1003"}),{multi:true} -- 批量删除

2.5分页查询数据

2.5.1.统计查询
  • 【语法】统计查询使用count()方法
db.douglas.count(query,options)
  • 【参数】
参数类型说明
querydocument查询选择条件
optionsdocument可选.用于修改计数的额外选项.
  • 【案例】

    • 统计所有记录:
    db.douglas.count() -- 统计douglas集合的所有的记录数据
    
    • 按条件统计记录数据:
    db.douglas.count({workNo:"1002"})  -- 统计workNo为1002的记录数据
    
2.5.2.分页列表查询
  • 【语法】 使用limit()方法来读取指定数量的数据,使用skip()方法,来跳过指定数量的数据.
db.集合名称.find().limit(2).skip(4)  -- 分页查询,每页查询2条,从第四条开始
  • 【案例】
    • 查询一个集合前10条数据
db.douglas.find().limit(10);
--10条数据不要其余的数据返回
db.douglas.find().ip(10);
-- 分页查询:需求 每页2, 第二页开始的时候:跳过前两条数据
db.douglas.find().skip(0).limit(2)  -- 第一页
db.douglas.find().skip(2).limit(2)  -- 第二页
2.5.3.排序查询
  • 【语法】sort()方法进行排序,sort()方法可以通过指定参数排序的字段,并使用1和-1来指定排序方式.其中1为升序排列,而-1为降序排列;
db.douglas.find().sort({workNo:1})  --查询所有数据,且根据workNo进行升序排列
db.集合名.find().sort(排序方式)
  • 【案例】对workNo降序排列,并对点赞量likenum进行升序排列
db.douglas.find().sort({workNo:-1,likenum:1})
  • 【注意】
    • skip(),limit(),sort()三个放在一起执行的时候,执行的顺序是先sort(),然后skip(),最后是显示的limit(),和命令编写顺序无关;

2.6高级查询

2.6.1.正则的复杂条件查询
  • 【模糊查询语法】
db.集合.find({字段:/正则表达式/})
db.douglas.find({name:/正则表达式/})
  • 【案例】查询name包含"d"的所有文档
db.douglas.find({name:/d/})
db.douglas.find({name:/^d/})   -- 查询name字段以"d"开头的
2.6.2.比较查询
  • 【语法】<,<=,>,>=
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	
  • 【案例】
db.douglas.find(likenum:{$gt:NumberInt(66)})  -- 查询likenum>66的数据
2.6.3.包含查询
  • 【语法】使用 i n 包 含 操 作 符 , in包含操作符, innin不包含操作符
db.douglas.find({workNo:{$in:["1003","1004"]}}) -- 查询集合中workNo包含1003,1004的文档
db.douglas.find({workNo:{$nin:["1003"]}})  -- 查询集合中workNo不包含1003的文档
2.6.4.条件连接查询
  • 【and语法】当查询同时满足两个以上条件,需要使用$and操作符将条件关联
$and:[{},{},{}]   -- 多个条件格式
db.douglas.find({$and:[{likenum:{$gte:NumberInt(66)}},{likenum:{$lt:NumberInt(100)}}]})     --查询大于等于66 并且小于 100的数据
  • 【or语法】两个以上条件之间是或者的关系
$or:[{},{},{}]
db.douglas.find({$or:[{workNo:"1003"},{likenum:{$lt:NumberInt(88)}}]}) --查询workNo=1003或likenum<88的数据

2.7常用命令小结

use.数据库名称    -- 选择切换,创建数据库;
db.集合名称.insertOne({})  -- 新增单条数据
db.集合名称.insertMany({}) -- 批量新增数据
db.集合名称.find({})       -- 全部数据查询
db.集合名称.find({条件})    -- 全部查询/条件查询
db.集合名称.findOne({条件})    -- 查询符合条件的第一条记录
db.集合名称.find({条件}).limit(条数)  -- 查询符合条件的前几条记录
db.集合名称.find({条件}).skip(条数)   -- 查询符合条件的跳过的记录
db.集合名称.update({条件},{修改后的数据}) -- 根据条件更新整条数据
db.集合名称.update({条件},{$set:{要修改部分的字段:value}})  -- 修改部分字段值
db.集合名称.update({条件},{$inc:{自增字段:自增值}})         -- 修改数据并自增某字段值
db.集合名称.remove({条件})  -- 删除数据
db.集合名称.count({条件})   -- 条件查询
db.集合名称.find({字段名称:/正则表达式/})  -- 模糊查询
db.集合名称.find({字段名称:{$gt:}})     -- 条件比较运算
db.集合名称.find({字段名:{$in:[1,值2]}})   -- 包含查询
db.集合名称.find({字段名:{$nin:[1,值2]}})  -- 非包含查询
db.集合名称.find({$and:[{条件1},{条件2}]})   -- 条件and链接查询
db.集合名称.find({$or:[{条件1},{条件2}]})    -- 条件or链接查询

3.索引

3.1索引概念

  • 有无索引区别
    • 没有索引,MongoDB必须执行全集合扫描,即扫描集合中的每个文档,查询效率非常低。
    • 使用索引,限制必须检查的文档数。进行高效查询
  • 数据结构
    • 索引以易于遍历的形式存储集合数据集的一小部分,存储特定字段或一组字段的值,按字段值排序。
    • 索引项的排序支持有效的相等匹配和基于范围的查询操作。
    • MongoDB支持使用索引中的排序返回排序结果。
    • B-Tree数据结构

3.2索引类型

3.2.1.单字段索引
  • MongoDB支持在文档的单个字段上创建用户定义的升序/降序索引,称为单字段索引(Single Field Index);
  • 对于单个字段索引和排序操作:
    • 索引键的排序顺序(即升序或降序)并不重要,因为MongoDB可以在任何方向上遍历索引。
3.2.2.复合索引
  • MongoDB支持多个字段的用户定义索引,即复合索引(Compound Index);
  • 复合索引中列出的字段顺序具有重要意义。
例如:复合索引由:{userid:1,score:-1}组成,则索引首先按userid正序排序,然后在每个userid的值内,再按score倒序排序。
3.2.3.其它索引
  • 地理空间索引(Geospatial Index)
    • 为了支持对地理空间坐标数据的有效查询,MongoDB提供了两种特殊的索引:
      • 返回结果时使用平面几何的二维索引;
      • 返回结果时使用球面几何的二维球面索引;
  • 文本索引(Text Indexes)
    • MongoDB提供了一种文本索引类型,支持在集合中搜索字符串内容。
    • 索引不存储特定语言的停止词(‘the’,‘a’,‘or’),而将集合中的词作为词干,只存储根词。
  • 哈希索引(Hashed Indexes)
    • 为了支持基于散列的分片,MongoDB提供了散列索引类型,它对字段值的散列进行索引。
    • 索引在其范围内的值分布更加随机,但只支持相等匹配,不支持基于范围的查询。

3.3索引操作

3.3.1.查看索引
  • 【语法】
db.集合名称.getIndexes();  -- 返回一个集合中的所有索引的数组。
  • 【案例】
db.douglas.getIndexes();
3.3.2.创建索引
  • 【语法】
db.集合名称.createIndex(keys,options)  -- 指定创建单个索引
db.集合名称.createIndex({userid:1,likenum:-1}) -- 创建复合索引 userid升序索引 likenum降序

  • 【案例】
db.douglas.createIndex({userid:1}) -- 创建douglas集合升序索引userid
3.3.3.删除索引
  • 【语法】
db.集合名称.dropIndex(index)   -- 删除指定索引
db.集合名称.dropIndexes()      -- 删除所有索引
  • 【案例】
db.douglas.dropIndex({userid:1})   -- 删除douglas集合中userid字段上的升序索引

3.4索引使用

3.4.1.执行计划
  • 【语法】
db.集合名称.find(query,options).explain(options)  

说明:分析查询性能(Analyze Query Performance)通常使用查询计划(解释计划,Explain Plan)来查看查询的情况;分析查询耗时,是否基于索引查询等。

  • 【案例】执行索引查询计划:
db.douglas.find({userid:"1003"}).explain()
3.4.2.涵盖查询
  • 当查询条件和查询的投影仅包含所有字段时,MongoDB直接从索引返回结果,而不扫描任何文档或将文档带入内存,这样的覆盖查询可以非常有效。
  • 【案例】
db.douglas.find({userid:"1003"},{userid:1,_id:0})

Index({userid:1}) – 创建douglas集合升序索引userid


#### 3.3.3.删除索引

- 【语法】

```js
db.集合名称.dropIndex(index)   -- 删除指定索引
db.集合名称.dropIndexes()      -- 删除所有索引
  • 【案例】
db.douglas.dropIndex({userid:1})   -- 删除douglas集合中userid字段上的升序索引

3.4索引使用

3.4.1.执行计划
  • 【语法】
db.集合名称.find(query,options).explain(options)  

说明:分析查询性能(Analyze Query Performance)通常使用查询计划(解释计划,Explain Plan)来查看查询的情况;分析查询耗时,是否基于索引查询等。

  • 【案例】执行索引查询计划:
db.douglas.find({userid:"1003"}).explain()
3.4.2.涵盖查询
  • 当查询条件和查询的投影仅包含所有字段时,MongoDB直接从索引返回结果,而不扫描任何文档或将文档带入内存,这样的覆盖查询可以非常有效。
  • 【案例】
db.douglas.find({userid:"1003"},{userid:1,_id:0})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

以梦为馬Douglas

您的鼓励是对我最大的支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值