这章我们学习MongoDB的查询操作。

Introduction to find

find方法用于执行MongoDB的查询操作。它返回collecion中的documents子集,没有添加参数的话它将返回整个collection数据。

例:查找c的所有数据

db.c.find()

find的第一个参数是查询条件,决定了返回哪些documents数据。

例:我们想要查找用户表中年龄为27的用户

db.users.find({"age":27})

假如我们想要多条件查询怎么办?只要在第一个参数里继续添加条件即可:

db.users.find({"age":27,"username":"joe"})

Specifying Which Keys to Return

有些时候查询你不需要返回所有的键值对。这时你可以在find或者findOne中的第二个参数里指定你想要返回的。

举个例子,你只要查询"username"和"email",这时可以这样写:

db.users.find({},{"username":1,"email":1})

这时返回:

{
"_id":ObjectId("4XXXX"),
"username":"joe",
"email":"joe@example.com"
}

"_id"是默认返回的,如果你连它也不需要返回,只需要这样写:

db.users.find({},{"username":1,"email":1,"_id":0})

Query Conditionals

"$lt","$lte","$gt","$gte"用于比较操作,相当于<,<=,>和>=

例如你想要查找年龄在18到30岁之间的用户:

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

"$ne" 用于不等于操作,例如你想要查询名字不为"joe"的用户,那你可以

db.users.find({"username":{"$ne":"joe"}})

OR Queries

在MongoDB中OR有两种方法:"$in"和"$or"。

如果你一个单独的key值有超过1种可能的值需要匹配,这时我们会用到"$in"。

假设我们想要查询彩票号码为725或者542或者390的document,我们可以这样

db.raffle.find({"ticket_no":{"$in":[725,542,390]}})

"$in"方法是非常灵活的,它允许你指定的值是不同的类型。

"$in"的方向操作是"$nin",例如我们不想查询彩票号码为725,542的document:

db.raffle.find({"ticket_no":{"$nin":[725,542]}})

那么,如果我们想要查询"ticket_no"为725或者"winner"为true的document,应该怎么写呢?

db.raffle.find({"$or":[{"ticket_no":725},{"winner":true}]})

再来个复杂点的:

db.raffle.find({"$or":[{"ticket_no":{"$in":[725,542]}},{"winner":true}]})

聪明如你,一定知道上面的意思啦~

$not

"$not"从字面意思来看,我想大家都能猜的出来。注意 它可以应用于所有条件之上。

我们先来看下"$mod","$mod"是用来取被除数的操作,它的第一个参数是除数,第二个是余数。

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

这个操作返回了用户的"id_num"为1,6,11,16...的document。

那么如果我们要求返回的"id_num"为2,3,4,5,7,8,9,10,12这些值该怎么办呢?这时候"$not"的作用就凸显出来了,我们只需要这样:

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

"$not"在与正则表达式的结合使用中是非常有用的,以后我们会介绍。

Conditional Semantics

假如你看过上一篇介绍的update modifiers,你会注意到以$为前缀的key会在不同的位置。在查询中,"$lt"在document里面;在更新中,“$inc”在document外面,

一般情况下这句话是对的:conditionals是一个docment的内部key,modifiers是document的外部key。

多个查询条件可以在一个单独的key中。举例,你想要查询年龄在20到30之间的用户,你会在"age"这个查询key中用到"$gt"和"$lt":

db.users.find({"age":{"$gt":20,"$lt":30}})

多个update modifiers不能被用在同一个key上,例如这样是错误的:

{"$inc":{"age":1},"$set":{"age":40}}

因为它改变了age两次。

还有一些元操作是用在document的外部的:"$and","$or","$nor"

他们都和下面的例子用法相似:

db.users.find({"$and":[{"x":{"$lt":1}},{"x":4}]})

Type-Specific Queries

null

null比较奇怪,它不仅能匹配自己也能匹配"does not exist"(也就是指缺少那个键的),如果在c中有这么几条条数据

{"_id":ObjectId("4XXX"),"y":null}
{"_id":ObjectId("4XXX"),"y":1}
{"_id":ObjectId("4XXX"),"y":2}

这时我们输入查询语句:

db.c.find({"z":null})

发现返回数据为:

{"_id":ObjectId("4XXX"),"y":null}
{"_id":ObjectId("4XXX"),"y":1}
{"_id":ObjectId("4XXX"),"y":2}

那么我们只想找值为null,我们可以这样写:

db.c.find({"y":{"$in":[null],"$exists":true}})

Regular Expressions

正则表达式对于字符串匹配是非常有用的。例如我们想要查找用户名为Joe或者joe的用户:

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

正则表达式也可以匹配自己:

>db.foo.insert({"bar": /baz/})
>db.foo.find({"bar": /baz/})
{
"_id":ObjectId("4XXX"),
"bar": /baz/
}

Querying Arrays

$all

我们先来插入几条数据

db.food.insert({"_id":1,"fruit":["apple","banana","peach"]})
db.food.insert({"_id":2,"fruit":["apple","kumquat","orange"]})
db.food.insert({"_id":3,"fruit":["cherry","banana","apple"]})

这时我们可以用$all查询包含apple和banana的数据:

db.food.find({"fruit":{"$all":["apple","banana"]}})

查询结果:

db.food.insert({"_id":1,"fruit":["apple","banana","peach"]})
db.food.insert({"_id":3,"fruit":["cherry","banana","apple"]})

我们来看看第二条返回结果,"banana"在"apple"前面,而查询条件中的"banana"是在后面,由此我们可以看出数组排序是无关紧要的。

另外,当$all中的数组中只有一个元素时,它的用法相当于不使用$all。

例:{"fruit":{"$all":["apple"]}}用法等同与{"fruit":"apple"}

