MongoDB——基本命令

基本命令

一、数据库常用命令

1、查看命令提示


2、切换/创建数据库

image-20210325172158613

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

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

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

image-20210325172401828

3、查询所有数据库

image-20210325172518854

4、删除当前使用数据库

image-20210329192001913

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、查看当前使用的数据库

image-20210329200323079

8、显示当前 db 状态

image-20210329200505417

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

9、当前 db 版本

image-20210329200718499

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

image-20210329200843574

11、清除错误记录

image-20210329200958576

二、集合

1、创建一个集合

image-20210329201226876

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

image-20210329201635337

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

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

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

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

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

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

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

image-20210329201849024

3、使用集合

image-20210329201947642

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

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

image-20210329202158598

image-20210329202219022

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

image-20210329202438514

6、查看集合数据大小

image-20210329202526925

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

7、查看集合索引大小

image-20210329202653367

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

image-20210329203020593

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

image-20210329203101088

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

image-20210329203135668

11、显示当前集合的状态

image-20210329203421934

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

12、集合的分片版本信息

image-20210329203541410

13、集合重命名

image-20210329205317787

image-20210329204010365

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

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

db,printCollectionStats();

image-20210329205403667

15、删除当前集合

image-20210329205619559

三、文档

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

image-20210413160134394

(3)更新文档

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

image-20210413160501307

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

image-20210413160547620

参数说明:

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

image-20210413162624764

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

image-20210414223621863

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

image-20210414223912008

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

image-20210414224043496

(4)删除文档

image-20210414224250620

image-20210414225028351

findAndModify方法的语法如下:

image-20210414224830744

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

image-20210414225704393

(5)更新并返回文档:

​ findAndModify() 方法

image-20210414230423790

​ runCommand() 方法

image-20210414230807711

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

findAndModify方法、runCommand()方法

image-20210414231421770

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

image-20210414231920681

四、索引

(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}

image-20210416220126344

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

image-20210416220307693

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

{“myName”:“ab”,age:14}

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

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

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

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

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

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

image-20210416220536255

在后台创建索引的原因:

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

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

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

image-20210416220925419

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

image-20210416221110232

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

image-20210416221136948

(2) 查询集合所有索引

image-20210416221238599

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

image-20210416221330130

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

image-20210416221429379

(5)删除指定索引

image-20210416221626956

(6)删除集合所有索引

image-20210416221701187

五、基本查询

1、find简介

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

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

image-20210422194044403

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

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

image-20210422195244661


新方法:

image-20210422195406082

来源于网络

2、游标

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

image-20210422200010249

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

image-20210422200340013


六 、条件查询

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

1、与操作

image-20210422201141439

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

2、或操作 $or

image-20210422201513332

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

3、大于 $gt (greater than)

image-20210422201939801

  • 查询age大于20的文档。

4、小于 $lt (less than)

image-20210422202057297

  • 查询age小于20的文档。

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

image-20210422202807901

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

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

image-20210422203001873

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

7、类型查询 $type

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

image-20210422203222339

使用方式如下:

image-20210422203456581

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

8、是否存在 $exists

image-20210422205818958

  • 查询age字段存在的文档

9、取模 $mod

image-20210422210104006

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

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

image-20210422210242257

  • 查询age不等于20的数据

11、包含 $in

image-20210422210412686

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

12、不包含 $nin

image-20210422210643652

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

13、反匹配 $not:

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

image-20210422210757215

七、特定类型查询

1、null

注意null前后不加引号!!

image-20210425115528112

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

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

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

例子:

\S+

<a[^>]+>

^J

of despair$

^abc$

notice

,[a-zA-Z0-9]$

MongoDB中正则表达式的用法:

image-20210425155112517

3、嵌套文档
3.1 精准匹配查询

image-20210425161544101

3.2 点查询

image-20210425161640883

4、数组

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

image-20210425162214963

image-20210425162250744

4.1数组单元素查询

image-20210425162510900

4.2 $all 数组多元素查询

image-20210425162614965

4.3 $size 数组长度查询

image-20210425162659954

4.4 $slice返回数组子集

image-20210426162831326

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

image-20210426162959217

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

image-20210426163422991

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

image-20210426163540945

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

4.5 精确匹配查询

image-20210426164023877

4.6 点查询

image-20210426164739638

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

image-20210426164712900

4.7 索引查询*

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

image-20210426165102641

image-20210426165233759

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

4.8 元素查询 $elemMatch

方法1:

image-20210426170108366

方法2:

image-20210426170615370

八、高级查询$where

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

image-20210426171328816

JavaScript与$where结合使用

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

image-20210426171611960

image-20210426171718192

image-20210426171929834

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

image-20210426171959821

image-20210426172122610

九、查询辅助

1、条件限制limit

image-20210515170502280

2、起始位置skip

image-20210515170851716

3、排序sort

image-20210515171309017

十、修改器

1、$set

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

