MongoDB 是一个高性能,开源,无模式的文档型数据库,是当前noSql数据库产品中最热门的一种。它在许多场景下用于替代传统的关系型数据库或键值对存储方式,MongoDB是用C++开发
随着互联网 web2.0 网站的兴起,非关系型的数据库现在成了一个极其热门的新领域,非关系数据库产品的发展非常迅速,而传统的关系型数据库在应付 web2.0 网站,特别是超大规 模和高并发的 SNS 类型的 web2.0 纯动态网站已经显得力不从心,暴露了很多难以克服的问题,例如:
High performance - 对数据库高并发读写的需求web2.0 网站要根据用户个性化信息来实时生成动态页面和提供动态信息,所以基本上无法使用动态页面静态化技术,因此数据库并发负载非常高,往往要达到每秒上万次读写请求
关系型数据库应付上万次 SQL 查询还勉强顶得住,但是应付上万次 SQL 写数据请求,硬盘IO 就已经无法承受了,其实对于普通的 BBS 网站,往往也存在对高并发写请求的需求
Huge Storage - 对海量数据的高效率存储和访问的需求对于大型的 SNS 网站,每天用户产生海量的用户动态信息,以国外的 Friend feed 为例,一个月就达到了 2.5 亿条用户动态,对于关系数据库来说,在一张 2.5 亿条记录的表里面进行SQL 查询,效率是极其低下乃至不可忍受的。再例如大型 web 网站的用户登录系统,例如腾讯,盛大,动辄数以亿计的帐号,关系数据库也很难应付
High Scalability&&HighAvailability-对数据库的高可扩展性和高可用性的需求在基于 web 的架构当中,数据库是最难进行横向扩展的,当一个应用系统的用户量和访问量与日俱增的时候,你的数据库却没有办法像 web server 和 app server 那样简单的通过添加
更多的硬件和服务节点来扩展性能和负载能力。对于很多需要提供 24 小时不间断服务的网站来说,对数据库系统进行升级和扩展是非常痛苦的事情,往往需要停机维护和数据迁移,可是停机维护随之带来的就是公司收入的减少
在上面提到的“三高”需求面前,关系数据库遇到了难以克服的障碍,而对于 web2.0 网站来说,关系数据库的很多主要特性却往往无用武之地,例如:
数据库事务一致性需求很多 web 实时系统并不要求严格的数据库事务,对读一致性的要求很低,有些场合对写一致性要求也不高。因此数据库事务管理成了数据库高负载下一个沉重的负担
数据库的写实时性和读实时性需求对关系数据库来说,插入一条数据之后立刻查询,是肯定可以读出来这条数据的,但是对于很多 web 应用来说,并不要求这么高的实时性
对复杂的SQL查询,特别是多表关联查询的需求任何大数据量的 web 系统,都非常忌讳多个大表的关联查询,以及复杂的数据分析类型的复杂 SQL 报表查询,特别是 SNS 类型的网站,从需求以及产品设计角度,就避免了这种情 况的产生。往往更多的只是单表的主键查询,以及单表的简单条件分页查询,SQL 的功能被极大的弱化了
因此,关系数据库在这些越来越多的应用场景下显得不那么合适了,为了解决这类问题的NoSQL 数据库应运而生。 NoSQL 是非关系型数据存储的广义定义。它打破了长久以来关系型数据库与 ACID 理论大一统的局面。NoSQL 数据存储不需要固定的表结构,通常也不存在连接操作。在大数据存取上具备关系型数据库无法比拟的性能优势,该概念在 2009 年初得到了广泛认同。 当今的应用体系结构需要数据存储在横向伸缩性上能够满足需求。而 NoSQL 存储就是为了实现这个需求。 Google 的 BigTable 与 Amazon 的 Dynamo 是非常成功的商业 NoSQL 实现。一些开源的 NoSQL 体系,如 Facebook的Cassandra,Apache的HBase,也得到了广泛认同。从这些NoSQL项目的名字上看不出什么相同之处:Hadoop、Voldemort、Dynomite,还有其它很多,但它们都有一个共同的特点,就是要改变大家对数据库在传统意义上的理解。
集群扩充起来非常方便并且成本很低,避免了传统商业数据库“sharding”操作的复杂性和成本。
它击碎了性能瓶颈NoSQL 的支持者称,通过 NoSQL 架构可以省去将 Web 或 Java 应用和数据转换成 SQL 格式的时间,执行速度变得更快。“SQL并非适用于所有的程序代码”,对于那些繁重的重复操作的数据,SQL 值得花钱。但是当数据库结构非常简单时,SQL 可能没有太大用处
它没有过多的操作虽然 NoSQL 的支持者也承认关系型数据库提供了无可比拟的功能集合,而且在数据完整性上也发挥绝对稳定,他们同时也表示,企业的具体需求可能没有那么复杂
它的支持者源于社区因为 NoSQL 项目都是开源的,因此它们缺乏供应商提供的正式支持。这一点它们与大多数开源项目一样,不得不从社区中寻求支持
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似 json 的 bjson 格式,因此可以存储比较复杂的数据类型。MongoDB 最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。它是一个面向集合的,模式自由的文档型数据库
面向集合(Collenction-Orented)意思是数据被分组存储在数据集中, 被称为一个集合(Collenction)。每个集合在数据库中都有一个唯一的标识名,并且可以包含无限数目的文档。集合的概念类似关系型数据库里的表(table),不同的是它不需要定义任何模式(schema)
模式自由(schema-free)意味着对于存储在 MongoDB 数据库中的文件,我们不需要知道它的任何结构定义。提了这么多次"无模式"或"模式自由",它到是个什么概念呢?例如,下面两个记录可以存在于同一个集合里面: {"welcome" : "Beijing"} {"age" : 25}
文档型意思是我们存储的数据是键-值对的集合,键是字符串,值可以是数据类型集合里的任意类型,包括数组和文档. 我们把这个数据格式称作 “BSON” 即 “Binary Serialized document Notation.”
下面将分别介绍 MongoDB 的特点、功能和适用场合
特点 面向集合存储,易于存储对象类型的数据模式自由支持动态查询支持完全索引,包含内部对象支持查询支持复制和故障恢复使用高效的二进制数据存储,包括大型对象(如视频等)自动处理碎片,以支持云计算层次的扩展性支持 Python,PHP,Ruby,Java,C,C#,Javascript,Perl 及 C++语言的驱动程序,社区中也提供了对 Erlang 及.NET 等平台的驱动程序文件存储格式为 BSON(一种 JSON 的扩展)可通过网络访问 功能 面向集合的存储:适合存储对象及 JSON 形式的数据动态查询:MongoDB 支持丰富的查询表达式。查询指令使用 JSON 形式的标记,可轻易查询文档中内嵌的对象及数组完整的索引支持:包括文档内嵌对象及数组。MongoDB 的查询优化器会分析查询表达式,并生成一个高效的查询计划 查询监视:MongoDB 包含一系列监视工具用于分析数据库操作的性能复制及自动故障转移:MongoDB 数据库支持服务器之间的数据复制,支持主-从模式及服务器之间的相互复制。复制的主要目标是提供冗余及自动故障转移高效的传统存储方式:支持二进制数据及大型对象(如照片或图片)自动分片以支持云级别的伸缩性:自动分片功能支持水平的数据库集群,可动态添加额外的机器 适用场合 网站数据:MongoDB 非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性缓存:由于性能很高,MongoDB 也适合作为信息基础设施的缓存层。在系统重启之后,由 MongoDB 搭建的持久化缓存层可以避免下层的数据源过载大尺寸,低价值的数据:使用传统的关系型数据库存储一些数据时可能会比较昂贵,在此之前,很多时候程序员往往会选择传统的文件进行存储高伸缩性的场景:MongoDB 非常适合由数十或数百台服务器组成的数据库。MongoDB的路线图中已经包含对 MapReduce 引擎的内置支持用于对象及 JSON 数据的存储:MongoDB 的 BSON 数据格式非常适合文档化格式的存储及查询mongodb官网
https://www. mongodb.com/download-ce nter#community
https:// fastdl.mongodb.org/win3 2/mongodb-win32-x86_64-2008plus-ssl-3.0.6-signed.msi
1、解压到一个指定的路径 D:\Program Files\MongoDB 的目录下
2、先在当前文件下创建一个配置文件 mongo.conf , 如下添加配置内容
dbpath=D:\Program Files\MongoDB\data #数据库路径 logpath=D:\Program Files\MongoDB\logs\mongo.log #日志输出文件路径 logappend=true #错误日志采用追加模式 journal=true #启用日志文件,默认启用 quiet=true #这个选项可以过滤掉一些无用的日志信息,若需要调试使用请设置为false port=27017 #端口号 默认为270173、在D:\Program Files\MongoDB目录下创建 data 文件夹(数据库路径 ) 和 logs 文件夹(日志文件夹),logs目录下新建mongo.log文件。
4、在bin 目录下,启动命令行,输入:
mongod --config "D:\Program Files\MongoDB\mongo.conf"(前面1~4的步骤时配置脚本,建议按照步骤执行。如果敲完第4步的命令,命令行出现等待的状态,不能再次输入则可关闭,继续执行下面的步骤)
5、不要关闭命令行页面,指定写入数据文件目录
mongod.exe --dbpath "D:\Program Files\MongoDB\data"6、再在当前目录下启动 cmd ,启动一个命令行,输入
mongo.exe如果能访问127.0.0.1:27017,说明服务已经启动成功了。
以上步骤是启动服务,只能在cmd 窗口启动的情况下,关闭cmd 命令行窗口就会终止服务。这时就需要添加系统服务里,不用每次使用都得启动一次。
7、将MongoDB加入windows服务,在bin 目录下启动 cmd (以管理员身份运行)键入以下命令:
mongod.exe --logpath "D:\Program Files\MongoDB\logs\mongo.log" --logappend --dbpath "D:\Program Files\MongoDB\data" --directoryperdb --serviceName MongoDB --install如果提示失败的话 window不能启动非计算机的服务MongoDB
如果没有提示,则可在服务中查找看使得否已经出现MongoDB服务。一般刚创建好是停止的状态,这是只要点击启动即可。
处理方法:
1、删除MongoDB目录下data目录下的mongod.lock和storage.bson文件。
2、删除原本添加的MongoDB服务
sc delete 服务名称: sc delete MongoDB3、重新添加MongoDB到系统服务
mongod.exe --logpath "D:\Program Files\MongoDB\logs\mongo.log" --logappend --dbpath "D:\Program Files\MongoDB\data" --directoryperdb --serviceName MongoDB --install4、在windows 服务里查看MongoDB服务,显示是否已启动。
3. 数据类型
MongoDB中常用的几种数据类型
注:table在mongodb里叫collections
已存在数据: {_id : 'abc123', " name " : " 小王 " } 再次进行插入操作时 insert({_id : 'abc123', " name " : " 小李 " }) 会报主键重复的错误提示
save({ _id : 'abc123', " name " : " 小李 " }) 会把 小王 修改为 小李 如果集合中不存在 _id : 'abc123', insert({_id : 'abc123', " name " : " 小李 " }) 增加一条数据 save({ _id : 'abc123', " name " : " 小李 " }) 增加一条数据
判断是否有某个字段
db.集合名称.find({'field':{$exists:true}})去重
db.集合名称.distinct(field)注意 :原insert方法也可以实现上面的功能,但是在PyMongo 3.x的版本已经不推荐使用了
比较符号
功能符号
注意: 也可以实现上面的功能,但是在PyMongo 3.x的版本已经不推荐使用了
代码:
注意: mongodb的save和insert函数都可以向collection里插入数据,但两者是有两个区别:
使用save函数里,如果原来的对象不存在,那他们都可以向collection里插入数据,如果已经存在,save会调用update更新里面的记录,save则需要遍历列表,一个个插入,效率稍低 而insert则会忽略操作,insert可以一次性插入一个列表,而不用遍历,效率高 例如: 已存在数据: {_id : 'abc123', " name " : " 小王 " } 再次进行插入操作时 insert({_id : 'abc123', " name " : " 小李 " }) 会报主键重复的错误提示 save({ _id : 'abc123', " name " : " 小李 " }) 会把 小王 修改为 小李 。 如果集合中不存在 _id : 'abc123',insert({_id : 'abc123', " name " : " 小李 " }) 增加一条数据save({ _id : 'abc123', " name " : " 小李 " }) 增加一条数据 查看当前使用的数据库:db 或 db.getName() 两者效果一样 显示当前数据库的状态:db.stats() 显示当前数据库的版本 :db.version() 显示当前数据库链接的地址:db.getMongo() 在指定的机器上,从数据库A,负责数据到B:db.copyDatabase("mydb", "temp", "127.0.0.1") 将本机的mydb的数据复制到temp数据库中 显示当前数据库中所有集合: db.getCollectionNames() 显示数据库的状态:db.table.stats() 删除当前数据库中某个集合:db.table.drop() 删除集合 table 删除当前数据库某个集合中的所有数据:db.table.remove({}) 删除集合 table中所有数据 删除当前数据库某个集合中name='test'的记录:db.table.remove({name:'test'}) 删除当前数据库某个集合中所有数据:db.Information.remove({})db.table.find()
查询age = 22的记录db.table.find({age:22})
查询age >22的记录db.table.find({age:{$gt:22}}) db.table.find("this.age>22")
查询age>=22的记录db.table.find({age:{$gte:22}}) db.table.find("this.age>=22")
查询age <30的记录db.table.find({age:{$lt:30}}) db.table.find("this.age < 30")
查询age <=30的记录db.table.find({age:{$lte:30}}) db.table.find("this.age<=30")
查询age >20 并且age< 30的记录db.table.find({age:{gt:20,lt :30}}) db.table.find("this.age>20 && this.age< 30")
查询集合中name 包含mongo的数据,相当于like '%mongo%' 模糊查询db.table.find({name:/mongo/})
查询集合中 name中以mongo开头的数据,相当于like 'mongo%' 模糊查询db.table.find({name:/^mongo/})
查询集合中,只查询,name和age两列db.table.find({},{name:1,age:1}) 查询结合中age>10 ,并且只查询 name 和 age两列db.table.find({age:{$gt:10}},{name:1,age:1}) 按年龄排序 ``` db.table.find().sort({age:1,name:1}) 按照年龄和姓名升序 db.table.find().sort({age:-1,name:1}) 按照年龄降序,姓名升序 python db.table.find().sort(‘age‘,pymongo.ASCENDING) 或 db.table.find().sort(‘age‘,1)升序; db.table.find().sort(‘age‘,pymongo.DESCENDING) 或 db.table.find().sort(‘age‘,-1)降序 db.table.find().sort([(‘age‘,pymongo.DESCENDING),('name',pymongo.ASCENDING)]) 年龄降序,姓名升序 或 db.table.find().sort([(‘age‘,-1),('name':1)])年龄降序,姓名升序 ``` 注意mongo和python里面命令的区别是冒号,python是逗号 查询前10条数据,相当于select top 10 from tabledb.table.find().limit(10) 查询10条以后的数据,相当于 select * from table where id not in (select top * from table )db.table.find().skip(10) 查询5-10条之间的数据db.table.find().skip(5).limit(10) 查询 age =10 or age =20的记录db.table.find({$or:[{age:20},{age:30}]}) 查询age >20的记录条数db.table.find({age:{$gt:20}}).count() 查询age>30 or age <20 的记录db.table.find({or:[{age:{gt:30}},{age:{$lt:20}}]}) db.table.find("this.age>30 || this.age < 20") 查询age > 40 or name ='mike'的记录 db.table.find({or:[{age:{gt:40}},{name:'mike'}]}) 查询age > 40 or name ='mike'的记录,只查询name 和age两列,并且按照name升序,age降序db.table.find({or:[{age:{gt:40}},{name:'mike'}]},{name:1,age:-1}) 查询age > 40 并且 name ='mike'的记录,只查询name 和age两列,并且按照name升序,age降序db.table.find({and:[{age:{gt:40}},{name:'mike'}]},{name:1,age:-1}) python 代码db.table.find({'and':[{age:{'$gt':40}},{'name':'mike'}]},{'name':1,'age':-1}) 像and和字段名必须在引号内,否则报错 查询age 在[30,40] 内的记录db.table.find({age:{$in:[30,40]}}) 查询age不在[30,40]范围内的记录db.table.find({age:{$nin:[30,40]}}) 查询age能被3整除的记录db.table.find({age:{$mod:[3,0]}}) 查询age能被3整除余2的记录db.table.find({age:{$mod:[3,2]}})//假如有以下文档 { 'name' : { 'first' : 'Joe', 'last' : 'Schmoe' } 'age' : 45 }
查询姓名为询姓名是Joe Schmoe的记录``` db.table.find({'name.first':'Joe','name.last':'Schmoe'})
db.table.find({name:{first:'Joe',last:'Schmoe'}}) ```
如果需要多个元素来匹配数组,就需要使用$all了//假设在我们表中3个下面的文档:
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']})要找到既有apple又有banana的文档:
db.food.find({fruit:{$all:['apple', 'banana']}}) 查询age不是30并且性别不是‘男’的记录,就用到 $nordb.person.find({$nor:[{age:30},{sex:'男'}]})
查询age不大于30的记录,用到not,not执行逻辑NOT运算,选择出不能匹配表达式的文档 ,包括没有指定键的文档。``` db.person.find({age:{not:{gt:30}}})
```
如果$exists的值为true,选择存在该字段的文档;若值为false则选择不包含该字段的文档。选择age存在,且不在[30,40]只能的记录
db.person.find({age:{exists:true,nin:[30,40]}}) 查询name中包括字母t的记录,类似 name like '%t%'``` db.person.find({name:/t/})
db.person.find({name:{$regex:/t/}})
db.person.find({name:/t/i}) i在这里是不区分大小写
db.person.find({name:{regex:/t/,options:'i'}}) i在这里是不区分大小写
```
查询name中以t字母结尾的记录,类似 name like '%t', 要用到符号$``` db.person.find({name:/t$/})
```
如果在查询的时候需要多个元素来匹配数组,就需要用到$all了,这样就匹配一组元素。例如:假如创建了包含3个元素的如下集合:
``` { "_id" : 1, "fruit" : [ "apple", "banana", "peach" ] } { "_id" : 2, "fruit" : [ "apple", "pear", "orange" ] } { "_id" : 3, "fruit" : [ "cherry", "banana", "apple" ] }
```
要找到既有apple, 又有banana的文档,就要用到$all
db.food.find({fruit:{$all:['apple','banana']}})查询结果如下:
db.food.find({fruit:{$all:['apple','banana']}}) { "_id" : 1, "fruit" : [ "apple", "banana", "peach" ] } { "_id" : 3, "fruit" : [ "cherry", "banana", "apple" ] }注意两条结果记录的apple和banana的顺序是不一样的,也就是说,顺序无关紧要。
要是想查询指定数组位置的元素,则需要用key.index语法指定下标
db.food.find({'fruit.2':'peach'}),结果为:{ "_id" : 1, "fruit" : [ "apple", "banana", "peach" ] }
nullnull比较奇怪,它确实能匹配本身,假如有下面的数据:
{ "_id" : 1, "fruit" : [ "apple", "banana", "peach" ] } { "_id" : 2, "fruit" : [ "apple", "pear", "orange" ] } { "_id" : 3, "fruit" : [ "cherry", "banana", "apple" ] } { "_id" : 4, "fruit" : null }db.food.find({fruit:null}) 查询结果:
{ "_id" : 4, "fruit" : null }但是null不仅能匹配本身,而且能匹配“不存在的” ,例如:
db.food.find({x: null}) ,food集合中本来不包含x键的,结果如下:
db.food.find({x:null})
{ "_id" : 1, "fruit" : [ "apple", "banana", "peach" ] } { "_id" : 2, "fruit" : [ "apple", "pear", "orange" ] } { "_id" : 3, "fruit" : [ "cherry", "banana", "apple" ] } { "_id" : 4, "fruit" : null } $size 对于查询来说也是意义非凡,顾名思义就是可用它来查询指定长度的数组比如有以下数据:
{ "_id" : 1, "fruit" : [ "apple", "banana", "peach" ] } { "_id" : 2, "fruit" : [ "apple", "pear", "orange" ] } { "_id" : 3, "fruit" : [ "cherry", "banana", "apple" ] } { "_id" : 4, "fruit" : null } { "_id" : 5, "fruit" : [ "apple", "orange" ] }db.food.find({fruit:{$size:3}})
查询结果如下:fruit对应的数组的长度为3
{ "_id" : 1, "fruit" : [ "apple", "banana", "peach" ] } { "_id" : 2, "fruit" : [ "apple", "pear", "orange" ] } { "_id" : 3, "fruit" : [ "cherry", "banana", "apple" ] }db.food.find({fruit:{$size:1}})
查询结果如下:fruit对应的数组的长度为1
{ "_id" : 5, "fruit" : [ "apple", "orange" ] } slice 可以按偏移量返回记录,针对数组。如{"slice":10}返回前10条,{"$slice":{[23,10]}}从24条取10条
例如在集合food中有数据如下:
{ "_id" : 1, "fruit" : [ "apple", "pear", "orange", "strawberry", "banana" ], "name" : "fruitName1" } { "_id" : 2, "fruit" : [ "apple", "orange", "pear", "banana" ], "name" : "fruitName2" } { "_id" : 3, "fruit" : [ "cherry", "banana", "apple" ], "name" : "fruitName3" } { "_id" : 4, "fruit" : null }
针对fruit 如何只获取该键对应数据前个数据,{"$slice":2}
查询语句:db.food.find({},{fruit:{$slice:2}}) 查询结果为:
{ "_id" : 1, "fruit" : [ "apple", "pear" ], "name" : "fruitName1" } 注意fruit对应的数据,只获取了,前两个数据,后面的去掉了 { "_id" : 2, "fruit" : [ "apple", "orange" ], "name" : "fruitName2" } { "_id" : 3, "fruit" : [ "cherry", "banana" ], "name" : "fruitName3" } { "_id" : 4, "fruit" : null }
针对fruit 如何只获取该键对应数据从第二个数据开始取,取两个,{"$slice":[1,2]}
查询语句:db.food.find({},{fruit:{$slice:[1,2]}}) 查询结果为:
{ "_id" : 1, "fruit" : [ "pear", "orange" ], "name" : "fruitName1" } { "_id" : 2, "fruit" : [ "orange", "pear" ], "name" : "fruitName2" } { "_id" : 3, "fruit" : [ "banana", "apple" ], "name" : "fruitName3" } { "_id" : 4, "fruit" : null }
$elemMatch 如果对象有一个元素是数组,那么$elemMatch可以匹配内数组内的元素。例如数据集school中有如下数据:
``` { "_id" : 1, "zipcode" : "63109", "students" : [ { "name" : "john", "school" : 102, "age" : 10 }, { "name" : "jess", "school" : 102, "age" : 11 }, { "name" : "jeff", "school" : 108, "age" : 15 } ] } { "_id" : 2, "zipcode" : "63110", "students" : [ { "name" : "ajax", "school" : 100, "age" : 7 }, { "name" : "achilles", "school" : 100, "age" : 8 } ] } { "_id" : 3, "zipcode" : "63108", "students" : [ { "name" : "ajax", "school" : 100, "age" : 7 }, { "name" : "achilles", "school" : 100, "age" : 8 } ] } { "_id" : 4, "zipcode" : "63109", "students" : [ { "name" : "barney", "school" : 102, "age" : 7 }, { "name" : "ruth", "school" : 102, "age" : 16 } ] } { "_id" : 5, "zipcode" : "63109", "students" : [ { "name" : "barney", "school" : 102, "age" : 12 }, { "name" : "ruth", "school" : 102, "age" : 16 } ] }
```
要查询 zipcode="63109" ,school= ‘102’ 并且 age>10的记录
db.school.find( { zipcode: "63109" },{ students: { elemMatch: { school: 102 ,age:{gt: 10}} } } )查询结果:
{ "_id" : 1, "students" : [ { "name" : "jess", "school" : 102, "age" : 11 } ] } { "_id" : 4, "students" : [ { "name" : "ruth", "school" : 102, "age" : 16 } ] } { "_id" : 5, "students" : [ { "name" : "barney", "school" : 102, "age" : 12 } ] } $exists判断某个字段是否存在,查询school集合中存在zipcode字段的记录
``` db.school.find({zipcode:{$exists:1}})
```
假如有集合school ,数据如下:``` { "_id" : 1, "zipcode" : "63109", "students" : [ { "name" : "john", "school" : 102, "age" : 10 }, { "name" : "jess", "school" : 102, "age" : 11 }, { "name" : "jeff", "school" : 108, "age" : 15 } ] } { "_id" : 2, "zipcode" : "63110", "students" : [ { "name" : "ajax", "school" : 100, "age" : 7 }, { "name" : "achilles", "school" : 100, "age" : 8 } ] } { "_id" : 3, "zipcode" : "63109", "students" : [ { "name" : "ajax", "school" : 100, "age" : 7 }, { "name" : "achilles", "school" : 100, "age" : 8 } ] } { "_id" : 4, "zipcode" : "63109", "students" : [ { "name" : "barney", "school" : 102, "age" : 7 }, { "name" : "ruth", "school" : 102, "age" : 16 } ] } { "_id" : 5, "zipcode" : "63109", "students" : [ { "name" : "barney", "school" : 102, "age" : 12 }, { "name" : "ruth", "school" : 102, "age" : 16 } ] }
```
如果只查询students字段里面的内容,并且只查询school =102 的姓名和年龄信息:
查询语句为:
`` db.school.find({'students.school':102},{'students.name':1,'students.age':1})
```
结果如下:
``` { "_id" : 1, "students" : [ { "name" : "john", "age" : 10 }, { "name" : "jess", "age" : 11 }, { "name" : "jeff", "age" : 15 } ] } { "_id" : 4, "students" : [ { "name" : "barney", "age" : 7 }, { "name" : "ruth", "age" : 16 } ] } { "_id" : 5, "students" : [ { "name" : "barney", "age" : 12 }, { "name" : "ruth", "age" : 16 } ] }
```
假设school 集合中包含一些记录:students字段对应一个数据字典
``` { "_id" : 7, "zipcode" : "63109", "students" : { "name" : "jike", "school" : "102", "age" : 45 } } { "_id" : 8, "zipcode" : "63109", "students" : { "name" : "Marry", "school" : "100", "age" : 75 } }
```
如果只查询字段students对应name和age信息,则查询语句如下:
``` db.school.find({_id:{$gt:5}},{'students.name':1,'students.age':1})
```
结果为:这里_id是必须要显示的
{ "_id" : 7, "students" : { "name" : "jike", "age" : 45 } } { "_id" : 8, "students" : { "name" : "Marry", "age" : 75 } }