MongoDB——基本命令

Posted 陈希瑞

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MongoDB——基本命令相关的知识,希望对你有一定的参考价值。

基本命令

一、数据库常用命令

1、查看命令提示


2、切换/创建数据库

切换到名称为 mydb 的数据库,如果该数据库不存在,则会自动新建。

MongoDB 中默认的数据库为 test ,如果没有创建新的数据库就执行集合或者文档操作,数据将存放在 test 数据库中。

还有一种切换数据库的方法是,进入 mongo 客户端时就指定数据库名,例如:

3、查询所有数据库

4、删除当前使用数据库

5、从指定主机上克隆数据库(4.0版本及以下适用)

db.cloneDatabase("192.168.199.9");

将指定机器上的同名数据库的数据克隆到当前数据库,例如当前是 test 数据库,命令会192.168.199.9 服务器中的 test 数据库克隆到本机的 test 数据库中。

6、从指定的机器上复制指定数据库数据到某个数据库(4.0版本及以下适用)

db.copyDatabase( "mydb", "temp","192.168.199.9");

将192.168.199.9的 mydb 的数据复制到本机 temp 数据库中。

7、查看当前使用的数据库

8、显示当前 db 状态

该命令显示数据库的统计信息,包括集合数量、平均文档大小、数据大小、索引数量和大小等。

9、当前 db 版本

10、查看当 db 的链接机器地址

11、清除错误记录

二、集合

1、创建一个集合

或者带参数创建固定集合:

在执行文档写入操作时,如果集合不存在,则会自动创建集合,所以 一般比较少使用创建集合命令,除非是创建固定集合。

• capped :是否启用集合限制,有两种选择: true 或false ,为 true 时启用限制创建为固定集合;如果开启需要制定一个限制条件,默认为 false ,不启用固定集合。

• size :限制集合使用空间的大小,默认为没有限制。

• max :集合中最大条数限制,默认为没有限制。

• autolndexId :是否使用 id 作为索引,有两种选择: true 或false ,默认为 true ,使用_id 作为索引。

注意 : size 的优先级比 max 要高。

2、显示当前数据库中的集合

3、使用集合

注意当集合名称为全数字时不能使用 db.mycoll 集合的方式,例如 db.123 报错,可以使用 db.getCollection(" 123" )。

4、查看集合命令帮助文档

5、查询当前集合的数据条数

6、查看集合数据大小

显示出的数字的单位是字节,因此如果需要转换单位为KB需要除以 1024

7、查看集合索引大小

8、查看为集合分配的空间大小,包括未使用的空间

9、显示集合总大小,包括索引和数据的大小和分配空间的大小

10、显示当前集合所在的 db

11、显示当前集合的状态

当前mydb数据库中状态数据太多,不方便截图,特将数据库换到test后执行此命令。

12、集合的分片版本信息

13、集合重命名

将mycoll重命名为users,集合名为纯数字时,只能使用 db.getCollection(“mycoll”).renameCollection这种方式。

14、显示当前 db 所有集合的状态信息

db,printCollectionStats();

15、删除当前集合

三、文档

(1)写入文档:

db.user.insert(“name”:“joe”);

db.user.save(“name”:“joe”);

​ save与insert 的区别:

​ 使用 save 时,如果集合中已经有具有相同id字段的文档,则会更新它;如果没有,则写入。

​ 使用 insert 时,如果集合中已经有具有相同id字段的文档,则会报错 E11000 duplicate key error collection ;如果没有, 则写入。

(2)查看文档

db.user.find();

(3)更新文档

可使用save()更新集合中的文档,通过_id匹配文档,用新传入的文档替换掉已有文档。

也可使用update() 方法更新已存在的文档。语法格式如下:

参数说明:

query : update的查询条件,类似sql update查询内where后 面的内容。

update : update的对象和一些更新的操作符(如 , , ,inc…) 等,也可以理解为sql update查询内set后面的内 容。

