浅谈MongoDB中几种不同查询方法

数据库 其他数据库 MongoDB
在MongoDB数据中,查询有多种方法。比如find和or查询等等。每种查询方法也有不同的查询条件供大家参考。

 1.find

MongoDB使用find来进行查询.查询就是返回一个集合中文档的子集,子集合的范围从0个文档到整个集合.find的第一个参数

决定了要返回哪些文档.其形式也是一个文档,说明要查询的细节.

空的查询文档{}会匹配集合的全部内容.要是不指定查询文档,默认是{}.

如:db.users.find()返回集合users中的所有内容.

向查询文档中添加键值对,就意味着添加了查询条件.对绝大多数类型来说,整数匹配整数,布尔类型匹配布尔类型,字符串匹配

字符串.

2.指定返回的键

有时并不需要返回文档中的所有键值对返回.可以通过find或findOne的第二个参数来指定要返回的键.这样做能节省传输的

数据量,又能节省客户端解码文档的时间和内存消耗.

  1. db.users.findOne({"name":"refactor"},{"age":1,"sex":1}) 

只会将键为_id,age,sex的数据返回.

"_id"键总是会被返回.

也可以用第二个参数来剔除查询结果中的某个键值对.

如:

键name不会显示在返回的结果中

  1. db.users.findOne({"name":"refactor"},{"name":0}) 

只会将键为age,sex的数据返回."_id"键是不会返回的

  1. db.users.findOne({"name":"refactor"},{"age":1,"sex":1,"_id":0}) 

 3.查询条件

"$lt","$lte","$gt","$gte"分别对应<,<=,>,>=

如:

查询age >=18  <=30

db.users.find({"age":{"$gte":18,"$lte":30}})

