MongoDB开发学习(2)--文档操作、查询和游标

来源:互联网 发布:虎扑推荐淘宝匡威店铺 编辑:程序博客网 时间:2024/06/02 05:30

一、文档基本操作
目录:
1、Document数据插入
2、Document数据删除
3、Document数据更新

1、Document数据插入
1.1插入文档(insert)
db.[documentName].insert({})
1.2批量插入文档
shell不支持批量插入,db.[documentName].insert([{},{},{}…])是错误的。
想完成批量插入文档可以使用mongo的应用驱动或是shell的for循环。只有插入多个文档到一个集合时可以使用,不支持批量插入一次性对多个文档执行批量插入操作。
1.3save操作
等同于insert()操作,区别在于:如果插入的集合的“_id”值,在集合中已经存在,用Insert执行插入操作回报异常,已经存在”_id”的键。用Save如果系统中没有相同的”_id”就执行插入操作,有的话就执行覆盖掉原来的值,相当于修改操作。
2、Document数据删除
2.1删除列表中所有数据
db.[documentName].remove()
集合的本身和索引不会被删除。
2.2根据条件删除
db.[documentName].remove({})
例如:删除persons集合中name键等于”zhangsan”的记录,db.persons.remove({name:”zhangsan”})
2.3小技巧
如果想删除一个数据量十分庞大的集合,可以直接删除该集合(db.drop_collection(“documentName”))并且重新建立索引的方法,效率要比remove效率高很多。
3、Document数据更新
3.1强硬的文档替换式更新操作
db.[documentName].update({查询器},{修改器})
此更新方法会用新的文档代替老的文档,但是主键冲突时会报错并停止更新操作。
3.2使用修改器完成局部更新操作
通常文档只有一部分需要更新,此时可以考虑使用更新修改器($)。更新修改器是种特殊的键,用来指定复杂的更新操作,如调整、增加或删除,还可以操作数组或者内嵌文档。
注意:使用修改器时,”_id”的值不能改变。
这里写图片描述
3.3insertOrupdate操作
db.[documentName].update({查询器},{修改器},true)
此方法的目的是查出来数据就执行更新操作,查不出来就执行替换操作
3.4批量更新操作
db.[documentName].update({查询器},{修改器},false,true)
默认情况下当查询出来多天数据的时候就默认修改第一条数据,但是执行此方法可以显现批量修改。
3.5addToSet each结合完成批量数组更新

db.persons.update({_id:1000},{$addToSet:{books:{$each:["JS","JAVA"]}}})

each addToSet操作。
3.6存在分配和查询效率
当document被创建时,DB为其分配了内存和预留内存,当修改操作不超过预留内存的时候查询效率非常快,当修改操作超过了预留内存时就要分配新的内存,此时就会比较耗费时间。
3.7runCommand函数和findAndModify函数
runCommand可以执行MongoDB中的特殊函数,findAndModify就是特殊函数之一,用于返回update或remove后的文档。举例略。

二、 Find查询
目录
1、Find详讲
2、分页和排序
3、游标和其他知识

1、Find详讲
db.[documentName].find({查询条件},{键指定})
查询所有数据的指定键(name,age,country): db.persons.find({},{name:1,age:1,country:1,_id}:0})
1.1查询条件
查询出年龄在25和27岁之间的学生

db.persons.find({age:{$gte:25,$lte:27}},{_id:0,age:1})

1.2包含和不包含
查询国籍是美国或中国的学生信息

db.persons.find({country:{$in:["China","USA"]}})

1.3or查询
查询英语成绩大于85或语文成绩大于90的学生信息

db.persons.find({$or:[{e:{$gte:85}},{c:{$gte:90}}]},{_id:0,c:1,e:1})

1.4null
把中国国籍的学生加上新的键”sex”

db.persons.update({country:"China"},{$set:{sex:"M"}},false,true)

查询出sex等于null的学生

db.persons.find({sex:{$in:[null]}},{_id:0,name:1,sex:1})

1.5正则查询
查询出名字中存在”li”的学生的信息

db.persons.find({name:/li/i},{_id:0,name:1})

1.6not的使用
与in不同处:not可以用到任何地方进行取反操作
查询出名字中不存在”li”的学生信息

db.persons.find({name:{$not:/li/i}},{name:1,_id:0})

1.7数组查询$all和index的查询
查询出喜欢看”MongoDB”和”JS”的学生的信息

db.persons.find({books:{$all:["MongoDB","JS"]}},{name:1,books:1,_id:0})

查询第二本书是”JS”的学生的信息