image-20210518114540910

image-20210518114844342

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

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

2、$unset

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

image-20210518115553734

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

3、$inc

$inc用于增加或减少数值

image-20210520115046466

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

4、$push

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

image-20210520142710251

5、$pushAll

image-20210520143600316

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

image-20210520144346272

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

image-20210522161131470

image-20210522161408577

image-20210522161933241

image-20210522162308590

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

image-20210522163049544

6、$pull

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

image-20210522163812384

7、$addToSet

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

image-20210522164103143

8、$pop

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

image-20210522164248428

9、$rename

修改字段名称

image-20210522164421488

10、$bit

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

常用场景:

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

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

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

image-20210522164808806

十一、原生聚合运算

1、数量查询count
  • 统计满足条件的文档数量

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

image-20210523124731814

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

  • 需要指定集合、字段

image-20210523125144476

3、分组group

image-20210523125913305

PuTTy: Option > encoding > UTF-8

image-20210523130119422

Group方法已弃用

image-20210523130148733

4、灵活统计MapReduce

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

image-20210523130226762

MapReduce语法

image-20210523130453035

image-20210523130507574

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

  • 第一步:插入文档

image-20210523130621200

image-20210523130718624

一般写法

image-20210523132626069

源码:

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

简单写法

image-20210523133122830

源码

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

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

image-20210523133423700

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

image-20210523133541754

十二、聚合管道

管道操作器

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

1、$project

修改输入文档的结构

image-20210604150103756

image-20210604150149321

image-20210604150420044

image-20210604150812761

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

image-20210604151224334

image-20210604151327464

2、$match

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

image-20210604151831764

image-20210604151849850

3、$limit

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

image-20210604152233659

4、$skip

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

image-20210604152457070

5、$unwind

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

image-20210605090737888

6、$group

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

image-20210605091422068

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

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

image-20210605091848616

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

image-20210605091827024

7、$sort

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

image-20210605092519255

8、$lookup

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

image-20210605093453545

​ $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>
        }
}

image-20210605094513743

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

image-20210605095740451

image-20210605100045727

image-20210605101341876

image-20210605101529166

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

image-20210605101804182

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

image-20210608111749087

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:"交通"}])

image-20210609111050103

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

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

image-20210609111118444

用find 查询从近到远的点

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

image-20210609111230638

使用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
		}
	}
])

image-20210609111823181

image-20210609112037010

image-20210609112056273

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

image-20210609114637430

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:"交通"}])

image-20210609113557392

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

image-20210609113747906

创建2dphere索引:

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

image-20210609113905402

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

image-20210609114408946


管道表达式

  • 是管道操作器的值

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

  • 跟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:"饰品"},
	{"_id":4,"name":"产品4","price":78,type:"服装"},
	{"_id":5,"name":"产品5","price":9,type:"饰品"},
	{"_id":6,"name":"产品6","price":18,type:"饰品"},
])

image-20210609115257070

求和 s u m , 平 均 值 sum,平均值 sumavg,最小值 m i n , 最 大 值 min,最大值 minmax

db.products.aggregate([{$group:{_id:"$type",price:{$sum:"$price"}}}]);
db.products.aggregate([{$group:{_id:"$type",price:{$avg:"$price"}}}]);
db.products.aggregate([{$group:{_id:"$type",price:{$min:"$price"}}}]);
db.products.aggregate([{$group:{_id:"$type",price:{$max:"$price"}}}]);

image-20210609115749247

数组添加$push, $addToSet

db.products.aggregate([{$group:{_id:"$type",tags:{$push:"$name"}}}]);
db.products.aggregate([{$group:{_id:"$type",tags:{$addToSet:"$name"}}}]);

image-20210609120115105
$addToSet与 ​$push的区别在于重复的值不会进入数组。

首元素$first,尾元素$last

db.products.aggregate([{$group:{_id:"$type",products:{$first:"$name"}}}]);
db.products.aggregate([{$group:{_id:"$type",products:{$last:"$name"}}}]);

image-20210609120355510

复合使用示例

数据如下,用aggregate统计age大于13的文档按age分组后每组的数量。

db.user.aggregate([
	{$match:{age:{"$gt":13}}},
	{$group:{_id:"$age","人数":{$sum:1}}}
])

image-20210609120731967

练习:说明以下两个aggregate统计代码,并说明区别

db.user.aggregate([
	{$match:{age:{"$gt":13}}},
	{$sort:{age:1}},
	{$limit:2},
	{$group:{_id:"$age","人数":{$sum:1}}}
])
db.user.aggregate([
	{$match:{age:{"$gt":13}}},
	{$group:{_id:"$age","人数":{$sum:1}}},
	{$sort:{_id:1}},
	{$limit:2},
])

image-20210609121313624

区别:

- 前者是先根据年龄排序,取前2位,最后根据年龄分组;
- 后者是先根据年龄分组,在根据_id排序,取前2组。
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值