upsert : 可选,这个参数的意思是,如果集合中不存在满足 query条件的文档,是否插入新文档,true为插入, 默认是false,不插入。

multi : 可选,默认是false,只更新找到的第一条记录,如果这 个参数为true,就把按条件查出来多条记录全部更新。

writeConcern :可选,抛出异常的级别。

writeConcern参数说明:使用NORMAL模式参数(默认),可以使得写操作效率非常高。但是如果此时服务器出错,也不会返回错误给客户端,而客户端会误认为操作成功。因此在很多重要写操作中需要使用WriteConcern.SAFE模式,保证可以感知到这个错误,保证客户端和服务器对一次操作的正确性认知保持一致。

db.user.update("myName":"joe",$set:"age":20,"company":"google",true,multi:true, ,WriteConcern.SAFE);

db.user.update("myName":"joe",$set:"age":20,"company":"google",true,true, WriteConcern.SAFE);

db.user.update("myName":"joe",$set:"age":20,"company":"google",true, WriteConcern.SAFE);

db.user.update("myName":"Joe",$set:"age":20,"company":"google",multi:1);

(4)删除文档

findAndModify方法的语法如下:

runCommand()函数可以执行mongoDB中的特殊函数,但一次只能处理一个文档。findAndModify作为一个特殊的函数,它返回update或remove后的文档。 runCommand方法的语法如下:

(5)更新并返回文档:

​ findAndModify() 方法

​ runCommand() 方法

(6)删除文档并返回文档

findAndModify方法、runCommand()方法

(7)查询满足条件的文档数量

四、索引

(1)创建索引

MongoDB使用 createIndex() 方法来创建索引。

注意:在 3.0.0 版本前创建索引方法为 db.collection.ensureIndex(),之后的版本使用了 db.collection.createIndex() 方法,ensureIndex() 还能用,但只是 createIndex() 的别名。

语法

createIndex()方法基本语法格式如下所示:

db.collection.createIndex(keys, options)

语法中 Key 值为你要创建的索引字段,1 为指定按升序创建索引,如果你想按降序来创建索引指定为 -1 即可。

先用save方法把以下数据放入user集合中

“myName”:“joe”,age:14,

“myName”:“ad”,age:14,

“myName”:“ad”,age:38,

“myName”:“ad”,age:24,

“myName”:“ab”,age:14

使用db.user.createIndex(myName: 1, age: -1)创建复合索引,表示集合中的所有文档先根据myName升序排列, myName同组的文档根据age降序排列。

按照索引文档的排列方式如下:

“myName”:“ab”,age:14

“myName”:“ad”,age:38

“myName”:“ad”,age:24

“myName”:“ad”,age:14

“myName”:“joe”,age:14

—————————————————————————分割线———————————————————————

Background参数,true表示在后台创建索引,默认为false

在后台创建索引的原因:

在前台创建索引期间会锁定数据库,会导致其它操作无法进行数据读写;在后台创建索引会定期释放写锁,从而保证其它操作的运行,但是后台操作会在耗时更长,尤其是在频繁进行写入的服务器上。

—————————————————————————分割线———————————————————————

Unique参数,true表示唯一索引,要求对应的key在集合中是唯一标识的,默认为false。如果唯一索引创建时,对应的key存在重复项,命令会报错。

dropDups参数,3.0+版本已废弃。在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引,默认值为 false。

Sparse参数,对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,不包含对应字段的文档和对应字段值为空的文档不会进入索引。默认值为 false。

(2) 查询集合所有索引

(3)查看集合总索引记录大小

(4)读取当前集合的所有index信息

(5)删除指定索引

(6)删除集合所有索引

五、基本查询

1、find简介

用find()查询文档,以非结构化的方式显示返回文档

在查询语句后加上pretty()方法,以结构化的方式显示返回文档

Find()语法:find(查询条件,指定返回字段)

两个参数必须为文档,_id字段默认返回


新方法:

2、游标

