怎么在MongoDB中使用Shell 命令

62次阅读
没有评论

共计 8593 个字符,预计需要花费 22 分钟才能阅读完成。

自动写代码机器人,免费开通

怎么在 MongoDB 中使用 Shell 命令?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

——————– 数据库内容 ——————

查看所有数据库

show dbs

删除数据库

db.dropDatebase()

——————– 集合内容 ——————–

创建集合

db.createCollection()

查看所有集合 \ 表

show collections
show tables

选定某一集合

use db_name

查看集合的信息

db.stats()

删除一个集合,但是需要先指定一个数据库,即先执行 use db_name

db.dropDatabase()

修改集合的名称

db.collection_name.renameCollection(new_name)

———————- 文档内容 ———————

插入数据

db.collection_name.insert(document)
db.collection_name.save(document)

查询数据多条数据

db.collection_name.find()

1、可以指定返回的内容

参数解释

db.collection_name.find({query_term:value},
return_key_name:1}
)

a find()函数的第一个参数是查询条件,即匹配该内容的文档都会被筛选出来,如果没有查询条件,则输入 {},不可以为空
b find() 函数的第二个参数是指定返回的内容,例如一个 student 的集合中的一个 xiaoming 文档中包含多条内容,姓名、学生号、家庭住址等,现在我只想看姓名,不想查询的时候返回 xiaoming 文档的全部内容,就可以使用这种 键名:1 的形式,后面的 1 表示筛选出该内容并正序输出,0 表示筛选出除了该内容的其余部分,- 1 表示逆序跟 1 一样的结果
c 可以返回多条记录,这里只是举个例子,还是拿 ixaoming 的例子

{
 name :1,
 student_id :1
}

这样就返回了两个信息,一个 name,一个 student_id

2、查询嵌套信息

结合二维数组理解下面的这个信息

