Mongo Find详解(续)
9.特殊类型查询
9.1.null类型
Mongo里的null值和关系型数据库里的null值不同,它可以和自己比较也就是null=null返回真。
注意:null不能写出NULL
例如:
我先将某个员工的COMM列更新成null
> db.emp.update({"EMPNO" : 7369},{$set : {"COMM" : null}})
查询COMM列为空的数据
> db.emp.find({"COMM" : null},{"_id" : 0,"ENAME" : 1,"COMM" : 1}) { "ENAME" : "SMITH", "COMM" : null }
null不但能匹配空值还好匹配不存在的列,例如我查询一个不存在的列
> db.emp.find({"NOT_EXISTS" : null},{"_id" : 0,"EMPNO" : 1,"ENAME" :1})
{ "EMPNO" : 7369, "ENAME" : "SMITH" }
{ "EMPNO" : 7499, "ENAME" : "ALLEN" }
{ "EMPNO" : 7521, "ENAME" : "WARD" }
{ "EMPNO" : 7566, "ENAME" : "JONES" }
{ "EMPNO" : 7654, "ENAME" : "MARTIN" }
{ "EMPNO" : 7698, "ENAME" : "BLAKE" }
{ "EMPNO" : 7782, "ENAME" : "CLARK" }
{ "EMPNO" : 7788, "ENAME" : "SCOTT" }
{ "EMPNO" : 7839, "ENAME" : "KING" }
{ "EMPNO" : 7844, "ENAME" : "TURNER" }
{ "EMPNO" : 7876, "ENAME" : "ADAMS" }
{ "EMPNO" : 7900, "ENAME" : "JAMES" }
{ "EMPNO" : 7934, "ENAME" : "MILLER" }
如果只查询存在的列且列数据是null,需要使用$exists
db.emp.find({"NOT_EXISTS" : {$in : [null], $exists : true}},{"_id" : 0,"EMPNO" : 1,"ENAME" :1})
由于不存在NOT_EXISTS列,所以该查询无数据返回。
9.2正则表达式
正则表达式在匹配字符串时非常灵活。
例如查找员工姓名是以A开头的员工信息
> db.emp.find({"ENAME" : /^A/i},{"_id" : 0, "ENAME" : 1})
{ "ENAME" : "ALLEN" }
{ "ENAME" : "ADAMS" }
9.3查询数组
首先构造一个表:
> db.food.insert({"_id" : 1, "fruit" : ["apple", "banana", "peach"]})
WriteResult({ "nInserted" : 1 })
> db.food.insert({"_id" : 2, "fruit" : ["apple", "kumquat", "orange"]})
WriteResult({ "nInserted" : 1 })
> db.food.insert({"_id" : 3, "fruit" : ["cherry", "banana", "apple"]})
WriteResult({ "nInserted" : 1 })
查询包含某个元素的数组
> db.food.find({"fruit" : "banana"}) { "_id" : 1, "fruit" : [ "apple", "banana", "peach" ] }
{ "_id" : 3, "fruit" : [ "cherry", "banana", "apple" ] }
如有要查询多个元素需要使用$all,例如我查询数组包含"apple" 和"banana"元素的数组:
> db.food.find({"fruit" : {$all : ["apple", "banana"]}})
{ "_id" : 1, "fruit" : [ "apple", "banana", "peach" ] }
{ "_id" : 3, "fruit" : [ "cherry", "banana", "apple" ] }
注意:与元素的顺序无关
如果要查询某个数组的某个特定元素,可以是索引,数组的索引是从0开始的。例如查询三个元素是”peach”的数组
> db.food.find({"fruit.2" : "peach"})
{ "_id" : 1, "fruit" : [ "apple", "banana", "peach" ] }
使用$size可以查询含有特定元素数量的数组,例如查询数组中包含3个元素的数组:
> db.food.find({"fruit" : {"$size" : 3}})
{ "_id" : 1, "fruit" : [ "apple", "banana", "peach" ] }
{ "_id" : 2, "fruit" : [ "apple", "kumquat", "orange" ] }
{ "_id" : 3, "fruit" : [ "cherry", "banana", "apple" ] }
使用$slice可以返回数组的部分元素
例如我想返回数组的前两个元素:
> db.food.find({},{"fruit" : {'$slice' : 2}})
{ "_id" : 1, "fruit" : [ "apple", "banana" ] }
{ "_id" : 2, "fruit" : [ "apple", "kumquat" ] }
{ "_id" : 3, "fruit" : [ "cherry", "banana" ] }
如果参数是负表示从后向前截取,例如:
> db.food.find({},{"fruit" : {'$slice' : -2}})
{ "_id" : 1, "fruit" : [ "banana", "peach" ] }
{ "_id" : 2, "fruit" : [ "kumquat", "orange" ] }
{ "_id" : 3, "fruit" : [ "banana", "apple" ] }
10游标
数据库将find命令查询出来的结果集返回给游标,是用游标你可以控制结果的输出。
可以使用hasNext()和next()方法来循环游标,例如:
> var result = db.emp.find()
> while (result.hasNext()){
... obj = result.next();
... print(obj.SAL);
... }
800
1600
1250
2975
1250
2850
2450
4000
5000
1500
1100
950
1300
使用forEach循环游标:
> var result = db.emp.find()
> result.forEach(function(obj){print(obj.SAL)})
800
1600
1250
2975
1250
2850
2450
4000
5000
1500
1100
950
1300
10.1使用Limits, Skips, 和Sorts限制结果返回
limits:限制结果的返回条数
> db.emp.find({},{"_id" : 0,"EMPNO" : 1}).limit(2)
{ "EMPNO" : 7369 }
{ "EMPNO" : 7499 }
skips:跳过指定的返回条数
> db.emp.find({},{"_id" : 0,"EMPNO" : 1}).skip(2)
{ "EMPNO" : 7521 }
{ "EMPNO" : 7566 }
{ "EMPNO" : 7654 }
{ "EMPNO" : 7698 }
{ "EMPNO" : 7782 }
{ "EMPNO" : 7788 }
{ "EMPNO" : 7839 }
{ "EMPNO" : 7844 }
{ "EMPNO" : 7876 }
{ "EMPNO" : 7900 }
{ "EMPNO" : 7934 }
sorts:指定排序列
例如按工资正序排列:
> db.emp.find({},{"_id" : 0,"EMPNO" : 1,"SAL" : 1}).sort({"SAL" : 1})
{ "EMPNO" : 7369, "SAL" : 800 }
{ "EMPNO" : 7900, "SAL" : 950 }
{ "EMPNO" : 7876, "SAL" : 1100 }
{ "EMPNO" : 7521, "SAL" : 1250 }
{ "EMPNO" : 7654, "SAL" : 1250 }
{ "EMPNO" : 7934, "SAL" : 1300 }
{ "EMPNO" : 7844, "SAL" : 1500 }
{ "EMPNO" : 7499, "SAL" : 1600 }
{ "EMPNO" : 7782, "SAL" : 2450 }
{ "EMPNO" : 7698, "SAL" : 2850 }
{ "EMPNO" : 7566, "SAL" : 2975 }
{ "EMPNO" : 7788, "SAL" : 4000 }
{ "EMPNO" : 7839, "SAL" : 5000 }
limits,skip,sorts可以组合使用
例如要跳过前5行后,返回5行数据,输出结果按工资倒序排列:
> db.emp.find({},{"_id" : 0,"EMPNO" : 1,"SAL" : 1}).skip(5).limit(5).sort({"SAL" : -1})
{ "EMPNO" : 7499, "SAL" : 1600 }
{ "EMPNO" : 7844, "SAL" : 1500 }
{ "EMPNO" : 7934, "SAL" : 1300 }
{ "EMPNO" : 7521, "SAL" : 1250 }
{ "EMPNO" : 7654, "SAL" : 1250 }