db.persons.find({"books.1":"JS"},{_id:0,name:1})

1.8查询指定长度数组$size,但它不能与比较查询运算符一起使用,这是弊端
查询出书籍数量大于4本的学生的信息

db.persons.find({books:{$size:4}},{_id:0,name:1})

1.9查询出喜欢的书籍数量大于3本的学生的信息
1)增加字段size

db.persons.update({},{$set:{size:4}},false,true)

2)改变书籍的更新方式,每次增加书籍的时候size增加1

db.persons.update({查询器},{$push:{books:"oracle"},$inc:{size:1}})

3)利用$gt查询

db.persons.find({size:{$gt:3}})

1.10利用shell查询出Jim喜欢看的书的数量

var Jim = db.persons.find({name:"Jim"})while(persons.hasNext()){obj = persons.next();print(obj.books.length);}

1.11$slice操作符返回文档中指定数组内部值
查询出Jim书架中第2-4本书

db.persons.find({name:"Jim"},{books:{$slice:[1,3]}})

查询出Jim书架中最后一本书

db.persons.find({name:"Jim"},{books:{$slice:-1}})

1.12文档查询
查询出在K学校上过学的学生
1)用绝对匹配可以完成,但是有问题(如顺序之类的)

db.persons.find({school:{school:"K",score:"A"}},{_id:0,name:1})

2)为了解决顺序问题我们可以使用”对象.”的方式定位

db.persons.find({"school.score":"A","school.school":"K"},{_id:0,name:1})

3)正确的解法:单条条件组查询$elemMatch

db.persons.find({school:{$elemMatch:{school:"K",score:"A"}}})

1.13where
当键/值对查询方式无法依然表达需求时,可是考虑使用”$where”万能字句,它可以执行任意JavaScript作为查询的一部分。该查询几乎能做任何事情。
举例略。

2、分页和排序
2.1 limit返回指定数据条数
查询出文档中前5条数据

db.persons.find({},{_id:0,name:1}).limit(5)

2.2skip返回指定数据的跨度
查询出文档中第5-10条数据

db.persons.find({},{_id:0,name:1}).limit(5).skip(5)

2.3sort返回按照年龄排序的数据[1,-1]

db.persons.find({},{_id:0,name:1,age:1}).sort({age:1})

注意:MongoDB中的key可以是不同类型的数据排序也就是优先级
排序顺序:最小值->null->数字(整数、长整型、双精度)->字符串->对象/文档->数组->二进制数据->对象ID->布尔型->日期型->时间戳->正则表达式->最大值
2.4limit和skip完成分页
三个数据为一页进行分页
第一页: db.persons.find({},{_id:0,name:1}).limit(3).skip(0)
第二页: db.persons.find({},{_id:0,name:1}).limit(3).skip(3)
但是使用skip进行分页时会有性能问题,当数据量非常大时,我们尝试使用date重构文档结构,即每次查询操作时,前台传值将上次最后一个文档的日期保存下来。
db.persons.find({date:{$gt:日期数值}}).limit(3)
个人建议:应该将软件的重点放在便捷和精确查询上而不是分页性能上,因为用户翻查最多不会2页。

3、游标和其他知识
3.1游标
利用游标遍历查询数据

var persons = db.persons.find();while(persons.hasNext()){    obj = persons.next();    print(obj.name);}

persons.hasNext()检查是否有后续结果存在,然后用persons.next()将其获得。
3.2游标的几个销毁条件
1)客户端发来消息将其销毁;
2)游标迭代完毕;
3)默认游标超过10分钟没有用则会自动清除。
3.3查询快照
快照后就会针对不变的集合进行游标运动。所有返回一组结果的查询实际上都进行了快照,不一致只在游标等待结果时集合内容被改变的情况下发生。

db.persons.find({$query:{name:"Jim"},$snapshot:true})

3.4高级查询选项

$query$orderby$maxscan:integer  //指定查询最多扫描的文档数量$min:document  //查询的开始条件$max:document  //查询的结束条件$hint:document  //指定服务器使用哪个索引进行查询$explain:boolean  //获取查询执行的细节(用到的索引、结果数量、耗时),而非真正执行查询$snapshot:boolean  //确保查询结果是在查询执行的那一刻的一致快照。

注意:
1、mongodb是Nosql数据库,它在文档查询上功能很强大;
2、查询符基本上放在花括号里面,更新符基本上放在花括号外面;
3、shell是个彻底的JS引擎,但是一些特殊的操作要靠它的各个驱动包来完成,如java,node.js

0 0
原创粉丝点击