Document 数据查询
首先在mongoDB中插入数据
var persons = [{
name:"jim",age:25,
email:"75431457@qq.com",
c:89,m:96,e:87,country:"USA",
books:["JS","C++","EXTJS","MONGODB"]
},
{
name:"tom",age:25,
email:"214557457@qq.com",
c:75,m:66,e:97,country:"USA",
books:["PHP","JAVA","EXTJS","C++"]
},
{
name:"lili",age:26,
email:"344521457@qq.com",
c:75,m:63,e:97,country:"USA",
books:["JS","JAVA","C#","MONGODB"]
},
{
name:"zhangsan",age:27,
email:"2145567457@qq.com",
c:89,m:86,e:67,country:"China",
books:["JS","JAVA","EXTJS","MONGODB"]
},
{
name:"lisi",age:26,
email:"274521457@qq.com",
c:53,m:96,e:83,country:"China",
books:["JS","C#","PHP","MONGODB"]
},
{
name:"wangwu",age:27,
email:"65621457@qq.com",
c:45,m:65,e:99,country:"China",
books:["JS","JAVA","C++","MONGODB"]
},
{
name:"zhaoliu",age:27,
email:"214521457@qq.com",
c:99,m:96,e:97,country:"China",
books:["JS","JAVA","EXTJS","PHP"]
},
{
name:"piaoyingjun",age:26,
email:"piaoyingjun@uspcat.com",
c:39,m:54,e:53,country:"Korea",
books:["JS","C#","EXTJS","MONGODB"]
},
{
name:"lizhenxian",age:27,
email:"lizhenxian@uspcat.com",
c:35,m:56,e:47,country:"Korea",
books:["JS","JAVA","EXTJS","MONGODB"]
},
{
name:"lixiaoli",age:21,
email:"lixiaoli@uspcat.com",
c:36,m:86,e:32,country:"Korea",
books:["JS","JAVA","PHP","MONGODB"]
},
{
name:"zhangsuying",age:22,
email:"zhangsuying@uspcat.com",
c:45,m:63,e:77,country:"Korea",
books:["JS","JAVA","C#","MONGODB"]
}]
for(var i = 0;i<persons.length;i++){
db.persons.insert(persons[i])
}
var persons = db.persons.find({name:"jim"})
while(persons.hasNext()){
obj = persons.next();
print(obj.books.length)
}
1、查询所有数据指定的键
查询出指定的name、age、country字段,由于_id默认查询出来的,所以要添加一个_id:0。
db.persons.find({},{name:1,age:1,country:1,_id:0})
2、使用查询条件查询
查询出年龄在25到27岁之间的学生
db.persons.find({age:{$gte:25,$lte:27}},{_id:0,age:1})
查询出所有不是韩国籍的学生的数学成绩
db.persons.find({country:{$ne:"Korea"}},{_id:0,m:1})
3、查询包含和不包含
$in或$nin
查询国籍是中国或美国的学生信息
db.persons.find({country:{$in:["USA","China"]}},{_id:0,name:1,country:1})
查询国籍不是中国或美国的学生信息
db.persons.find({country:{$nin:["USA","China"]}},{_id:0,name:1,country:1})
4、OR查询和Null
查询语文成绩大于85或者英语大于90的学生信息
db.persons.find({$or:[{c:{$gte:85}},{e:{$gte:90}}]},{_id:0,c:1,e:1})
把中国国籍的学生上增加新的键sex
db.persons.update({country:"China"},{$set:{sex:"m"}},false,true)
查询出sex 为 null的学生
db.persons.find({sex:{$in:[null]}},{country:1})
5、正则查询和not的使用
$not可以用到任何地方进行取反操作, $not和$nin的区别是$not可以用在任何地方儿$nin是用到集合上的
查询出名字中存在”li”的学生的信息,查询出名字中不存在”li”的学生的信息
db.persons.find({name:/li/i},{_id:0,name:1})
db.persons.find({name:{$not:/li/i}},{_id:0,name:1})
6、数组查询$all和index应用
查询喜欢看MONGOD和JS的学生
db.persons.find({books:{$all:["MONGODB","JS"]}},{books:1,_id:0})
查询第二本书是JAVA的学习信息
db.persons.find({"books.1":"JAVA"})
7、查询指定长度数组$size它不能与比较查询符一起使用
查询出喜欢的书籍数量是4本的学生
db.persons.find({books:{$size:4}},{_id:0,books:1})
8、查询出喜欢的书籍数量大于3本的学生
//增加字段size
db.persons.update({},{$set:{size:4}},false, true)
//改变书籍的更新方式,每次增加书籍的时候size增加1/
db.persons.update({查询器},{$push:{books:“ORACLE"},$inc:{size:1}})
//利用$gt查询/
db.persons.find({size:{$gt:3}})
//利用shell查询出Jim喜欢看的书的数量/
var persons = db.persons.find({name:"jim"})
while(persons.hasNext()){
obj = persons.next();
print(obj.books.length)
}
小结:
1.mongodb 是NOSQL数据库但是他在文档查询上还是很强大的
2.查询符基本是用到花括号里面的更新符基本是在外面
3.shell是个彻彻底底的JS引擎,但是一些特殊的操作要靠他的
各个驱动包来完成(JAVA,NODE.JS)
9、$slice操作符返回文档中指定数组的内部值
//查询出Jim书架中第2~4本书
db.persons.find({name:"jim"},{books:{"$slice":[1,3]}})
//查询出最后一本书
db.persons.find({name:"jim"},{books:{"$slice":-1},_id:0,name:1})
10、文档查询
首先为jim添加简历文档
var jim = [{
school :"K",
score:"A"
},{
school :"L",
score:"B"
},{
school :"J",
score:"A+"
}]
db.persons.update({name:"jim"},{$set:{school:jim}})
查询出在K上过学的学生
//这个我们用绝对匹配可以完成,但是条件必须完全一样
db.persons.find({school:{school:"K",score:"A"}},{_id:0,school:1})
//这样查询可以不需要完全匹配,但是查询结果是两个条件的并集
db.persons.find({"school.score":"A","school.school":"K"},{_id:0,school:1})
//使用$elemMatch查询可以解决这个问题
db.persons.find({school:{$elemMatch:{school:"K",score:"A"}}})
11、$where查询
复杂的查询我们就可以用$where因为他是万能,但是我们要尽量避免少使用它因为他会有性能的代价
//查询年龄大于22岁,喜欢看C++书,在K学校上过学的学生信息
db.persons.find({"$where":function(){
//得到查询结果的每一条文档
var books = this.books;
//得到文档中的school对象
var school = this.school;
//如果年纪>=22
if(this.age > 22){
var php = null;
//遍历书籍
for ( var i = 0; i < books.length; i++) {
if(books[i] == "C++"){
php = books[i];
//如果学校是真
if(school){
for (var j = 0; j < school.length; j++) {
//判断是不是在K上学
if(school[j].school == "K"){
//返回是真
return true;
}
}
break;
}
}
}
}
}})
分页与排序
1、Limit返回指定的数据条数,Skip返回指定数据的跨度
//查询出persons文档中前5条数据
db.persons.find({},{_id:0,name:1}).limit(5)
//查询出persons文档中5~10条的数据
db.persons.find({},{_id:0,name:1}).limit(5).skip(5)
2、Sort返回按照年龄排序的数据[1,-1] (-1倒序)
db.persons.find({},{_id:0,name:1,age:1}).sort({age:-1})
3、.Limit和Skip完成分页
三条数据位一页进行分页
//第一页
db.persons.find({},{_id:0,name:1}).limit(3).skip(0)
//第二页
db.persons.find({},{_id:0,name:1}).limit(3).skip(3)
游标以及快照
1、游标
//利用游标遍历查询数据
var persons = db.persons.find();
while(persons.hasNext()){
obj = persons.next();
print(obj.name)
}
游标的销毁条件
1.客户端发来信息叫他销毁
2.游标迭代完毕
3.默认游标超过10分钟没用也会别清除
2、查询快照
如果数据量比较大的时候使用游标遍历集合,就可能由于重新分配存储空间,从而出现漏读或者重复数据的情况,使用快照可以避免这样的问题。使用快宅查询的时候需要用到高级查询。一般情况下不需要使用高级查询来查询数据。
db.persons.find({$query:{name:"jim"},$snapshot:true})
高级查询选项
$query
$orderby
$maxsan:integer 最多扫描的文档数
$min:doc 查询开始
$max:doc 查询结束
$hint:doc 使用哪个索引
$explain:boolean 统计
$snapshot:boolean 一致快照