{
 name : yang ,
 sex : man ,
 skill :[{ php :1},
{mongodb :4},
{redis :5}
 favorite_food : meat 
}

其中如果使用 skill 来作为 find()的查询条件的话,千万别写成这样

— 错误例子 —

db.self.find({skill :[{ php :1}]})

这样是查不到的,因为这样 mongodb 会将 {skill :[{ php :1}]} 解析成 skill 数组下只包含 php :1 这一条记录的内容,上面的例子明显不符合这一要求,所以查询不到

— 正确的例子 —

db.self.find({skill.php :1})

这里使用了 . 告诉 mongodb 数据库去匹配 skill 数组下 php 为 1 的内容,重点在于 skill 下是否有 php :1 这一条记录

— 正确例子 2 —

如果一定要使用上面的错误例子的方式查询数据,可以使用 $elemMatch 参数,注意该参数使用的位置

db.self.find({
 skill :{$elemMatch:
{php :1}
})

这里的 $elemMatch 是作为条件操作符来使用的

查询单条数据

db.collection_name.findOne()

skip 跳过查询的最开始的数量,limit,限制返回数量,sort,当 x:1 表示正序,x:-1 表示逆序

db.collection_name.find().skip(Number).limit(Number).sort({x:1})

计算符合查询条件的文档的数量

db.collection_name.find().count()

count()函数默认情况下会忽略 skip()或 limit()函数,例如假设 student 集合中有 4 个文档,下面的三条语句将显示不同的结果

db.student.find().limit(1).count() 结果为 4,count 忽略了 limit(1)的条件

db.student.find().limit(1).count(true) 结果为 1,为 count()传入参数 true

获取结果的唯一值

db.collection_name.distinct(key_name)

也是查询的函数,只不过他比起 find()会将查询结果显示唯一值,而不是根据原有集合中,文档的数量来显示结果,结合关系型数据库中的 distinct 来理解,举个例子,有一个图书集合 –books,该集合下有书名,作者,出版日期等信息,注意,一个作者可能写了很多本书,现在我想查看在该集合中有多少作者,如果我直接使用上面的 find()函数来搜索的话

db.books.find({ writer :1}
)

这样会将全部的作者列出来,但是很多都是重复的,因为 find()是根据文档数量来返回结果的,而 distinct()会将结果筛选,
其中重复的部分

db.books.distinct(writer)

将查询结果分组

db.collection_name.group()

参数 1 key 按照此 key 进行分组

参数 2 initial 设置变量,该变量会在最终输出,注意,这个变量是对每个分组都会定义一个的,一个新的分组开始就重新创建

参数 3 reduce 一个函数,在文档分组期间执行,即对一个文档进行一次分组就会执行一次,传入两个参数,一个是代表 initial 的参数,一个是目前进行分组的文档,为了便于理解,分别取名叫 out 和 doc

参数 4 keyf,可选,作用跟 key 一样,但是可以指定一个函数创建一个原本不存在于文档中的字段作为分组的依据,需要传入一个当前文档的参数

参数 5 cond 过滤条件,只有满足该条件的文档才能参与分组

参数 6 finalize 在分组完成后执行的函数,传入代表 initial 的参数
  下面来看一个例子就能大致上了解了,先传入几个文档到 orders 集合中

data1={ 
  _id  : ObjectId(552a330e05c27486b9b9b650), 
  _class  :  com.mongo.model.Orders , 
  onumber  :  002 , 
  date  : ISODate(2014-01-03T16:03:00Z), 
  cname  :  zcy , 
  item  : { 
  quantity  : 1, 
  price  : 4.0, 
  pnumber  :  p002  
 } 
data2={ 
  _id  : ObjectId(552a331d05c275d8590a550d), 
  _class  :  com.mongo.model.Orders , 
  onumber  :  003 , 
  date  : ISODate(2014-01-04T16:03:00Z), 
  cname  :  zcy , 
  item  : { 
  quantity  : 10, 
  price  : 2.0, 
  pnumber  :  p001  
 } 
} 
data3={ 
  _id  : ObjectId(552a333105c2f28194045a72), 
  _class  :  com.mongo.model.Orders , 
  onumber  :  003 , 
  date  : ISODate(2014-01-04T16:03:00Z), 
  cname  :  zcy , 
  item  : { 
  quantity  : 30, 
  price  : 4.0, 
  pnumber  :  p002  
 } 
} 
data4={ 
  _id  : ObjectId(552a333f05c2b62c01cff50e), 
  _class  :  com.mongo.model.Orders , 
  onumber  :  004 , 
  date  : ISODate(2014-01-05T16:03:00Z), 
  cname  :  zcy , 
  item  : { 
  quantity  : 5, 
  price  : 4.0, 
  pnumber  :  p002  
 } 
} 
db.orders.insert(data1)
db.orders.insert(data2)
db.orders.insert(data3)
db.orders.insert(data4)

接下来展示 group()函数

例 1

db.orders.group({key:{data:1, item.pnumber :1},
initial:{total :0},
reduce:function (doc,out){out.total+=doc.item.quantity})

首先是按照 data 和 ietm 数组中的 pnumber 分组
接着定义了输出变量 total,记录每个产品的总数
接着是定义处理函数,也就是 reduce 中的函数,注意,传入参数的先后顺序,第一个参数表示当前进行分组的文档,第二个参数表示 initial,所以 doc 能直接调用 doc.item.quantity,即文档的内容,out 能调用 out.total,即 initial 的内容

例 2

db.orders.group({keyf:function(doc){return { month :doc.date.getMonth()+1};
initial:{total :0, money :0},
reduce:function (doc,out){
out.total+=doc.item.quantity*doc.item.price
finalize:function (out){
out.avg=out.money/out.total;
return out;
})

首先,这个例子展示了 keyf 的用法,他返回了一个新的字段 –month,接下来 mongodb 会按照 month 的计算结果分类
接着,就是在 keyf 以及 finalize 的函数中都有传入参数,其实这个参数跟 reduce 中的参数名字没有关系,这里写在一起主要是为了便于理解其含义
最后就是在 finalize 中临时创建了一个变量 avg,这个 avg 在最后也是会被输出的
最后一点,在函数中处理结果都是会被 return 的

—————- 使用条件操作符来筛选查询结果 ——————

一般情况下都使用在 find()的第一个参数内部,作为筛选条件使用

—$gt,$lt,$get,$lte,$ne—

db.collection_name.find(key_name:{$gt:value}
})

注意操作符的位置,看例子可以便于理解

db.student.find(height :{$gt:180}
})

表示筛选出学生集合中身高高于 180 的学生

可以同时使用两个操作符来指定范围

db.student.find({height :{$gt:180,$lt:220}
})

这两个的使用方法跟上面是一样的,但是需要单独拎出来讲,因为有点特殊

—$in,$nin—

db.student.find({height :{$in:[170,180,190,200]}
})

表示筛选出身高为 170,180,190,200 的学生,$nin 就是筛选除了 170,180,190,200 之外的学生

—$all—

上面的 $in 中的内容是‘或 的形式,只要你的身高是 170,或 180,或 190,或 200,那么你就符合筛选条件,而 $all 则是且的关系

db.student.find({height :{$all:[170,180,190,200]}
})

这句话的意思是你的身高既是 170,又是 180,又是 190,又是 200 才能满足条件

—$or—

db.student.find({
$or:[{ score :100},
{sex :man}
})

上面的例子中,score:100 与 sex:man 是‘或 的关系,结合下面的例子就可以看出 $or 的作用了

db.student.find({ score :100, sex : man}
)

其中的 score:100 与 sex:man 是且的关系

limit(x)函数加 skip(y)函数 =$slice:[y,x]

具体使用方法可以看下面这个例子

db.student.find({ height :{$slice:[10,5]}}
)

还是那句老话,注意 $slice 的位置,这句话表示筛选身高第 11 到 15 的人,第一个参数是 skip()的参数,第二个是 limit()

limit()函数是限制返回文档的数量的,$size 是筛选符合数量的数组的,看下面的例子就明白了

先在数据库中添加以下信息

message={
 cds :[{ first_song : hello},
{second_song : world},
{third_song : again}
db.songs.insert(message)

接着我们来查询一下上述结果

db.songs.find({ cds :{$size:2}}
)

无返回结果,因为 cds 数组里有 3 组数据

db.songs.find({ cds :{$size:3}}
)

返回全部结果,注意一点,这里是作为 find()函数的第一个参数传入的,所以是筛选条件

筛选含有特定字段的值

db.collection_name.find(key_name:{$exit:true}
})

返回存在该字段的文档,注意,这里是存在该字段,而没有指定该字段的具体内容

根据数据类型筛选返回结果

db.collection_name.find(key_name :{$type:x}
})

其中的 x 取值内容有很多,这里就不介绍了,因为太多了看一遍也没用

在筛选中使用正则表达式

db.collection_name.find(key_name :/ /})

在 /  / 中添加正则表达式的内容

更新数据

db.collection_name.update({original_key:original_value},{new_key:new_value})

1、只要原 collection 中包含 original_key:original_value 就会被选中成为操作对象

2、整个 collection 都会被更新成 new_key:new_value,而不单单就只是更新 original_key:original_value

相较于上面会更新整个集合,下面添加了 $set: 的形式来只进行部分字段的更新

db.collection_name.update({original_key:original_value},{$set:{new_key:new_value}})

上面使用 $set 更新了一条字段,可以使用 $unset 删除一条字段

db.collection_name.update{{$unset:{key:value}}
}

如果此更新数据不存在就创建这一条数据,加第三个参数为 true 就可以实现了

db.collection_name.update({original_key:original_value},{new_key:new_value},true)

或者下面的形式也可以

db.collection_name.update({original_key:original_value},{new_key:new_value},{upsert:true})

update 只会更新第一条满足条件的记录,但是想更新多条记录时,将第三个参数设置为 false,第四个参数设置为 true,而且还要设置 $set

db.collection_name.update({original_key:original_value},{$set{new_key:new_value}},false,true)

—————— 插入数据——数组部分 ——————–

插入数据

db.collection_name.update({original_key:value},
{$push:{new_key:new:value)

注意,如果 original_key 不存在,则会被创建,并且定义为数组的形式,new_key:value 则是第一个值
如果 original_key 存在,并且数数组,则插入 new_key:value,如果不是数组,则报错

一次性插入多个值,前面是使用 $push 一次插入一个值,如果想插入多个值的话,需要使用下面的内容

db.collection_name.update({original_key:value},
{$push:{
new_key:{
$each:[
 value1 ,
 value2 ,
 value3 
})

注意这里的 $push 是针对数组操作的,也就是 $each 后面的内容都将添加到 new_key 的数组中

与 $push 对应,$pop 删除数组中的数据

db.collection_name.update({original_key:value},
{$pop:{{original_key:1}
})

注意,这里的 1 表示删除的数量,可以是 2,3 等整数,表示从数组的后端开始删除,也可以是 - 1 等负数,表示从数组的前端开始删除

前面的 $pop 可以指定删除的数量,但是不能指定删除的条件,$pull 则可以

db.collection_name.update({original_key:value},
{$pull:
{key1:value1}
)

$pull 会删除掉 key1 中所有 value1 的数据,注意,是删除 key1 中的 value1 数据,不是删除 key1,所以只要 key1 数组中包含了 value1 就会被删除掉 value1

与 $pull 类似,$pullAll 可以删除掉多个数据

db.collection_name.update({original_key:value},
{$pullAll:{
key1:
 value1 ,
 value2 ,
 value3 
})

$addToSet 是一个非常实用的向数组添加数据的命令,如果该数据不存在则添加,存在就不会重复添加了

db.collection_name.update({original_key:value},
{$addToSet:{
new_key:{
$each:[
 value1 ,
 value2 ,
 value3 
})

设想一下,如果这里不添加 $each 的情况,如果不添加 $each, 则会变成往数组 new_key 中直接添加新的数组

[value1 , value2 , value3]

可以尝试一下,理解 $each 的功能,回到 $addToSet 上来,如果原数组中就存在 value1,value2,value3 则不会添加,如果不存在,则将没有的添加进去,有的也不会重复添加,彼此之间不是互相影响的。

原子操作

这里就不解释什么叫原子操作了,对于我们使用者来说只要知道怎么采用原子操作就可以了

db.collection_name.findAndModify(query:{key:value},
sort:{key2:1/-1},
update/remove:true,
new:true
)

query 指定查询的文档
sort   排序,1,- 1 的含义这里就不解释了,跟上面一样
update/remove 表示操作
new   表示返回最终的修改结果,可以不填

删除所有查找到的数据

db.coolection_name.remove({key:value})

删除一张表

db.collection_name.drop()

查看集合的索引

db.collection_name.getIndexes()

创建索引

db.collection_name.ensureIndex({key:value})

前面是根据 key:value 的形式创建索引的,接下来就为一集合的某一字段全部创建索引

db.collection_name.ensureIndex({key:1})

复合索引的创建就是在其中多添加几个内容

删除索引

db.collection_name.dropIndex({key:value})

删除所有索引

db.collection_name.dropIndexes()

前面我们操作的都是一个集合,接下来我们要学习简单的操作多个集合了,有两种方式,手动或者使用 DBRef
先创建两个集合

collection1={
 name : yang ,
 sex : man 
collection2={
 id :1,
 name : yang ,
 math :60,
 pe :30,
 chinese :60
db.student.save(collection2)
db.yang.save(collection)

接下来就是大致思路了

yang=db.yang.findOne()
db.student.find({ name :yang.name}
)

关于怎么在 MongoDB 中使用 Shell 命令问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注丸趣 TV 行业资讯频道了解更多相关知识。

向 AI 问一下细节

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-12-04发表,共计8593字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)