游标是一种容器,一般用于遍历数据集,可存放find执行结果。放入游标的数据无论是多少条,每次只能提取一条数据。通过hasNext()判断是否有下一条数据,next()获取下一条数据。

游标实现了迭代器接口,可使用forEach函数


六 、条件查询

find()第一个参数是查询条件文档,查询条件文档需要满足BSON格式,MongoDB提供了多种查询方式。

1、与操作

  • 未查询出同时满足myName为ad和age为16的文档
  • 查询出同时满足myName为ad和age为14的文档

2、或操作 $or

  • 查询出age为38或者age为24的文档,满足其中一个条件即可。

3、大于 $gt (greater than)

  • 查询age大于20的文档。

4、小于 $lt (less than)

  • 查询age小于20的文档。

5、大于等于 $gte (greater than or equal to)

  • 查询age大于等于20的文档

6、小于等于 $lte (less than or equal to)

  • 查询age小于等于20的文档

7、类型查询 $type

$type操作符用来查询文档中字段与指定类型匹配的数据,并返回结果。

使用方式如下:

  • 查询myName字段为string类型存在的文档

8、是否存在 $exists

  • 查询age字段存在的文档

9、取模 $mod

  • 查询age字段取模10等于0的数据

10、不等于 $ne (not equal to)

  • 查询age不等于20的数据

11、包含 $in

  • 查询myName的值被包含在[“图图”,“小仙女”,“ab”]数组中的文档

12、不包含 $nin

  • 查询myName的值不被包含在[“图图”,“小仙女”,“ab”]数组中的文档

13、反匹配 $not:

以上所有字段查询操作都能取非,比如:

七、特定类型查询

1、null

注意null前后不加引号!!

2、正则查询(模糊查询)

正则表达式被用来检索、替换那些==符合某个模式(规则)==的文本。

常用的正则表达式基本符号和代码见教材

例子:

\\S+

<a[^>]+>

^J

of despair$

^abc$

notice

,[a-zA-Z0-9]$

MongoDB中正则表达式的用法:

3、嵌套文档

3.1 精准匹配查询

3.2 点查询

4、数组

用update方法更新文档,插入favorite_number字段

4.1数组单元素查询

4.2 $all 数组多元素查询

4.3 $size 数组长度查询

4.4 $slice返回数组子集

$slice需要放在第二个参数作为限定参数

因为第一个参数为查询条件

将$slice的值设置为-2,表示什么?

-2表示:从数组右边开始截取2个元素

4.5 精确匹配查询

4.6 点查询

用于查询复杂的数组,如数组中包含子文档。

4.7 索引查询*

注意索引字段要加双引号,如“favorite_number.0”

*Number.0表示的是数组的下标

4.8 元素查询 $elemMatch

方法1:

方法2:

八、高级查询$where

之前的查询条件都是键值对的BSON格式,对于复杂的查询条件BSON格式无法胜任。MongoDB提供$where操作器,可执行任意javascript作为查询条件的一部分,来实现BSON格式无法胜任的复杂查询。

JavaScript与$where结合使用

查询age>18的文档,有以下几种方式

$where最典型的应用:一个文档,如果有两个键的值相等,就选出来,否则不选:

九、查询辅助

1、条件限制limit

2、起始位置skip

3、排序sort

十、修改器

1、$set

$set用于指定修改的字段和值。

把myName为joe的文档age字段值修改为18,company字段的值修改为Huawei

multi:1表示更新多条记录,也可使用multi:true

2、$unset

$unset用于取消字段,也就是删除文档中的某个字段。

把myName为joe的文档company字段去掉。

3、$inc

$inc用于增加或减少数值

把myName为joe的文档age增加50。

4、$push

把元素追加到数组字段中。如果字段不存在,会新增该字段,该字段的值为数组。

5、$pushAll

p u s h A l l 已 与 pushAll已与 pushAllpush合并, $pushAll不再使用

