MongoDB常用Shell命令
MongoDB Shell 命令1、数据库命令# 显示所有数据库show dbs# 显示当前使用的数据库db# 切换到local数据库,如果不存在local数据库,则创建use local# 删除当前数据库db.dropDatabase2、对数据库集合的操作# 显示当前数据库的所有集合show collections# 在当前数据库中创建一个集合workerdb.createCollection(
·
MongoDB Shell 命令
1、数据库命令
# 显示所有数据库
show dbs
# 显示当前使用的数据库
db
# 切换到local数据库,如果不存在local数据库,则创建
use local
# 删除当前数据库
db.dropDatabase
2、对数据库集合的操作
# 显示当前数据库的所有集合
show collections
# 在当前数据库中创建一个集合worker
db.createCollection("worker")
# 删除当前数据库中的worker集合
db.worker.drop()
3、编辑集合的数据
# 往当前数据库的worker集合中插入一条数据,如果不存在worker集合,则创建
db.worker.insert(
{
"name": "fanyangyang",
"age": 24
}
)
# 往当前数据库的worker集合中插入两条数据,如果不存在worker集合,则创建
db.worker.insert(
[
{
"name": "chengya",
"age": 25
},
{
"name": "quanzhisheng",
"hobby": [
"first",
"second"
]
}
]
)
# 查找worker集合中name为chengya的文档,并用{"name":"chengya","score":54}作为新文档,替换旧文档
# 没有匹配到则不更新也不新增
db.worker.replaceOne(
{"name": "chengya"},
{"name": "chengya", "score": 54}
)
# 查找worker集合中name为wangfang的文档,并用{"name":"wangfang","score":54}作为新文档,替换旧文档,没有匹配到则新增
# upsert参数设置为true时,如果没有匹配到符合条件的文档,则新增
# 在更新数据库之后,生成了一个对象wangfang,这个对象的内容即为此次更新数据库的结果,
# 例如匹配数据条数,修改数据条数,插入数据的id等
var wangfang = db.worker.replaceOne({"name":"wangfang"},{"name":"wangfang","score":54},{"upsert":true})
# 更新worker集合的数据,
# upsert 设置为true,表示未匹配到符合条件的数据,则新增
# multi 设置为true,表示匹配到多个符合条件的数据时,更新所有数据;默认false,即只更新符合要求的第一条数据
# key-value,key可以省略引号,value的引号不可以省略。
# update与replaceOne不同,update可以只修改指定的字段,未指定的字段不做任何处理;replaceOne将匹配到的数据完全替换。
db.worker.update({name:"zhangjian"},{$set:{name:"lihui",age:28}},{upsert:true,multi:true})
# 将clearTime设置为当前时间
# 注意:如果 $set 没有写,那么update函数的作用就和replaceOne函数一样了,将会把原数据整条替换,而不是只对指定字段进行更新。
db.worker.update({name:"majinqiao"},{$set:{clearTime:new Date()}})
# 删除集合中的文档
db.worker.deleteOne({name:"lihui"})
db.worker.deleteMany({name:"lihui"})
db.worker.deleteMany({})
4、查询
# 查询worker集合中name属性是"majinqiao"的数据
# pretty函数 ,以格式化的方式显示查询结果
db.worker.find({name:"majinqiao"}).pretty()
# or查询 name = "majinqiao" or score = 54
db.worker.find({$or:[{name:"majinqiao"},{score:54}]}).pretty()
# or查询 age < 30 or age > 50
db.worker.find({$or:[{age:{$lt:30}},{age:{$gt:50}}]})
# or查询 age <= 30 or age => 50
db.worker.find({$or:[{age:{$lte:30}},{age:{$gte:50}}]})
# and查询 age != 30 and name != 'chengya'
db.worker.find({age:{$ne:30},age:{$ne:50}})
# and查询,name = "majinqiao" and age = 36
db.worker.find({name:"majinqiao",age:36}).pretty()
# 查找name字段为字符串的数据
db.worker.find({name:{$type:"string"}})
# 限制查询结果条数为2条
db.worker.find({name:"zhangjian"}).limit(2)
# province字段正序排列,city_age字段倒序排列
db.city.find().sort({province:1,city_age:-1})
# 当limit,skip,sort同时出现时,逻辑顺序为sort,skip,limit
db.worker.find({name:"zhangjian"}).limit(2).skip(1).sort({score:1})
# 查询city集合中存在history字段,且history的值是null的数据
db.city.find({history:{$in:[null],$exists:true}})
# select _id,city_name as cityName from city where city_name = 'jingzhou' and city_age >= 10
# _id 是默认查询的,如果想不返回这个字段, _id:0 即可
db.city.find({city_name:"jingzhou",city_age:{$gte:10}},{cityName:"$city_name"})
5、索引
# 为集合worker创建一个联合索引,name升序,age降序,设置索引名字为worker_index
db.worker.createIndex({name:1,age:-1},{name:"worker_index"})
# 查看集合的索引
db.worker.getIndexes()
# 查看集合索引的大小
db.worker.totalIndexSize()
# 删除集合的索引,索引名为name_1_age_-1
db.worker.dropIndex("name_1_age_-1")
6、查询覆盖索引
mongoDB查询分析较常使用的函数是 .explain("executionStats") ,例如
db.city.find({city_age:{$gt:100}}).explain("executionStats")
此函数的输出结果中:
queryPlanner.winningPlan.inputStage.stage 显示为 IXSCAN,表示使用了索引扫描;若显示为COLLSCAN,则表示使用了集合扫描
executionStats.nReturned 显示为 3,表示匹配查询并返回的文档数目为 3
executionStats.totalKeysExamined 显示为 3,表示 MongoDB 扫描了 3 个索引条目
executionStats.totalDocsExamined 显示为 3,表示 MongoDB 扫描了 3 个文档
如何才能是查询覆盖索引:
1、遵循最左匹配原则
首先建立一个索引
db.city.createIndex({city_name:1,city_age:1},{name:"city_name_age_index"})
然后分别做以下查询:
db.city.find({city_name:"wuhan",city_age:{$gt:300,$lt:400}}).explain("executionStats")
查询使用了索引。
然后把查询条件的顺序调换一下
db.city.find({city_age:{$gt:300,$lt:400}},city_name:"wuhan").explain("executionStats")
查询使用了索引。
db.city.find({city_name:"wuhan"}).explain("executionStats")
查询使用了索引
db.city.find({city_age:{$gt:300,$lt:400}}).explain("executionStats")
查询没有走索引,而是进行了集合扫描。
那么,当查询条件的部分字段不是索引中的字段时,又会怎样呢?
首先,做如下查询,这里查询条件中的province就是不存在于索引中的
db.city.find({city_name:"wuhan",province:"hubei"}).explain("executionStats")
结果发现居然使用了索引。
接下来,再尝试这个查询
db.city.find({city_age:{$gt:300,$lt:400},province:"hubei"}).explain("executionStats")
发现这个查询是没有使用索引的,而是采用了集合扫描的方式。
这是因为city_age是我们索引中的第二个字段,而索引中的第一个字段city_name并没有出现在查询条件中,所以查询没有覆盖索引。
因此,我们可以得出一个结论,mongo的索引遵循最左匹配原则。
7、聚合
# select province,count(*) as cityNum from city group by province;
db.city.aggregate([{$group:{_id:"$province",cityNum:{$sum:1}}}])
# select province,sum(city_age) as cityAge from city group by province;
db.city.aggregate([{$group:{_id:"$province",cityAge:{$sum:"$city_age"}}}])
# 按照province分组,求city_age的平均值
db.city.aggregate({$group:{_id:"$province",avgAge:{$avg:"$city_age"}}})
# 按照province分组,求city_age的最小值
db.city.aggregate({$group:{_id:"$province",minAge:{$min:"$city_age"}}})
# select province,sum(city_age) from city group by province where province = 'hubei' ;
# 此处$match 相当于sql中的where关键字,注意分组后province的别名是 _id
# 因此,此处如果写成 {$match:{province:"hubei"}} 是查询不到结果的
db.city.aggregate([{$group:{_id:"$province",sumAge:{$sum:"$city_age"}}},{$match:{_id:"hubei"}}])
# db.city.aggregate([{$match:{province:"hubei"}},{$group:{_id:"$province",sumAge:{$sum:"$city_age"}}}])
# 这又是可以的,这种方式是先按条件筛选,然后再聚合的
# 计算city集合中所有数据的city_age的总和
db.city.aggregate([{$group:{_id:null,sumAge:{$sum:"$city_age"}}}])
# $project只输出指定的字段,_id是默认会输出的,_id:0 表示不输出 _id
db.city.aggregate([{$match:{history:{$in:[null],$exists:true}}},{$project:{_id:0,city_name:1,province:1}}])
# worker集合的address字段是数组类型, $unwind将address数组拆分为元素,然后将这些元素与其他字段一起逐条输出
db.worker.aggregate([{$unwind:"$address"}])
# select count(*) as city_count from city where province in ('hubei','hunan');
db.city.aggregate([{$match:{province:{$in:["hubei","hunan"]}}},{$count:"city_count"}])
# 我的集合文档是
# { "_id" : ObjectId("60c48afadb603930d40f2492"), "city_name" : "changsha", "city_age" : 106, "province" : "hunan", "create_time" : ISODate("2021-06-14T11:40:00Z"), "history" : null }
db.city.aggregate([{$match:{city_name:"changsha"}},{$project:{city_name:1,"create_year":{$year:"$create_time"},"create_month":{$month:"$create_time"},"create_day":{$dayOfMonth:"$create_time"}}}])
# 查询结果是
# { "_id" : ObjectId("60c48afadb603930d40f2492"), "city_name" : "changsha", "create_year" : 2021, "create_month" : 6, "create_day" : 14 }
# 只取特定的几个字段,并使用别名返回
db.city.aggregate([{$project:{_id:0,cityName:"$city_name",createTime:"$create_time"}}])
# 查询 2021-06-01 <= create_time <= 2021-08-31
db.city.find({create_time:{$gte:new Date(2021,5,1)},create_time:{$lt:new Date(2021,8,1)}})
# new Date(2021,6,6) 实际是 2021-07-06 00:00:00
8、引用
# 首先,插入数据
# 还有一个 $db可选参数,指定数据库名称,如果不设置,默认当前库
db.worker.insert({worker_name:"xumingkai",address:{$ref:"city",$id:ObjectId("60c48e76db603930d40f249f")}})
# 然后,关联查询
var worker = db.worker.findOne({worker_name:"xumingkai"})
var address = worker.address
db[address.$ref].findOne({_id:(address.$id)})
更多推荐
已为社区贡献3条内容
所有评论(0)