MongoDB - 查询文档

一、基本查询(find)

1、find、findOne

    db.test.find(); # 默认查询条件为{},查询全部test集合的文档,可以根据条件进行过滤

    db.test.findOne();  # 默认查询条件为{},查询满足条件的文档,返回第一条数据

 

2、指定字段查询

    按照条件查询返回文档,并且第二个对象参数指定需要返回的字段,默认会返回所有的字段(即字段值为1),不返回需要指定字段值为0 ,既节省了mongo查询时候的数据量和传输量,也让客户端反序列化的时间和内存消耗。

    1、_id默认会进行返回,除非特别指定为0,不进行返回。

    2、其他字段不进程任何指定,默认全部返回。有指定返回的情况下,没有指定则不返回;反之,有指定不返回的情况下,其他则全部返回

    db.test.find({}, {"name": 1,"_id":0});

 

二、条件查询

1、$lt、$lte、$gt、$gte(范围查找)

    使用对象进行查询的时候,就是等于(=)符合,则需要查询范围时候则使用上面的符号,意思一目了然。

    db.test.find({"_id":{"lte":5}});   # 查询主键id小于5的集合, 默认插入了10000条数据

2、$or、$in、$nin(后面一定是数组对象)

    1)、默认查询的对象条件就是and关联符,所以尽量将能过滤掉最多的条件放前面;

    db.user.find({"name":"kevin","age":NumberInt("5")});  # 查询名称为kevin并且(and)年龄为5的集合

    2)、$or操作则需要后面跟的对象是一个对象的各个条件是or操作,并在尽量使用第一个条件就能查询满足条件比较多的文档

   db.user.find({"$or":[{"_id":NumberInt("3")},{"name":"kevin5"}]});  # 主键为3或者名称为kevin5的文档

    3)、$in和$nin(not in操作),则比较好理解,直接是in(或者not in)一个集合

    db.user.find({"name":{"$in":["kevin7","kevin8","kevin10"]}}); # 名称在后面的数组中的集合

3、$not(取反操作,可对任何条件取反)

    db.user.find({"name":{"$not":{"$nin":["kevin7","kevin8","kevin10"]}}});  # 名称不在数组中,再取反,与上面结果应该一致

4、$mod(取模判断条件是否满足)

    db.user.find({"_id":{"$mod":[5000,2]}}); # 主键_id取模5000,余数为2的文档

5、$and、$nor(not or)、$or等,一个字段满足多个条件

    db.user.find({"$and":[{"_id":{"$lte":70}},{"_id":50]}}); # 同一个字段的值,同时满足多个条件

6、null、$exists

    mongo不像关系型数据库,可能会存在键的值为null或者其他文档存在某一个键,而其他文档不存在的情况。null会查询出所值为null和键不存在的文档,而$exist(boolean类型)则用于查询是否存在某个字段

    db.test.find({"department":null});                    #  查询部门为null及部门不存在的文档 

    db.test.find({"department":{"$exists":true}});  # 查询部门字段存在的值     null查询 = null + $exists

7、正则表达式(/需要匹配的字符?/i)

    与一般使用的正则表达式一样,Mongo使用Perl兼容的正则表达式(PCRE),语法方式:

        1)、     /需要匹配的字符/i   其中i可写可不写,可以匹配大小写忽略

        2)、     需要匹配的字符可以使用 ^ 表示开头,表示匹配任何

    db.user.find({"name":/^KEVIN50?/i});  # 匹配字符kevin50开头,忽略大小写的所有文档

8、数组查询

    1)、$all

    db.test.find({"movieId":{"$all":[1,3]}}); # 用户同时喜欢电影id为1和3的文档

    2)、$size

    db.test.find({"movieId":{"$size":2}}); # 用户喜欢的电影只有两个的文档

   3)、$slice

    find的第二个参数是可选项,用于设置指定需要返回的字段(见最上面一、基本查询的第二条)。不仅可以用于指定返回那些字段,还可用于执行返回的字段的前几条或后几条($slice,整数表示前多少条,负数反之)。

    db.test.find({},{"movieId":{"$slice": -1}});  # 返回文档条件的文档,但是需要过滤喜欢的电影,都只返回最好一个

    db.test.find({},{"movieId":{"$slice":[1,2]}}); # 查询范围偏移量

    4)、指定数组元素的第几个($)

    与slice比较相同,但是slice用于指定返回的前后的范围,但是不能精确的返回元素的第一个,可以用一个$符合进行查询,下标从1开始:

    db.test.find({},{"movieId.$": 2}); # 满足条件的文档,值返回第二个数组的元素(即喜欢的第二个电影)

9、内嵌文档

    内嵌文档可以使用正常的对象方式进行查询,也可以使用 (父字段名称.子字段名)方式进行查询:

    db.test.find({"name":{"first":"kevin","last":"li"}}); #  查询第一个名称为kevin,第二个名称为li的文档,等价于下面的:

    db.test.find({"name.first":"kevin","name.last":"li"});  # 同上

10、$where子语句

  $where子语句能够满足比较复杂的子查询,但是需要在服务端使用脚本进行设置,为安全起见,一般建议禁止使用。

 

三、MongoDB分页

 1、$limit、$skip、$sort(排序分页)

    db.user.find({}).skip(100).limit(10).sort({"name":1}); # 按照名称正序,跳过100条,查询10条数据

2、分页数非常大的时候的优化

    MongoDB与mysql一样,当分页查询需要过滤到很多的文档时性能特别低(每次需要查询非常多的文档,然后进行skip),所以像mysql一样,会有以下两种做法:

    1)、查询的时候,若对数据要求性不是那么高,比如展示给用户看的信息。则可以使用id>越过数,在limit的方式

    2)、若类似我们现在,每天搜索系统需要同步一次好几张表的全量数据,则可以在查询的时候,要求上一次返回查询的最后一条数据的id或者时间,先进行大于(_id或者时间)等操作,并且该操作一般会使用索引,然后再进行limit操作。

    而对于mongoDB还有一个非常重要的特性就是游标(Cursor),并且我们的项目中也已经在使用(但是游标使用也需要注意很多问题),后面进行专门讲解。

 

 

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值