用$push把多个元素追加到数组中,追加的元素会作为子数组插入到数组中。如果想要将多个元素直接追加到数组中,需要搭配$each使用。

$push搭配​$each使用,实现多个元素直接追加到数组中。

6、$pull

删除数组中满足条件的元素。如果有多个元素满足条件,则都删除。与$push为反操作。

7、$addToSet

追加一个原数组中没有的元素到数组中。注意与$push的区别。

8、$pop

删除数组中的第一个元素(-1)或最后一个元素(1)

9、$rename

修改字段名称

10、$bit

位运算,将十进制转换为二进制,通过and按位与,or按位或,xor按位异或,得到返回值。

常用场景:

and 1: 取二进制数的末尾数,可用于判断奇偶(偶数末尾为0,奇数末尾为1)

Or 1: 将二进制数尾数强行变为1

异或同一个数两次结果等于本身,即(a xor b)xor b=a:可用于简单加密

十一、原生聚合运算

1、数量查询count

  • 统计满足条件的文档数量

  • 分片集群中count统计的数量不准确

2、不同值distinct

  • 用于找出指定字段的所有不同值

  • 需要指定集合、字段

3、分组group

PuTTy: Option > encoding > UTF-8

Group方法已弃用

4、灵活统计MapReduce

一些高级聚合函数,如sum、average、max、min、variance、standard deviation等需要MapReduce来实现

MapReduce语法

举例:使用mapreduce完成教材26页例子

  • 第一步:插入文档

一般写法

源码:

db.student.mapReduce(
 function()
 emit(
 this.class,
 age:this.class,count:1
 );
 ,
 function (key,values)
 var count = 0;
 values.forEach(function(val)
 count += val.count;
 );
 return class:key,count:count;
 ,
 
 out:inline:1,
 finalize:function(key,reduced)
 return"班级":reduced.class,"人数":reduced.count;
 
 
 )

简单写法

源码

db.student.mapReduce(
 function()emit(this.class,1);,
 function(key,values)return Array.sum(values);,
 out:inline:1
)

练习1:运用MapReduce统计user集合中,每个年龄有多少人?

练习2:运用MapReduce统计student集合中,男生女生各有多少人?

十二、聚合管道

管道操作器

管道阶段(pipeline stages)需要使用管道操作器/符识别。管道操作器类型很多。

1、$project

修改输入文档的结构

Aggregate使用0值表示结果集中排除字段,1值表示结果集中包含字段,可直接给字段赋值来修改字段值,可直接给新字段赋值来新建字段 ,赋值时可用==$==引用原字段的值。

2、$match

用于过滤数据,只输出符合条件的文档。

3、$limit

用来限制MongoDB聚合管道返回的文档

4、$skip

跳过指定数量的文档,返回余下的文档。

5、$unwind

将文档中的某个数组字段拆分成多条,每条包含数组中的一个元素

6、$group

将集合中的文档分组,可用于统计结果,一般与管道表达式$sum等组合使用。

把数据根据age字段进行分组:

db.user.aggregate([$group:_id:"$age"])

db.user.aggregate([$group:_id:"$age",num:$sum:1])

7、$sort

将输入文档排序后输出,1为升序,-1为降序

8、$lookup

用于多表连接返回关联数据。执行左连接到一个集合(非分片集合),两个集合必须在同一数据库中。

​ $lookup语法


    $lookup:
        
            from:<collection to join>,
            localField:<field from the input documents>,
			foreignField:<field from the documents of the "from" collection>,
			as:<output array field>
        

示例:有product产品信息集合、order订单信息集合,order中的pid与product中的_id关联。

练习1:查询出订单中购买的产品价格大于90的订单信息?

练习2:查询出产品1的产品信息和对应的订单信息

9、$geoNear

用于输出接近某地理位置的有序文档,返回距离信息

表面类型:平面和球面

表面类型会影响数据的存储、建立的索引的类型及查询的语法的形式。

1)平面

