设为首页 加入收藏

TOP

mongo简介――查询(续)(二)
2014-11-24 01:03:21 来源: 作者: 【 】 浏览:18
Tags:mongo 简介 查询
log.find(tags:{$ne:['nosql','mongo']});//返回所有不包含nosql和mongo这两个标签的博文
$size---检查一个数组的尺寸,不利用索引,不能做范围查询,以后可能会增加这方面的支持
有时iteye会给用户快递一些奖品,iteye可能会把用户曾经填过的地址保存下来。可以这么保存
在USER集合里增加一个address属性,没有留过地址的可以没有。
一个用户不一定只有一个地址,这个address就可以创建为一个字符串数组。
比如要返回所有只留了一个地址的用户。
db.USER.find(address:{$size:1});
有些时候,如果ITEYE想要知道用户更详细的地址信息,就要用更复杂的文档保存地址。比如:
{
_ID:ObjectID(.........),
accountName:'runfriends',
address:[{category:'home',city:'北京',district:'东城',street:'.....'},
{category:'company',city:'北京',district:'海淀',street:'........'}]
}
如果要查出所有家在北京的用户,要怎么做呢?
可能会这样写:
db.USER.find({'address.category':'home','address.city':'北京'})。
但是这样是错的!这行命令的意义是查询出所有地址里面分类包含home,而且地址所在城市包含北京的用户。有些用户的公司地址在北京,而家庭地址不是,这些用户也会被匹配到。
那么接下来就用到了$elemMatch
它只在需要匹配子文档的多个属性时才会用到
db.USER.find(address:{$elemMatch:{category:'home',city:'北京'}});
$not---取反值,只有在没有指定相反操作时才需要用到它。因为绝大部分操作符都有对应的相反操作,所以应当尽量使用相反操作符,比如正则表达式匹配没有相反操作
假如有一天,ITEYE只允许用户名以字母开头了就可以把所有不以字母开头的用户查出来给他们发一封邮件,让他们改名。
db.USER.find(accountName:{$not:/^[a-zA-Z]/})
当然$not也接收单值,但是不建议使用
$exists----检查某个属性的存在性。
比如要把所有包含附件的博文查询出来。
db.blog.find({attachment:{$exists:true}});
没有附件的就是db.blog.find({attachment:{$exists:false}});
或才可以这样做:
db.log.find({attachment:null});//不存在
db.blog.find({attachment:{$ne:null}});//存在
前面介绍BSON的时候说过空值使用nil,但是这里却用了null,是因为nil是BSON的定义,这里是java script的语法
$mod-----求余数,不利用索引
假如说某天ITEYE心血来潮要给所有年龄能被4整队的用户快递一份奖品。
db.USER.find({age:{$mod:[4,0]}});//数组的第一个值是除数,第二个值是期望的余数
$type---以属性类型查询
虽然不建议在同一集合的不同文档相同属性名保存着不同类型的数据,但是有时由于程序bug或设计不严谨可能会出现这种情况。现在要把这种情况找出来,比如_ID属性有的是ObjectID类型,有的是整数。下面把所有_ID是字符串的文档找出来。
db.USER.find(_id:{$type:2})
db.USER.find(_id:{$not:{$type:7}});//把所有主键ObjectID类型的文档找出来
$or $and----逻辑运算
它们的意义就不多解释了。不过它们的用法非常有意思
比如找出所有月收入在20000以上或2000以下的用户
db.USER.find({$or:[{salary:{$gt:20000}},{salary:{$lt:2000}}]});
找出所有月收入在8000以上,20000以下的用户
db.USER.find({$and:[{salary:{$gte:8000}},{salary:{$lte:20000}}]});
查询嵌套文档和数组元素
前面的内容已经简单介绍一些嵌套文档和数组元素的查询。嵌套文档和数组的查询遵守相同的语法规则
1. 它们都采用点号分割嵌套文档的属性,如果是数组的索引就用从0开始的数字表示。
db.USER.find({'address.category':'home'});//这个是查出所有留了家庭地址的用户
如果想知道用户留下的第一个地址是不是家庭地址可以这么做:
db.USER.find({'address.0.category':'home'});
那么如果想只返回留了家庭地址的用户而又只返回家庭地址却不返回其它的地址该怎么做呢?
目前采用的数据模型恐怕做不到这一点,如果有这样的需求,恐怕只能为不同的地址定义不同的字段了。
当然如果代码规范规定第一个地址必须是家庭地址,那么可以这样做:
db.USER.find({'address.0.category':'home'},{'accountName':1,'address.0':1});
不过通常情况下,把第一个地址定义为默认地址更好一些。
$where-----接收一段java script代码作为查询条件,不利用索引
假如说要查询所有闰年出生的用户 www.2cto.com
db.USER.find({$where:'var year=birthday.getFullYear();return year%4==0 && year%100>0 || year%400==0';});
或:
db.USER.find($where:'function(){var year=this.birthday.getFullYear();return year%4==0 && year%100>0 || year%400==0'}');
好了,关于mongo的查询方式就这么多了。下一篇将要简单说下聚合。
mongo真是个神奇的数据库,它还能很方便的完成很多数据分析工作。很多使用mongo的公司也确实在用它做数据分析。
首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇mongodb释放内存 下一篇Redis学习手册(虚拟内存)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: