日常开发中习惯了Oracle、mysql等关系型数据库之后,切换到基于分布式文件存储的数据库mongodb之后,最明显的感觉就是查询不是很得心应手,最根本的原因还是对mongodb的查询语法不熟悉,因此在这里记录一下mongodb的查询技巧。
查询格式
find(query, projection)
返回指定键
有时并不需要返回文档中的所有键值对.可以通过find或findOne的第二个参数来指定要返回的键.这样做能节省传输的数据量,又能节省客户端解码文档的时间和内存消耗。
db.users.findOne({“name”:”refactor”},{“age”:1,”sex”:1})
$lt,$lte,$gt,$gte
对应<,<=,>,>=,例如查询age >=18 <=30
db.users.find({“age”:{“$gte”:18,”$lte”:30}})
$ne
查出所有name不等refactor1的文档,注意 文档中不存在键name的文档也会被查出来。
db.users.find({"name":{"$ne":"refactor1"}})
$in,$nin,$or,$and,$not
"$in"的数组只有一个值和直接匹配这个值效果是一样的。
db.users.find({pageViews:{“$in”:[10000,20000]}})
使用"$nin"返回与数组中所有条件都不匹配的文档
"$in"能对单个键进行or查询.那么如果要对多个键进行条件组合呢?使用$or关键字,例子如下:
db.users.find( { "$or": [ {"pageViews":{"$in":[10000,20000]}}, {"url":"http://www.cnblogs.com/refactor"} ] } )
使用普通的and查询时,要尽量将最苛刻的条件放在前面。
- "$not"可以用在任何条件之上,取反。
null查询
- null可以匹配自身,而且可以匹配"不存在的"
- 如果需要查出为null,但是不查出不存在键的,使用$exist关键字
db.users.find({"pageViews":{"$in":[null],"$exists":true}})
正则表达式查询
正则表达式能够灵活有效的匹配字符串.同时也可以匹配自身。
- 忽略大小写
db.users.find({"name":/refact/i})
- MongoDB可以为前缀型正则表达式(如:/^refactor/)查询创建索引.所以这种类型的查询非常高效。
查询数组
- 数组很大多数情况下可以这样理解:每一个元素都是整个键的值。
- 如果需要多个元素来匹配数组,就要用"$all"。
db.users.find( { "emails": { "$all": [ "111222333@163.com", "111222333@126.com" ] } } )
- 要是只对一个元素的数组使用"$all"就和不用"$all"是一样的
- 若想查询数组指定位置的元素,需要使用key.index语法指定下标
db.users.find({"emails.1":"295240648@163.com"})
- 指定数组长度
db.users.find({"emails":{"$size":3}})
- 数组长度为区间范围内的数据呢,可惜的是
$size
并不能与其他查询子句组合(如:"$gt"),只能通过在文档中添加一个size
键的方式来实现 $slice
返回数组的子集合
limit,skip,sort
var cursor=db.refactor.find(),当调用find的时候,shell并不立即查询数据库,而是等待真正开始要求获得结果的时候才发送查询,这样执行之前可以给查询附加额外的选项。几乎所有游标对象的方法都返回游标本身,这样可以按照任意顺序组成方法链。
- limit限制数据条数
- skip跳过数据条数
- sort数据排序
- sort用一个对象作为参数:一组键值对,键对应文档的键名,值代表排序方向.排序方向可以是1(升序),-1(降序)。如果指定了多个键,则按照键的顺序逐个排序。
- 这三个方法可以组合使用来进行分页。如果略过过多的结果会导致性能问题,尽量避免。分页性能调优,可以研究一下