向文档增加键birthday

 

  1. db.users.update( 
  2. {"name":"refactor"}, 
  3. "$set"
  4. "birthday":new Date("1989/10/26"

查询birthday日期是1990-1-1之前的人

  1. db.users.find({"birthday":{"$lt":new Date("1990/01/01")}}) 

使用"$ne"

查出所有name不等refactor1的文档,注意 文档中不存在键name的文档也会被查出来

  1. db.users.find({"name":{"$ne":"refactor1"}}) 

使用or查询

MongoDB可以使用"$in","$or"

使用"$in"

查询出pageViews为10000,20000的数据

  1. db.users.find({pageViews:{"$in":[10000,20000]}}) 

"$in"可以指定不同类型的条件和值,如正在将用户的ID号迁移成用户名的过程中,要做到两者兼顾的查询:

  1. db.users.find({"user_id":{"$in":[12345,"refactor"]}}) 

这会匹配user_id为12345和"refactor"的文档.

要是 "$in"的数组只有一个值和直接匹配这个值效果是一样的.

 

  1. db.users.find({"pageViews":{"$in":[10000]}}) 
  2. db.users.find({"pageViews":10000}) 

使用"$nin"返回与数组中所有条件都不匹配的文档

如 查出所有pageViews不等10000,20000的文档,注意 文档中不存在键pageViews的文档也会被查出来

  1. db.users.find({"pageViews":{"$nin":[10000,20000]}}) 

"$in"能对单个键进行or查询.

使用"$or"

 

  1. db.users.find( 
  2. "$or"
  3. {"pageViews":{"$in":[10000,20000]}}, 
  4. {"url":"http://www.cnblogs.com/refactor"

这将查询出pageViews是10000,20000或url是http://www.cnblogs.com/refactor的文档.

注意:使用普通的and查询时,要尽量将最苛刻的条件放在前面.

使用"$not"

"$not"可以用在任何条件之上.

如:

 

  1. db.users.find( 
  2. {"id_num":{"mod":[5,1]}} 

这会查询出id_num取模后值为1的文档.

 

  1. db.users.find( 
  2. {"id_num":{"$not":{"mod":[1,5]}}} 

4.条件句的规则

在查询中,"$lt"在内层文档,在更新中"$inc" 是外层文档的键.

条件句是内层文档的键,修改器是外层文档的键.

可对一个键应用多个条件,但一个键不能对应多个更新修改器.

5.特定于类型的查询

null可以匹配自身,而且可以匹配"不存在的"

能查出url 是"http://www.cnblogs.com/refactor",pageViews为null的文档

 

  1. db.users.find({"url":"http://www.cnblogs.com/refactor","pageViews":null}) 

能查出pageViews为null的文档,不存在键pageViews的也能查出来

 

  1. db.users.find({"pageViews":null}) 

能查出url 是"http://www.cnblogs.com/refactor",pageViews为null的文档,但不能查出不存在键pageViews的的文档
db.users.find({"url":"http://www.cnblogs.com/refactor","pageViews":{"$in":[null],"$exists":true}})

MongoDB没有"$eq"操作符,但是只有一个元素的"$in"的操作效果是一样的

如果仅仅想要匹配键值为null的文档,既要检查该键的值是否为null,还要通过"$exists"条件判断该键是不是存在.

6.正则表达式

正则表达式能够灵活有效的匹配字符串.

查找所有名包含refact或Refact的用户,使用正则表达式执行忽略大小写的匹配

 

  1. db.users.find({"name":/refact/i}) 

系统可以接受正则表达式标识(i),但不是一定有.现在匹配了各种大小写形式的refact.

MongoDB可以为前缀型正则表达式(如:/^refactor/)查询创建索引.所以这种类型的查询非常高效.

正则表达式也可以匹配自身

 

  1. db.users.find({"name":/refact/}) 

可以查出name为/refact/的文档.

7.查询数组

数组很大多数情况下可以这样理解:每一个元素都是整个键的值.

db.users.findOne({"userName":"refactor","emails":"295240648@qq.com"})能匹配到

使用"$all"

如果需要多个元素来匹配数组,就要用"$all"

db.users.insert({"userName":"refactor",emails:["295240648@qq.com","295240648@163.com","295240648@126.com"]})
db.users.insert({"userName":"refactor",emails:["295240648@qq.com","295240648@126.com","295240648@111.com"]})
db.users.insert({"userName":"refactor",emails:["295240648@126.com","295240648@163.com","295240648@111.com"]})

要找到邮箱有"295240648@163.com"又有"295240648@126.com",顺序无关紧要的文档

  1. db.users.find( 
  2. "emails"
  3. "$all"
  4. "295240648@163.com"
  5. "295240648@126.com" 

要是只对一个元素的数组使用"$all"就和不用"$all"是一样的,如

 

  1. db.users.find({"emails":{"$all":["295240648@126.com"]}}) 
  2. db.users.find({"emails":"295240648@126.com"}) 

效果是一样的.

也可以精确的匹配数组

  1. db.users.find({"userName":"refactor",emails:["295240648@qq.com","295240648@163.com","295240648@126.com"]}) 

若想查询数组指定位置的元素,需要使用key.index语法指定下标

db.users.find({"emails.1":"295240648@163.com"})

使用"$size"

"$size"可以查询指定长度的数组

查询数组长度为3的数组

db.users.find({"emails":{"$size":3}})

常见的查询是数组长度范围的查询."$size"并不能与其他查询子句组合(如:"$gt"),但是这种查询可以通过

在文档中添加一个"size"键的方式来实现.这样每一次向指定数组添加元素的时候,同时增加"size"值.原来这样

的更新:

db.users.update({"$push":{"emails":"295240648@139.com"}})

变成这样的更新:
db.users.update({"$push":{"emails":"295240648@139.com"},"$inc":{"size":1}})

这样就可以这样查询了

db.users.find({"size":{"$gt":3}})

 

使用"$slice"查询

find的第二个参数是可选的,可以指定返回那些键,"$slice"返回数组的一个子集合

返回emails数组的前两个元素

 

  1. db.users.find({"userName":"refactor"},{"emails":{"$slice":2}}) 

返回emails数组的后两个元素

 

  1. db.users.find({"userName":"refactor"},{"emails":{"$slice":-2}}) 

返回emails数组的第2个和第11个元素.如果数组不够11个,则返回第2个后面的所有元素

 

  1. db.users.find({"userName":"refactor"},{"emails":{"$slice":[1,10]}}) 

"$slice"默认将返回文档中的所有键. 

原文链接:http://www.cnblogs.com/refactor/archive/2012/07/30/2591344.html

【编辑推荐】

  1. MongoDB 2.0 正式版发布
  2. MongoDB 2.0新功能逐个看之Compact Command
  3. 主流NoSQL数据库全方位评测之MongoDB
  4. 教你如何利用MySQL学习MongoDB
  5. 在Windows环境下MongoDB搭建和简单操作

 

 

责任编辑:彭凡 来源: 博客园
相关推荐

2009-05-21 09:24:42

表空间查询Oracle

2009-06-08 10:20:01

Hibernate查询

2010-06-10 17:59:05

2019-11-15 10:01:07

MySQL数据库数据

2009-06-29 09:03:31

Hibernate多条

2013-05-27 10:11:25

路由器查询方式路由器递归查询路由器扑朔图

2010-11-15 16:26:46

Oracle系统时间

2009-06-17 15:52:23

Hibernate查询

2010-10-29 11:22:23

Oracle用户会话

2009-01-27 21:00:00

服务器数据库SQL Server

2010-11-25 16:40:11

MySQL大表重复字段

2009-07-21 14:15:00

iBATIS.NET多

2024-03-04 11:13:29

Django数据库Python

2022-06-21 08:13:34

MySQL查询数据库

2009-01-20 10:51:00

局域网IP地址分配

2010-09-14 15:51:15

sql遍历

2018-09-06 16:46:33

数据库MySQL分页查询

2009-07-28 16:07:40

.NET图片快速处理

2011-03-21 13:44:38

SQL ServerSQL Server2分页

2012-03-22 09:31:14

Java
点赞
收藏

51CTO技术栈公众号