你也可以对数组中的特定索引值进行匹配,例:

db.food.find({"fruit.2":"peach"})

上面的意思是对fruit字段的第3个值进行匹配。

$size

"$size"是一个很有用的查询条件,它允许你根据数组的长度进行匹配查找。

db.food.find({"fruit":{"$size":3}})

"$size"不能结合别的条件一起使用(例如$gt)

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

上面这种用法是错误的。

$slice

在之前的章节我们已经说过find的第二个参数用于返回特殊的key值。"$slice"可以返回数组key值的子集。

例:

 db.food.find({},{"fruit":{"$slice":2}})

返回的值为:

{ "_id" : 1, "fruit" : [ "apple", "banana" ] }
{ "_id" : 2, "fruit" : [ "apple", "kumquat" ] }
{ "_id" : 3, "fruit" : [ "cherry", "banana" ] }

另外"$slice"还能做分页

db.food.find({},{"fruit":{"$slice":[2,2]}})

上面的2代表skip2个元素,总的意思就是取3-4的数据。

这章暂时介绍到这,下章我们继续学习MongoDB的查询操作。

MongoDB 学习三的更多相关文章

  1. mongodb学习(三) 安装和基本CRUD

    菜鸟啊...先吐槽一下自己 发现mongodb已经升级到2.6标准版了.  服务端最新安装方法: http://www.cnblogs.com/lzrabbit/p/3682510.html 一 准备 ...

  2. MongoDB学习(三)

    MongoDB条件操作符 $gt  > 大于 $lt   < 小于 $gte >= 大于等于 $lte  <= 小于等于 $ne  !=  不等于 条件操作符可用于查询语句中, ...

  3. MongoDb学习三(spring-data-mongodb)

    本文采用2个种配置方式.xml配置 代码配置方式进行数据库的连接.实现简单的增删该查等一些操作.代码都有注释官方文档如下https://docs.spring.io/spring-data/mongo ...

  4. MongoDB学习笔记(三)--权限 && 导出导入备份恢复 && fsync和锁

    权限                                                                                             绑定内网I ...

  5. Mongodb学习笔记一(Mongodb环境配置)

    Mongodb学习 说明: MongoDB由databases组成,database由collections组成,collection由documents组成,document由fileds组成.Mo ...

  6. MongoDB学习记录

    一.操作符 "$lt" :"<""$lte" :"<=""$gt" :"> ...

  7. MongoDB学习(四)客户端工具备份数据库

    在上一篇MongoDB学习(三)中讲解了如何在服务器端进行数据的导入导出与备份恢复,本篇介绍下如何利用客户端工具来进行远程服务器的数据备份到本地. 以客户端工具MongoVUE为例来进行讲解: 1.首 ...

  8. MongoDB学习之--安全和认证

    MongoDB学习之--安全和认证 本文主要介绍两部分内容,Mongodb的安全检查配置以及安全认证操作: 虽然确保系统安全是系统管理员的重要工作,但是作为程序员了解其机制也是大有好处的,毕竟不是每个 ...

  9. MongoDB 学习笔记(原创)

    MongoDB 学习笔记 mongodb 数据库 nosql 一.数据库的基本概念及操作 SQL术语/概念 MongoDB术语/概念 解释/说明 database database 数据库 table ...

随机推荐

  1. Lua开发环境搭建(Mac OS X)

    1. 安装Rudix Rudix: http://rudix.org curl -O https://raw.githubusercontent.com/rudix-mac/rpm/2015.4/ru ...

  2. 在AxureRP8中实现广告文字滚动效果

    本文是实现动态文字在一个区域中滚动的效果,大概实现过程如下: 先准备一个区域,然后让文字在该区域内水平移动,本文是实现了从右到左的轮询的效果,其他雷同. 在Axure中,这种移动的过程需要动态移动,利 ...

  3. python 之 线程池实现并发

    使用线程池实现高IO并发 模块:ThreadPoolExecutor, as_completed 测试代码如下: #!/opt/python3/bin/python3 from concurrent. ...

  4. HDU 1011 Starship Troopers (树dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1011 题意: 题目大意是有n个房间组成一棵树,你有m个士兵,从1号房间开始让士兵向相邻的房间出发,每个 ...

  5. CentOS 笔记

    对安装CentOS安装使用过程中的问题做一个笔记,第一次安装,安装的是7.0版本,最小化安装. 安装环境 :Windows 2012 R2 Standard,Hyper-V Virstual Mach ...

  6. 邁向IT專家成功之路的三十則鐵律 鐵律十二:IT人養生之道-德行

    所謂的「養生」在中國古代裡所指的是針對內在精神層面修為的提升,到了近代中醫所謂的養生,則除了包含最根本的內在精神層面之外,還涵蓋了外在身體的養護.在現今各行各業的人士當中,嚴格來說都應該要有一套專屬的 ...

  7. sqlalchemy如何实现时间列自动更新?

    目标:数据表的时间列在其他列内容更新的时候,自动更新时间列到更新的时间 方法:数据库表模型如下:server_default表示初始时间,onupdate表示更新的时间 class MonitorDa ...

  8. C++精华笔记

    牛客微信推送的C++笔记:2016-12-12   14:23:26 1.C++不仅支持面向对象,也可以像C一样支持面向过程. 2.OOP三大特性:封装 继承 多态 3.函数重载依据:函数类型and形 ...

  9. SocketIO总结

    我在马克飞象上写的一样的内容,感觉那个样式好看的:WorkerMan的部分总结 workerman中部分函数总结 以下是把我搜集到的资料进行了一个整合.详细怎么使用.慢慢摸索吧. Worker类 中文 ...

  10. git 强制覆盖,分支合并

    强制合并 git fetch --all && git reset --hard origin/master && git pull 合并代码 git commit - ...