目录
6.8、db.createCollection(name,options)
6.10、db.collection.ensureIndex(keys, options)
6.11、db.collection.getIndexes()
6.12、db.collection.dropIndex(index)
1、查询
说明:db.getCollection(“'test'”)和db.test一样
1.1、全部查询
标准格式:find({}), find是关键词, ({})是固定格式
mongo是json文本存储的所以{}也必须是json格式的查询
db.getCollection('test').find({})
1.2、查询单个条件 需要有索引
不准确:没有索引也可以查询到,不过正常使用不可以这样,对mongo的性能消耗大,查询慢
db.getCollection('diskBaseInfo').find({"fid":"d000e1a1-763b-4e3c-ae71-464ad8c2f850"})
1.3、多个条件查询(and)
注意:find后面的第一个({}) 是条件无论多少个条件都在这个{}里面
db.getCollection('diskBaseInfo').find({"uid":"123456","name":"test-1"})
1.4、or查询(带符号操作)
or不属于简单查询,需要借助特殊字符来查询$or
格式:$or:[{ },{}], key:$sor,value:带[]的json
db.getCollection('diskBaseInfo').find({$or:[{"uid":"123456789"},{"uid":"123456"}]})
1.5、大于小于等情况查询(带符号操作)
条件操作符
$gt : >
$lt : <
$gte: >=
$lte: <=
$ne : !=、<>
$in : in
$nin: not in
$all: all
$not: 反匹配(1.3.3及以上版本)
注:每个人的记法不同,{“key”:””},如果没有操作服务就简单的“value“,有操作符的需要对操作符进行赋值,赋值就需要键值对{”key“:”value“},此时对应的操作符就成了key,只不过操作不不要带”“,它不属于字符串,是Mongo的系统操作字段。
db.collection.find({ "key" : { $gt: value } })
db.collection.find({ "key" : { $gt: value1 , $lt: value2 } })
nin
db.collection.find({ "key" : { $nin: [ 1, 2, 3 ] } })
db.collection.find({ "key" : { $in: [ 1, 2, 3 ] } })
1.6、左右模糊查询
注:查询fid中包含mongo的数据 %y% 注意不要带”” 特殊符:/value/
db.getCollection('test01').find({"age":"/22/"}) 错误
db.getCollection('test01').find({"age":/22/}) 正确
1.7、以某字开头
注:特殊符:/^/
db.getCollection('diskBaseInfo').find({fid:/^d/})
1.8、分页
注:分页是skip().limit()使用的是指针分页,和mysql的区别
Skip不是第几页,也是从什么位置开始,如果是第2页,skip就是20,limit=size
db.getCollection('diskBaseInfo').find().skip(4).limit(10)
1.9、查询单个列的列表
注:find({})的第一个素组是查询,第2个素组是字段显示
({},{})表示那些字段需要回显,类似select name,id
1或者true表示显示,0或者false表示隐藏,默认情况下_id都是显示的
db.getCollection('diskBaseInfo').find({},{name:1,fid:1})
db.getCollection('diskBaseInfo').find({},{name:1,fid:1,_id:0})
或者db.getCollection('diskBaseInfo').find({},{name:true,fid:true})
1.10、排序
注:Monodb的默认排序是自然排序,自然排序不是_id的排序,切记
说明影响自然顺序的情况:
如果文档被移动、删除,你可能得到不同的结果集。如果没有文档插入、更新、删除你会获得相同的结果。添加索引不会影响文档在磁盘上的位置。
最好加上排序
db.student.find().sort({"age":-1});
按照sort里面key的值排序,1为正序,-1为倒序
2、更新
2.1、update
标准:db.collection.update(criteria,objNew,upsert,multi)
参数说明:
criteria:查询条件
objNew:update对象和一些更新操作符
upsert:如果不存在update的记录,是否插入objNew这个新的文档,true为插入,默认为false,不插入。
multi:默认是false,只更新找到的第一条记录。如果为true,把按条件查询出来的记录全部更新
例如:
更新一条:db.getCollection('diskBaseInfo').update({name:'likui-test1'},{$set:{name:'likui-test122222'}})
更新多个:
db.getCollection('diskBaseInfo').update({name:'likui-test1'},{$set:{name:'likui-test122222'}},{multi:true})
注:
db.test01.update({"name":"23"},{"name":"213"})不带符号的更新页可以使用,会覆盖原数据,切记慎用!
看下效果:原数据结构:
执行:db.test01.update({"name":"22"},{"name":"213"})后
2.2、save
db.collection.save(obj)
obj代表需要更新的对象,如果集合内部已经存在一个和obj相同的"_id"的记录,Mongodb会把obj对象替换集合内已存在的记录,如果不存在,则会插入obj对象。
这条命令比较简单,示例就省略了。
2.3、一些简单的加减法(后面在更新)
$inc
用法:{$inc:{field:value}}
作用:对一个数字字段的某个field增加value
示例:将age为22的学生的index增加5
db.getCollection('test01').update({"age":"22"},{"$inc":{"index":1}})
原数据:
更新后:
3、插入
单个:db.student.insert({"name":"张三","age":"22","sex":"男","class":"计算机2班"})
多条:[{},{}]数组
db.student.insert([{"name":"王五","age":"22","sex":"男","class":"计算机2班"},{"name":"赵六","age":"22","sex":"女","phone":"18513081650","class":"计算机1班"}]);
4、删除
注:删除操作一定慎用,最好配合备用语句使用
db.getCollection('test01').remove()#删除所有数据
db.getCollection('test01').remove({"age":"22"})#按照条件删除,全部删除
db.getCollection('test01').remove({"age":"22"},1)#删除指定条数
5、数组更新
这里说一个数组的更新,平时常用的一种。
数据结构中:"parentfolders" : [ "0", "222" ],
单个:db.getCollection('diskBaseInfo').update({"fid":"85fd0a0e-150d-44b9-b255-2a076a325e8e"},{$set:{'parentfolders.1':"223"}})
更新第2个值为223
多个更新(和一般的多个更新一样):
db.getCollection('diskBaseInfo').update({"fid":"85fd0a0e-150d-44b9-b255-2a076a325e8e"},{$set:{'parentfolders.1':"223",'parentfolders.0':"1"}})
6、DDL操作
上面介绍的是DML语句现在来说说DDL操作,DDL一个使用情况不多,并且都是属于慎用语句所以方一起讲。
6.1、基本mongo库语句
对库的操作语句集合:
6.1、db
查询当前所在数据库
6.2、show dbs
查看当前数据库服务器上的数据库名字
6.3、use dbSchema
切换到名为 dbSchema 的数据库上下文
当名为 dbSchema 不存在时,创建该数据库,使用 use 创建的数据库如果没有保存数据的话,在 switch 到其他数据库时,该空的数据库将别删除。
6.4、db.dropDatabase()
删除当期所在的数据库
6.5、db.stats()
6.6、show collections
查看当前数据库内的集合
6.7、db.collection.stats()
查看集合的状态
6.8、db.createCollection(name,options)
创建集合:
db.createCollection(name, {capped: <Boolean>, autoIndexId: <Boolean>, size: <number>, max: <number>} )
> db.createCollection(
... "test",
... {
... capped: true,
... autoIndexId: true,
... size: 1024
... })
{ "ok" : 1 }
>
name: 集合的名字
capped: 是否启用集合限制,如果开启需要制定一个限制条件,默认为不启用,如果你要开启 size,max 的限制,需要开启 capped
size: 限制集合使用空间的大小,默认为没有限制
max: 集合中最大条数限制,默认为没有限制
autoIndexId: 是否使用_id作为索引,默认为使用(true或false)
size的优先级比max要高
6.9、db.yourColl.drop()
删除集合
db.test.drop()
6.10、db.collection.ensureIndex(keys, options)
创建索引(无特殊要求,一般使用默认就好)
db.ensureIndex(keys, {background: <Boolean>, unique: <Boolean>, name: <String>, dropDups: <Boolean>, sparse: <Boolean>, expireAfterSeconds: <Integer>, v: <Index version>} )
解析:
keys: 索引对{field:1},1表示升序,-1表示降序
background: 是否在后台创建索引, false 在创建索引时将会阻断其他操作,但效率更高
unique:是否唯一索引
name:索引名
dropDups:创建唯一索引,并删除重复值,散列索引中无效
sparse:是否使用 sparse 索引
expireAfterSeconds:TTL 索引的过期时间,过期后将自动删除。TTL 集合时是有限制的: (1)你不能创建 TTL 索引,如果要索引的字段已经在其他索引中使用。(2)索引不能包含多个字段。(3)索引的字段必须是一个日期的 bson 类型。
v: 索引版本号
6.11、db.collection.getIndexes()
查询索引
如果需要查询系统中全部的索引,可以使用db.system.indexes.find()函数
6.12、db.collection.dropIndex(index)
删除指定索引
index:可以是索引名,也可以是某一确定某一索引的文档,例如对于上文中的的索引可以同样可以通过 “username_1”,也可以通过“{username:1}”删除同一个索引。
注:删除全部索引db.yourColl.dropIndexes()
(索引还有一些复杂操作,有看到在更新)
db.collection.reIndex() 删除某集合上的所有索引然后重建
6.13、查询版本
db.version()
6.14、查询引擎
db.serverStatus()
6.15、mongo语句的执行计划
db.getCollection('diskBaseInfo').find({"uid":"123456"}).skip(2).limit(10).explain('executionStats')
关注: executionStats
"executionStages" : {
"stage" : "LIMIT",
"nReturned" : 10,
"executionTimeMillisEstimate" : 0,
"works" : 13,
"advanced" : 10,
"needTime" : 2,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"limitAmount" : 10,
"inputStage" : {
"stage" : "SKIP",
"nReturned" : 10,
"executionTimeMillisEstimate" : 0,
"works" : 12,
"advanced" : 10,
"needTime" : 2,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 0,
"invalidates" : 0,
"skipAmount" : 0,
"inputStage" : {
"stage" : "FETCH",
"nReturned" : 12,
"executionTimeMillisEstimate" : 0,
"works" : 12,
"advanced" : 12,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 0,
"invalidates" : 0,
"docsExamined" : 12,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 12,
"executionTimeMillisEstimate" : 0,
"works" : 12,
"advanced" : 12,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 0,
"invalidates" : 0,
"keyPattern" : {
"uid" : 1.0
},
"indexName" : "uid_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"uid" : [
"[\"123456\", \"123456\"]"
]
},
"keysExamined" : 12,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
}
}
},
Skip>limit> FETCH> IXSCAN
6.2、删除字段
$unset
用法:{$unset:{field:1}}
作用:删除某个字段field
示例: 将index的字段删除
原结构
db.test01.update({"name":"test01"},{$unset:{"index":1}})
更新后:
注:"index":1键值对后面的1没有什么意思,我传了““也可以
unset这个key.value可以是任意的.true.1或者其他都没关系.只要看到就会干掉它
6.3、字段添加
用法:{$push:{field:value}}
作用:把value追加到field里。注:field只能是数组类型,如果field不存在,会自动插入一个数组类型
可以再使用$set修改其value值
6.、字段重新命名
$rename
用法:{$rename:{old_field_name:new_field_name}}
作用:对字段进行重命名
注意到index字段是还是存在集合中的,因为我们是修改的指定对面的列表
加上{multi:true}即可。
6.5、备份还原
备份全部数据库
mkdir /bak
mongodump
备份指定数据库
mkidr /bak
mongodump -d admin
备份一个数据库中的某个集合
mkdir /bak
mongodump -d admin -c student
恢复全部数据库
mongorestore --drop # --drop是为了防止数据重复
恢复某个数据库
mongorestore -d dbname --drop
恢复某个数据库的某个集合
mongorestore -d dbname -c student --drop
异机数据恢复
mongorestore -h host -d dbname /path/sourcefile # 注意这里要使用dump出来的文件的源文件
部分数据备份:mongodb.back.ups=mongodump -u admin -p adminpwd --port 57017 --host 172.*.*.137 -d mydb -c myconllection --query {uid:{$in:['123456','0']}} -o d:\test
说明:
U:用户名
P:密码
Port:mongodb端口
Host:mongodb的host
D:备份的db
C:备份的集合
Query:查询条件
o:备份的磁盘位置
还原:
mongodb.back.recover=mongorestore -u admin -p adinmpwd --port 57017 --host 172.*.*.137 -d db -c mycollection d:\test\rc_disk\diskBaseInfo.bson
说明:使用mongorestore语句
磁盘位置只要导入指定的bson文件
7、总结:
7.1、修改器的总结
Update修改器相关的操作符
7.1.1、$inc:
可以对文档的某个值为数字型(只能为满足要求的数字)的键进行增减的操作。
7.1.2、$set
键值对存在的情况下,直接更新(一般的更新,变更value的属性值)
键值对不存在的情况下,添加 (新增字段)
可改变键值对的值的类型,int变string,变数组等(变更value的类型和属性值)
对于内嵌文档在使用$set更新时,使用"."连接的方式。
7.1.3、$unset
使用修改器$unset时,不论对目标键使用1、0、-1或者具体的字符串等都是可以删除该目标键。(这个上面已经介绍过了,不够其值影响)
7.1.4、$push
向文档的某个数组类型的键添加一个数组元素,不过滤重复的数据。添加时键存在,要求键值类型必须是数组;键不存在,则创建数组类型的键。
7.1.5、$ne/$addToSet
主要给数组类型键值添加一个元素时,避免在数组中产生重复数据,$ne在有些情况是不通行的。
> db.c.update({"title" : {$ne:"t2"}},{$push:{"title":"t2"}})
> db.c.find()
{ "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "size" : { "height" : 8,
"width" : 7, "length" : 15 }, "title" : [ "t1", "t2", "t2" ], "type" : "suv" }
> db.c.update({"name" : "toyota"},{$addToSet:{"title":"t2"}})
> db.c.find()
{ "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "size" : { "height" : 8,
"width" : 7, "length" : 15 }, "title" : [ "t1", "t2", "t2" ], "type" : "suv" }
7.1.6、$pop、$pull
$pop从数组的头或者尾删除数组中的元素,示例如下:
{ "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "size" : { "height" : 8,
"width" : 7, "length" : 15 }, "title" : [ "t1", "t2", "t3", "t4" ],"type" : "suv" }
--从数组的尾部删除 1
> db.c.update({"name" : "toyota"},{$pop:{"title":1}})
> db.c.find()
{ "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "size" : { "height" : 8,
"width" : 7, "length" : 15 }, "title" : [ "t1", "t2", "t3" ], "type" : "suv" }
--从数组的头部 -1
> db.c.update({"name" : "toyota"},{$pop:{"title":-1}})
> db.c.find()
{ "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "size" : { "height" : 8,
"width" : 7, "length" : 15 }, "title" : [ "t2", "t3" ], "type" : "suv" }
--从数组的尾部删除 0
> db.c.update({"name" : "toyota"},{$pop:{"title":0}})
> db.c.find()
{ "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "size" : { "height" : 8,
"width" : 7, "length" : 15 }, "title" : [ "t2" ], "type" : "suv" }
$pull从数组中删除满足条件的元素,示例如下:
{ "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "size" : { "height" : 8,
"width" : 7, "length" : 15 }, "title" : [ "t1", "t2", "t2", "t3" ],"type" : "suv" }
> db.c.update({"name" : "toyota"},{$pull:{"title":"t2"}})
> db.c.find()
{ "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "size" : { "height" : 8,
"width" : 7, "length" : 15 }, "title" : [ "t1", "t3" ], "type" : "suv"
7.1.7、数组的定位修改器$
在需要对数组中的值进行操作的时候,可通过位置或者定位操作符("$").数组是0开始的,可以直接将下标作为键来选择元素。
示例如下:
{"uid":"001",comments:[{"name":"t1","size":10},{"name":"t2","size":12}]}
> db.c.find({"uid":"001"})
{ "_id" : ObjectId("5003da405af21ff428dafbe8"), "uid" : "001", "comments" : [ {
"name" : "t1", "size" : 10 }, { "name" : "t2", "size" : 12 } ] }
> db.c.update({"uid":"001"},{$inc:{"comments.0.size":1}})
> db.c.find({"uid":"001"})
{ "_id" : ObjectId("5003da405af21ff428dafbe8"), "uid" : "001", "comments" : [ {
"name" : "t1", "size" : 11 }, { "name" : "t2", "size" : 12 } ] }
> db.c.update({"comments.name":"t1"},{$set:{"comments.$.size":1}})
> db.c.find({"uid":"001"})
{ "_id" : ObjectId("5003da405af21ff428dafbe8"), "uid" : "001", "comments" : [ {
"name" : "t1", "size" : 1 }, { "name" : "t2", "size" : 12 } ] }
注意和上面的数组修改的区别
看出区别了吗,上面那个是以数组索引位置更新
7.2、基本mongoDB库语句
MongoDB 语句 | 说明 |
db | db 查看当前所在的数据库(默认 test) |
show dbs | 查看当前数据库服务器上的数据库名字 |
use dbSchema | 切换到名为 dbSchema 的数据库上下文 |
db.dropDatabase | 删除当期所在的数据库 |
db.stats() | Db状态 |
show collections | 查看当前数据库内的集合 |
db.collection.stats() | 查看集合的状态 |
db.createCollection(name,options) | 创建集合 |
db.yourColl.drop | 删除集合 |
db.collection.ensureIndex(keys, options) | 创建索引(无特殊要求,一般使用默认就好 |
db.collection.getIndexes | 查询索引 |
db.collection.dropIndex | 删除指定索引 |
7.3、与mysql的对比操作
mongondb | mysql | 说明 |
db.users.find() | select * from users | |
db.users.find({"age" : 27}) | select * from users where age = 27 | |
db.users.find({"username" : "joe", "age" : 27}) | select * from users where "username" = "joe" and age = 27 | |
db.users.find({}, {"username" : 1, "email" : 1}) | select username, email from users | |
db.users.find({}, {"username" : 1, "_id" : 0}) | 即时加上了列筛选,_id也会返回;必须显式的阻止_id返回 | |
db.users.find({"age" : {"$gte" : 18, "$lte" : 30}}) | select * from users where age >=18 and age <= 30 | $lt(<) $lte(<=) $gt(>) $gte(>=) |
db.users.find({"username" : {"$ne" : "joe"}}) | select * from users where username <> "joe" |
|
db.users.find({"ticket_no" : {"$in" : [725, 542, 390]}}) | select * from users where ticket_no in (725, 542, 390) | |
db.users.find({"ticket_no" : {"$nin" : [725, 542, 390]}}) | select * from users where ticket_no not in (725, 542, 390) | |
db.users.find({"$or" : [{"ticket_no" : 725}, {"winner" : true}]}) | select * form users where ticket_no = 725 or winner = true | |
db.users.find({"id_num" : {"$mod" : [5, 1]}}) | select * from users where (id_num mod 5) = 1 | |
db.users.find({"$not": {"age" : 27}}) | select * from users where not (age = 27) | 这什么鬼 |
db.users.find({"username" : {"$in" : [null] | select * from users where username is null | 区别:find({"username" : null})进行查询,"没有username"的纪录一并筛选出来 |
db.food.find({fruit : {$all : ["apple", "banana"]}}) | 对数组的查询, 字段fruit中,既包含"apple",又包含"banana"的纪录 | |
b.food.find({"fruit.2" : "peach"}) | 对数组的查询, 字段fruit中,第3个(从0开始)元素是peach的纪录 | |
db.food.find({"fruit" : {"$size" : 3}}) | 对数组的查询, 查询数组元素个数是3的记录,$size前面无法和其他的操作符复合使 | |
db.people.find({"name.first" : "Joe", "name.last" : "Schmoe"}) | 嵌套查询 | |
db.blog.find({"comments" : {"$elemMatch" : {"author" : "joe", "score" : {"$gte" : 5}}}}) | 嵌套查询,仅当嵌套的元素是数组时使用, | |
db.foo.find({"$where" : "this.x + this.y == 10"}) | 复杂的查询,$where当然是非常方便的,但效率低下。对于复杂查询,考虑的顺序应当是 正则 -> MapReduce -> $where | |
db.foo.find({"$where" : "function() { return this.x + this.y == 10; }"}) | $where可以支持javascript函数作为查询条件 | |
db.foo.find().sort({"x" : 1}).limit(1).skip(10); | 回第(10, 11]条,按"x"进行排序; |
到此结束,有问题请及时告知下,以免误人子弟,谢谢!