按照正常坐标对的形式(数组或内嵌文档)存放位置数据,使用2d索引。解决短距离的距离搜索场景。

可用的坐标对书写方式:

loc:[60,30]
loc:x:90,y:32
loc:foo:70,y:80
loc:lng:40,739037,lat:73.992964

示例:

创建places集合,并存入坐标信息

db.places.save(
	[name:"肯德基",loc:lng:40.739037,lat:73.992964,category:"餐饮",
	name:"麦当劳",loc:lng:42.739037,lat:73.992964,category:"餐饮",
	name:"农行",loc:lng:41.739037,lat:73.992685,category:"银行",
	name:"地铁站",loc:lng:51.739037,lat:83.992685,category:"交通"])

需要给坐标对字段创建空间索引才可使用地理位置查询。

db.places.createIndex("loc":"2d")

用find 查询从近到远的点

db.places.find(loc:$near:lng:40.639037,lat:73.992964)

使用aggregate和$geoNear能指定范围。

示例:查询在坐标值相差2度(平面单位)以内的文档

db.places.aggregate([
	
		$geoNear:
			spherical:false,
			distanceMultiplier:1,
			near:lng:40.639037,lat:73.992964,
			distanceField:"dist.distance",
			maxDistance:2,
			query:category:"餐饮",
			includeLocs:"dist.location",
			num:1
		
	
])

db.places.aggregate([
	
		$geoNear:
			spherical:false,
			distanceMultiplier:1,
			near:lng:40.739037,lat:73.992964,
			distanceField:"dist.distance",
			maxDistance:2,
			query:category:"餐饮",
			includeLocs:"dist.location",
		
	,
	$limit:1
]).pretty()

2)球面

按照普通坐标对或GeoJSON对象存储数据,使用2dphere索引。解决远距离的距离搜索场景。

GeoJSON对象可以有单点、线段、多边形、多点、多线段、多个多边形、几何体集合,如:

单点:

type:"Point",coordinates:[40,5]

线段:

type:"LineString",coordinates:[[40,5],[41,6]]

多边形:


	type:"Polygon",
	coordinates:[[[0,0],[3,6],[6,1],[0,0]]]

type表示类型,coordinates表示几何点。注意几何点的顺序是Ing, lat。

以单点为示例:

db.places.save(
	[name:"肯德基",loc:type:"Point",coordinates:[40.739037,73.992964],category:"餐饮",
	name:"麦当劳",loc:type:"Point",coordinates:[42.739037,73.992964],category:"餐饮",
	name:"农行",loc:type:"Point",coordinates:[41.739037,73.992685],category:"银行",
	name:"地铁站",loc:type:"Point",coordinates:[51.739037,83.992685],category:"交通"])

创建places集合并存储坐标信息

创建2dphere索引:

db.places2.createIndex(loc:"2dsphere")

db.places2.aggregate([
	
		$geoNear:
			spherical:true,
			near:type:"Point",coordinates:[40.739037,73.992964],
			distanceField:"dist.distance",
			maxDistance:2000,
			query:category:"餐饮",
			includeLocs:"dist.location",
		
	,
	$limit:5
]).pretty()


管道表达式

  • 是管道操作器的值

  • 是一个文档结构,由字段名、字段值和一些表达式操作符组成

  • 跟find中使用的表达式类似

测试数据准备:

db.products.insert([
	"_id":1,"name":"产品1","price":99,type:"服装",
	"_id":2,"name":"产品2","price":88,type:"服装",
	"_id":3,"name":"产品3","price":29,type:"

以上是关于MongoDB——基本命令的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB按“数字”升序排列

哈希和升序索引之间的 Mongodb 性能差异(有啥理由不在无序字段中使用哈希?)

MongoDB升序/降序定位错误值

Mongodb学习笔记二(Mongodb基本命令)

Mongodb学习笔记二(Mongodb基本命令)

使用 mongodb 聚合管道按升序向集合中的所有记录添加日期