![MongoDB与Redis(从入门到商业实战)_第1页](http://file4.renrendoc.com/view6/M01/0A/0C/wKhkGWeKrjWAfcjpAABNqpQcOqk984.jpg)
![MongoDB与Redis(从入门到商业实战)_第2页](http://file4.renrendoc.com/view6/M01/0A/0C/wKhkGWeKrjWAfcjpAABNqpQcOqk9842.jpg)
![MongoDB与Redis(从入门到商业实战)_第3页](http://file4.renrendoc.com/view6/M01/0A/0C/wKhkGWeKrjWAfcjpAABNqpQcOqk9843.jpg)
![MongoDB与Redis(从入门到商业实战)_第4页](http://file4.renrendoc.com/view6/M01/0A/0C/wKhkGWeKrjWAfcjpAABNqpQcOqk9844.jpg)
![MongoDB与Redis(从入门到商业实战)_第5页](http://file4.renrendoc.com/view6/M01/0A/0C/wKhkGWeKrjWAfcjpAABNqpQcOqk9845.jpg)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
MongoDB与Redis从入门到商业实战目录\h第1篇基础知识\h第1章进入MongoDB与Redis的世界\h1.1非关系型数据库的产生背景与分类\h1.1.1关系型数据库遇到的问题\h1.1.2非关系型数据库的分类及特点\h1.2MongoDB与Redis可以做什么\h1.2.1MongoDB适合做什么\h1.2.2Redis适合做什么\h1.3如何学习MongoDB和Redis\h1.3.1项目驱动,先用再学\h1.3.2系统梳理,由点到面\h1.3.3分清主次,不要在无谓的操作中浪费时间\h1.3.4在不同领域中尝试\h1.4如何使用本书\h1.4.1本书的产品定位\h1.4.2本书适用的读者群体\h1.4.3如何利用本书实例进行练习\h第2章数据存储方式的演进\h2.1从文件到MongoDB数据库\h2.1.1使用文件保存数据\h2.1.2使用MongoDB保存数据\h2.2从队列Queue到Redis\h2.2.1了解“生产者/消费者”模型\h2.2.2实例1:使用Python实现队列\h2.2.3Python的Queue及其缺陷\h2.2.4实例2:使用Redis替代Queue\h本章小结\h第2篇快速入门\h第3章MongoDB快速入门\h3.1MongoDB和SQL术语对比\h3.2安装MongoDB\h3.2.1在Windows中安装\h3.2.2在Linux中安装\h3.2.3在macOS中安装\h3.3MongoDB的图形化管理软件——Robo3T\h3.3.1安装\h3.3.2认识Robo3T的界面\h3.4MongoDB的基本操作\h3.4.1实例3:创建数据库与集合,写入数据\h3.4.2实例4:查询数据\h3.4.3实例5:修改数据\h3.4.4实例6:删除数据\h3.4.5实例7:数据去重\h3.5使用Python操作MongoDB\h3.5.1连接数据库\h3.5.2MongoDB命令在Python中的对应方法\h3.5.3实例8:插入数据到MongoDB\h3.5.4实例9:从MongoDB中查询数据\h3.5.5实例10:更新/删除MongoDB中的数据\h3.6MongoDB与Python不通用的操作\h本章小结\h第4章实例11:用MongoDB开发员工信息管理系统\h4.1了解实例最终目标\h4.2准备工作\h4.2.1了解文件结构\h4.2.2搭建项目运行环境\h4.2.3启动项目\h4.3项目开发过程\h4.3.1生成初始数据\h4.3.2实现“查询数据”功能\h4.3.3实现“添加数据”功能\h4.3.4实现“更新数据”功能\h4.3.5实现“删除数据”功能\h本章小结\h第5章Redis快速入门\h5.1安装Redis\h5.1.1在Windows中安装Redis\h5.1.2在Linux中安装Redis\h5.1.3在macOS中安装Redis\h5.1.4在线测试环境\h5.2字符串的创建、查询和修改\h5.2.1使用redis-cli实现\h5.2.2使用Python实现\h5.2.3字符串的应用\h5.3列表的创建、查询和修改\h5.3.1使用redis-cli实现\h5.3.2使用Python实现\h5.3.3列表的应用\h5.4集合的创建和修改\h5.4.1使用redis-cli实现\h5.4.2使用Python实现\h5.4.3集合的应用\h本章小结\h第6章实例12:用Redis开发一个聊天室网站\h6.1了解实例的最终目标\h6.2准备工作\h6.2.1了解文件结构\h6.2.2搭建项目运行环境\h6.3项目开发过程\h6.3.1实现登录功能1:创建Redis的连接实例\h6.3.2实现登录功能2:实现“检查昵称是否重复”功能\h6.3.3实现登录功能3:实现“设置和获取Token”功能\h6.3.4实现聊天室页面1:实现“获取聊天消息”功能\h6.3.5实现聊天室页面2:实现“发送新信息”功能\h6.3.6实现聊天室页面3:设定“刷屏检查字符串”\h6.3.7实现聊天室页面4:读取刷屏限制的剩余时间\h本章小结\h第3篇高级应用\h第7章MongoDB的高级语法\h7.1AND和OR操作\h7.1.1实例13:查询同时符合两个条件的人(AND操作)\h7.1.2实例14:查询只符合其中任一条件的人(OR操作)\h7.1.3实例15:用Python实现MongoDB的AND与OR操作\h7.2查询子文档或数组中的数据\h7.2.1认识嵌入式文档\h7.2.2实例16:嵌入式文档的应用\h7.2.3认识数组字段\h7.2.4实例17:数组应用——查询数组包含与不包含“××”的数据\h7.2.5实例18:数组应用——根据数组长度查询数据\h7.2.6实例19:数组应用——根据索引查询数据\h7.2.7Python操作嵌入式文档与数组字段\h7.3MongoDB的聚合查询\h7.3.1聚合的基本语法\h7.3.2实例20:筛选数据\h7.3.3实例21:筛选与修改字段\h7.3.4实例22:分组操作\h7.3.5实例23:拆分数组\h7.3.6实例24:联集合查询\h7.3.7实例25:使用Python执行聚合操作\h本章小结\h第8章MongoDB的优化和安全建议\h8.1提高MongoDB读写性能\h8.1.1实例26:“批量插入”与“逐条插入”数据,比较性能差异\h8.1.2实例27:“插入”与“更新”数据,比较性能差异\h8.1.3实例28:使用“索引”提高查询速度\h8.1.4实例29:引入Redis,以降低MongoDB的读取频率\h8.1.5实例30:增添适当冗余信息,以提高查询速度\h8.2提高MongoDB的安全性\h8.2.1配置权限管理机制\h8.2.2开放外网访问\h本章小结\h第9章Redis的高级数据结构\h9.1哈希表的功能和应用\h9.1.1实例31:使用Redis记录用户在线状态\h9.1.2实例32:使用Python向哈希表中添加数据\h9.1.3实例33:使用Python从哈希表中读取数据\h9.1.4实例34:使用Python判断哈希表中是否存在某字段,并获取字段数量\h9.1.5实例35:在Redis交互环境redis-cli中读/写哈希表\h9.2发布消息/订阅频道\h9.2.1实例36:实现一对多的消息发布\h9.2.2实例37:在Python中发布消息/订阅频道\h9.2.3实例38:在redis-cli中发布消息/订阅频道\h9.3有序集合\h9.3.1实例39:实现排行榜功能\h9.3.2实例40:使用Python读写有序集合\h9.3.3实例41:在Redis交互环境redis-cli中使用有序集合\h9.4Redis的安全管理\h9.4.1实例42:设置密码并开放外网访问\h9.4.2禁用危险命令\h本章小结\h第4篇商业实战\h第10章实例43:搭建一个类似“知乎”的问答网站\h10.1了解实例的最终目标\h10.2准备工作\h10.2.1了解文件结构\h10.2.2搭建实例运行环境\h10.2.3运行项目\h10.3项目开发过程\h10.3.1生成初始数据\h10.3.2实现“查询问题列表”功能\h10.3.3实现“查询回答”功能\h10.3.4实现“提问与回答”功能\h10.3.5实现“点赞”与“点踩”功能\h本章小结\h第11章实例44:使用Redis存储网站会话(接第10章实例)\h11.1了解实例的最终目标\h11.1.1注册账号\h11.1.2登录后回答问题\h11.1.3修改回答\h11.1.4用户回答同一个问题的次数\h11.1.5修改提问\h11.2准备工作\h11.2.1了解文件结构\h11.2.2搭建项目运行环境\h11.2.3运行实例\h11.3开发过程\h11.3.1会话管理的基本原理\h11.3.2保存与读取用户信息\h11.3.3更新问题和回答\h11.3.4检查用户名是否已经注册\h11.3.5在Redis中储存与删除Session\h11.3.6从Redis中获取Session\h11.3.7记录和检查“用户回答是否回答了某个问题”\h本章小结\h第12章实例45:大规模验重和问答排序(接第11章实例)\h12.1了解实例的最终目标\h12.1.1账号验重功能\h12.1.2动态排序功能\h12.1.3注销登录功能\h12.2.4翻页功能\h12.2准备工作\h12.2.1了解文件结构\h12.2.2搭建项目运行环境\h12.2.3运行项目\h12.3开发过程\h12.3.1了解“布隆过滤器”的基本原理\h12.3.2使用“布隆过滤器”对注册用户进行验重\h12.3.3让“问题”与“回答”根据点赞数动态排序\h本章小结\h第13章重构和优化\h13.1划分代码层次\h13.1.1寻找问题\h13.1.2如何重构\h13.2MongoDB的常见陷阱\h13.2.1默认超时时间\h13.2.2硬盘空间的使用\h13.3使用Redis的注意事项\h13.3.1“多Redis实例”与“单Redis实例多数据库”的差异\h13.3.2尽可能为每个Key设置过期时间\h本章小结\h第1篇基础知识随着大数据时代的到来,数据急速增长,导致关系型数据库(SQL)越来越不够用。高性能、可扩展的数据库变得越来越重要起来。在这样的场景下,非关系型数据库(NoSQL)应运而生。这里的“NoSQL”不是“NoSQL(不是SQL)”,而是“NotonlySQL(不仅是SQL)”的简称。第1章主要介绍数据库的产生背景和功能,以及如何学习它们。第2章通过实例介绍MongoDB与Redis存在的必要性。\h第1章进入MongoDB与Redis的世界非关系型数据库在如今的大数据环境下越来越受到重用。相比传统的关系型数据库,非关系型数据库在越来越多的使用场景下极大地提升了生产力。非关系型数据库的佼佼者——文档型数据库MongoDB与键值数据库Redis,是这本书的两个主角。\h1.1非关系型数据库的产生背景与分类\h1.1.1关系型数据库遇到的问题2008年左右,网站、论坛、社交网络开始高速发展,关系型数据库的地位受到了很大的挑战。关系型数据库的以下问题逐渐凸显:●难以应付每秒上万次的高并发数据写入。●查询上亿量级数据的速度极其缓慢。●分库、分表形成的子库到达一定规模后难以进一步扩展。●分库、分表的规则可能会因为需求变更而发生变更。●修改表结构困难。在很多互联网应用场景下,对数据联表的查询需求不是那么强烈,也并不需要在数据写入后立刻读取,但对数据的读取和并发写入速度有非常高的要求。在这样的情况下,非关系型数据库得到高速的发展。2009年,分布式文档型数据库MongoDB引发了一场去SQL的浪潮。\h1.1.2非关系型数据库的分类及特点非关系型数据库主要分为以下几类。1.键值数据库主要代表是Redis、Flare。这类数据库具有极高的读写性能,用于处理大量数据的高访问负载比较合适。2.文档型数据库主要代表是MongoDB、CouchDB。这类数据库满足了海量数据的存储和访问需求,同时对字段要求不严格,可以随意地增加、删除、修改字段,且不需要预先定义表结构,所以适用于各种网络应用。3.列存储数据库主要代表是Cassandra、Hbase。这类数据库查找速度快,可扩展性强,适合用作分布式文件存储系统。4.图数据库主要代表是InfoGrid、Neo4J。这类数据库利用“图结构”的相关算法,适合用于构建社交网络和推荐系统的关系图谱。\h1.2MongoDB与Redis可以做什么\h1.2.1MongoDB适合做什么MongoDB适合储存大量关联性不强的数据。MongoDB中的数据以“库”—“集合”—“文档”—“字段”结构进行储存。这种结构咋看和传统关系型数据库的“库”—“表”—“行”—“列”结构非常像。但是,MongoDB不需要预先定义表结构,数据的字段可以任意变动,并发写入速度也远远超过传统关系型数据库。\h1.2.2Redis适合做什么Redis有多种数据结构,适合多种不同的应用场景。1.使用Redis做缓存Redis的字符串、哈希表两种数据结构适合用来储存大量的键值对信息,从而实现高速缓存。2.使用Redis做队列Redis有多几种数据结构适于做队列:●使用“列表”数据结构,可以实现普通级和优先级队列的功能。●使用“有序集合”数据结构,可以实现优先级队列;●使用“哈希表”数据结构,可以实现延时队列。3.使用Redis去重Redis有多几种数据结构适于做去重:●利用“集合”数据结构,可以实现小批量数据的去重;●利用“字符串”数据结构的位操作,可以实现布隆过滤器,从而实现超大规模的数据去重;●利用Redis自带的HyperLogLog数据结构,可以实现超大规模数据的去重和计数。4.使用Redis实现积分板Redis的“有序集合”功能可以实现积分板功能,还能实现自动排序、排名功能。5.使用Redis实现“发布/订阅”功能Redis自带的“发布/订阅”模式可以实现多对多的“发布/订阅”功能。\h1.3如何学习MongoDB和Redis本节谈一谈如何学习MongoDB和Redis。\h1.3.1项目驱动,先用再学“先看理论,再实做”的学习方法,最容易让人昏昏欲睡。如果先看理论,由于不知道具体的应用场景,学起来就难以抓住重点。如果先给出一个项目,然后根据完成这个项目需要哪些知识点去针对性地学习,就能很容易找到重点,活学活用。在完成项目的同时,也就学好了知识点。\h1.3.2系统梳理,由点到面项目驱动也并非完美无缺。基于项目来学习,容易导致的问题是知识点零碎而不成系统。因此,在完成一个项目后,应对项目涉及的知识点进行系统性的学习。例如,聊天网站需要使用Redis的列表,那么在完成了聊天网站后,就应该详细了解Redis列表的其他命令。又比如,在问答系统中需要使用MongoDB的联集合查询,那么在完成项目以后,应根据联集合查询用到的“aggregate”命令去了解MongoDB的聚合操作。在了解了聚合操作以后,再思考聚合操作的其他应用场景。\h1.3.3分清主次,不要在无谓的操作中浪费时间搭建环境是很多人学习的“拦路虎”。由于电脑环境的差异,可能有一些读者无论如何都无法在自己的电脑上把数据库运行起来。此时,千万不要恋战。赶紧重装系统、更换电脑、求助他人,或者使用别人已经搭建好的环境。首先学会使用数据库,等基于MongoDB或者Redis的程序能够完美运行了,再来慢慢考虑环境搭建的问题。至于MongoDB的分库、分表、集群,Redis的集群、哨兵等内容,除非你想成为数据库工程师,否则,可以等到熟练使用MongoDB和Redis后,再找大块空闲时间来了解。\h1.3.4在不同领域中尝试MongoDB与Redis在多个领域中都有重要的应用。例如:●在爬虫开发中,MongoDB主要用来写数据,Redis主要用来缓存网址。●在数据分析中,MongoDB的聚合操作用得较多。●在后端开发中,主要用到MongoDB的增、删、改、查功能,Redis主要用来做缓存。●在游戏开发中,Redis可以用来做排名功能。如果希望更好地掌握MongoDB和Redis,那么可以在多个领域都寻找项目来进行尝试,从而更全面地了解各个功能和应用场景。\h1.4如何使用本书\h1.4.1本书的产品定位本书旨在教会读者在不同应用场景下正确使用MongoDB和Redis的不同功能,不会介绍数据库的底层原理,也不会介绍如何优化数据,更不会介绍如何搭建数据库集群。如果以开车作为比喻,学习开车不需要知道汽车的所有组成元件,也不需要知道汽车为什么踩下油门就可以跑,更不需要知道汽车是如何组装的。诚然,技艺高超的赛车手确实需要知道汽车的一些底层原理,但前提是要会开车,再来考虑如何开得好。几乎找不到不用数据库的互联网公司。似乎在任何场景下都要用到数据库,但数据库绝不仅仅是保存数据那样简单,数据库的不同功能有不同的适用场景。如何在适当的场景下选择最适当的功能,正是本书需要教给读者的。本书虽然也有数据库搭建的内容,但希望读者耗费在搭建数据库上的时间不要超过半小时。如果搭建遇到了问题,请立即咨询朋友、老师,或者使用学校或公司已经搭建好的数据库来进行学习。绝对不应该在搭建数据库上耗费太多时间。\h1.4.2本书适用的读者群体本书不适合希望成为数据库工程师的读者。本书强调如何将MongoDB和Redis应到实际项目中,因此本书会使用编程语言Python来操作数据库,这就要求读者必须有Python基础。如果读者对Python不熟悉,可以参考李金洪老师编著的《Python带我起飞——入门、进阶、商业实战》(电子工业出版社出版)一书。本书适合有Python基础的后端工程师、爬虫工程师、数据工程师、数据科学家、数据挖掘工程师、游戏开发工程师等群体阅读学习。1.后端工程师本书中涉及的网站是使用Flask开发的,后端工程师在学习了MongoDB与Redis知识后,可以参考本书的网站源代码举一反三,使用MongoDB与Redis来优化自己网站的后台代码,从而提高速度或者简化逻辑。2.爬虫工程师MongoDB特别适合写入大批量、高并发、不规则的数据,Redis特别适合作为分布式爬虫的连接枢纽。爬虫工程师在学习了MongoDB与Redis后,可以大大提高爬虫的开发效率和运行效率。3.数据工程师、数据科学家、数据挖掘工程师这个群体的读者,可以使用MongoDB来保存数据,并使用MongoDB的聚合查询功能来对数据进行一些基本的查询操作和清洗操作,从而输出格式较为规范的数据,以便进行进一步分析。4.游戏工程师Redis特别适合用来存放一些中间数据。另外,Redis自带的一些数据结构天然适合用来实现游戏中的一些功能,例如积分板、去重、高速缓存等。\h1.4.3如何利用本书实例进行练习本书有大量的实例供读者练习。实例分为小型、中型和大型三种。1.小型实例对于小型实例,读者可以根据书中的描述直接在MongoDB图形化管理软件、Redis交换环境或Python交互环境中进行操作。这种实例包括(但不限于)MongoDB与Redis的基本语法、基本操作。2.中型实例对于中型实例,由于需要完成较多的Python代码,因此需要在Python的集成开发环境(PyCharm等)中完成。本书会为中型实例提供原始数据的生成程序。只要运行生成程序,就会在MongoDB或者Redis中写入练习专用的原始数据。然后,读者就可以操作这些原始数据进行学习。3.大型实例对于大型的实例,本书会附送相应的代码(一个网站的所有源文件)。读者根据书中的使用说明,可以在自己电脑上将网站的运行环境搭建起来。在项目环境能正常运行后,读者只需要完成项目中的MongoDB或Redis模块,就可以使整个网站按照预期的效果正常工作。\h第2章数据存储方式的演进对于小批量的数据,可以使用“记事本”程序将其保存到硬盘里。但如果数据量越来越多,类型越来复杂,使用“记事本”程序保存就难以查询和修改。数据库的出现,就是为了便于从大量数据中查询和修改内容。在程序开发中,常常涉及一些中间数据,这些中间数据会被频繁读/写。如果仅仅把中间数据放在内存中,则不便于从外界观察程序运行到了什么状态。而把中间数据保存到基于硬盘的传统数据库,又会影响程序性能。内存数据库的出现,就解决了这个问题。\h2.1从文件到MongoDB数据库\h2.1.1使用文件保存数据对于少量数据,可以使用“记事本”程序来保存。但如果需要对数据进行计算,那么记事本显然就不能胜任了。此时可以考虑Excel。还可以使用Excel的数据透视表来统计数据,如图2-1所示。图2-1使用数据透视表统计数据Excel的一张表可以存放100万行左右的数据,那如果每天的数据都超过100万行呢?此时就不得不使用数据库来保存了。\h2.1.2使用MongoDB保存数据使用数据库,可以保存大量的数据,这是数据库最基本的功能。另外,数据库还能够对数据进行逻辑运算、数学运算、搜索、批量修改或删除。相比于传统的关系型数据库,MongoDB对于每一次插入的字段格式没有要求,字段可以随意变动,字段类型也可以随意变动,如图2-2所示。图2-2MongoDB对字段格式与内容不做限制MongoDB可以并发插入上万条文档,这是传统关系型数据库所不能望其项背的。\h2.2从队列Queue到Redis在某些场景下,使用队列可以提高程序的运行性能,但如何选择合适的队列也需要仔细考虑。\h2.2.1了解“生产者/消费者”模型在餐馆吃饭时,厨师做完一道菜后就会把菜从传菜窗口递出去,然后继续做下一道菜。厨师不需要关心顾客是不是已经把菜吃完了。如果厨师做菜的速度大于顾客拿菜的速度,那么就会有越来越多的菜堆在传菜窗口。如果顾客拿菜的速度大于厨师做菜的速度,那么传菜窗口始终是空的,来一道菜就会立刻被拿走。在程序开发中,这就是一个典型的“生产者/消费者”模型:厨师是生产者,负责生产;顾客是消费者,负责消费。厨师和顾客各做各的事情。传菜窗口就是队列,它把生产者与消费者联系在一起。\h2.2.2实例1:使用Python实现队列实例描述使用Python自带的queue对象来实现队列:(1)使用Python实现一个简单的“生产者/消费者”模型。(2)使用Python的queue对象做信息队列。在Python使用多线程实现生产者与消费者的程序中,可以使用Python自带的queue对象来作为生产者与消费者沟通的队列。在代码2-1中,生产者负责产生两个数字,消费者负责把两个数字相加。代码2-1简单的“生产者/消费者”队列生产者固定每两秒生产一组数,然后把这一组数放进队列里。消费者每次从队列里面取一组数,将它们相加然后打印出来。消费者取一次数的时间是1~10秒中的一个随机时间。由于生产过程和消费过程的时间不对等,所以,可能会出现生产者生产的数据堆积在队列中的情况,如图2-3所示。图2-3生产的数据堆积\h2.2.3Python的Queue及其缺陷代码2-1的运行结果存在两种情况:●如果消费者每次暂停的时间都小于2秒,那么队列始终是空的,来一组数立刻就被消费。●如果消费者每次暂停的时间都大于2秒,那么队列里的数就会越来越多。但是,由于消费者暂停时间是随机的,我们不能提前知道它每次会暂停多久。假定程序运行了1小时,请问队列里有多少数据?如果使用Python自带的队列,就会出现以上的疑问。因为开发者不能直接看到队列的长度。如果开发者一开始就考虑到“需要随时观察队列长度”这个需求,那么可以通过对代码做一些修改来实现。但如果一开始没有打算观察队列长度,仅仅是临时起意,那该怎么办?如果不仅想看队列长度,还想看里面每一组数都是什么,又该如何操作?假设队列里已经堆积了一百组数,现在想增加消费者,该怎么增加?如再运行一个Python程序,那能去读第一个正在运行中的Python程序中的队列吗?Python把队列中的数据存放在内存中。如果电脑突然断电,那队列里的数是不是全都丢失了?为了防止丢数据,是否需要把数据持久化到硬盘?那持久化的代码怎么写,代码量有多少,考不考虑并发和读写冲突?为了解决上述问题,在代码2-1的基础上,代码量要翻倍翻倍再翻倍。\h2.2.4实例2:使用Redis替代Queue实例描述使用Redis作为队列,从而解决实例1中遇到的各种问题。(1)拆分“生产者/消费者”队列。(2)使用Redis的列表作为队列。如果使用Redis代替Python自带的队列,解决2.2.3小节中提出的所有问题,则代码量的变化甚至可以忽略不计。把生产者代码和消费者代码分别写到两个文件中。1.生产者代码代码2-2使用Redis后的生产者代码2.消费者代码代码2-3使用Redis后的消费者代码提示:读者不必太纠结本章中的代码,本书后面的章会对各个知识点做详细的解读。现在,生产者和消费者可以放在不同的机器上运行,想运行多少个消费者就运行多少个消费者,想什么时候增加消费者都没有问题。如果想观察当前队列里有多少数据,或者想看看具体有哪些数据在队列里,则执行一条命令:“llen队列名称”即可。图2-4中,当前队列中已经堆积了35组数据。图2-4观察当前队列中有多少数据Redis自己会对数据做持久化处理,所以,即使电脑断电也不必担心。甚至,开发者还可以通过修改队列中的数据,从而影响消费者的输出结果。\h本章小结本章简单介绍了MongoDB与Redis的两个应用实例,从而引出了MongoDB和Redis在实际应用中的优势。其中,MongoDB可以用来保存大量数据,且字段和格式均可以随意改变;Redis扩展了队列的应用范围,使得开发者可以方便地观察程序的运行状况,甚至在运行中改变程序的行为。\h第2篇快速入门非关系型数据库有着强大的扩展能力,不需要事先定义好数据库中的字段,数据插入速度远超关系型数据库。第3章会介绍MongoDB的安装和基本语法。另外,介绍在图形化管理工具Robo3T中操作MongoDB,以及使用Python操作MongoDB的方法。第4章会以实例的形式巩固MongoDB的基础知识。第5章会介绍Redis的安装和基本语法,以及使用Python操作Redis的方法。第6章会以实例的形式巩固Redis的基础知识。\h第3章MongoDB快速入门MongoDB的语法与Python非常相似。在很多情况下,操作MongoDB的代码都可以直接用到Python中。所以,结合Python来学习MongoDB可以起到事半功倍的效果。\h3.1MongoDB和SQL术语对比SQL与MongoDB术语对比见表3-1。表3-1SQL与MongoDB术语对比\h3.2安装MongoDB\h3.2.1在Windows中安装(1)访问MongoDB官网的下载页面(/download-center?jmp=nav#community),单击“DOWNLOAD(msi)”按钮,如图3-1所示。图3-1从MongoDB官网下载Windows版MongoDB(2)双击下载的文件(如无特殊说明,只需要一直单击“Next”按钮即可)。在安装过程中将会看到如图3-2所示的界面选择安装方式,这里单击“Custom”按钮。(3)修改文件的安装路径到C:\ProgramFiles\MongoDB,单击“Next”按钮进行安装,如图3-3所示。图3-2单击“Custom”按钮图3-3修改文件安装路径(4)安装完成以后,进入C:\ProgramFiles\MongoDB\bin,可以看到如图3-4所示的内容。图3-4安装完成后的文件内容(5)将这里的所有文件全部复制并粘贴到C:\MongoDB\下,以方便管理。手动创建存放数据文件的文件夹“C:\MongoDB\Data”,以及存放日志文件的文件夹“C:\MongoDB\Log”。最后使用记事本创建配置文件,配置文件的内容见代码3-1。代码3-1MongoDB配置文件(6)将配置文件保存在“C:\MongoDB\mongod.conf”。此时,C:\MongoDB\下的内容如图3-5所示。在D:\MongoDB的安装文件夹中的空白位置,按住Shift键并单击鼠标右键,在弹出的菜单中选择“在此处打开命令窗口”命令,然后输入以下代码启动MongoDB:mongod.exe--configmongod.conf图3-5创建文件夹和配置文件以后的MongoDB文件夹运行MongoDB以后,由于日志文件(Log)都已经被写到文件C:\MongoDB\Log\mongo.log中了。因此控制台中就什么都没有显示,如图3-6所示。这是正常现象。图3-6MongoDB在Windows中运行不会有内容打印出来\h3.2.2在Linux中安装由于Linux有众多的发行版,不同发行版本有不同的包管理工具,所以在各个发行版本中安装MongoDB的命令可能会有一些差异。本书以Ubuntu18.04与Ubuntu16.04为例,来说明如何安装MongoDB。1.在Ubuntu18.04中安装MongoDB(1)安装。在Ubuntu18.04中安装MongoDB非常简单,只需要执行以下两行命令:sudoaptupdatesudoaptinstall-ymongodb(2)确认MongoDB是否正常。Ubuntu18.04版的MongoDB自带了一个配置文件(/etc/mongod.conf)。MongoDB被安装后,系统会以这个配置文件为基准,自动以服务的方式启动它。所以,MongoDB安装完成后就自启动了,不需要运行额外的命令来启动。但是,可以通过以下命令来确认MongoDB是否正常运行:systemctlstatusmongodb图3-7中方框框住的“active(running)”表示MongoDB正在运行。图3-7观察MongoDB是否正常运行提示:如果不是以root账户登录Ubuntu,则执行systemctl命令时需要加上“sudo”,如下:sudosystemctlstatusmongodb2.在Ubuntu16.04中安装MongoDB首先添加MongoDB的源,见代码3-2。代码3-2在Ubuntu16.04中安装MongoDB其中主要代码说明如下。●第1行代码:导入包管理程序的公钥。●第3行代码:创建MongoDB需要用到的列表文件。●第5行代码:安装MongoDB。提示:Ubuntu16.04版的MongoDB也自带配置文件,地址为:/etc/mongod.conf。3.启动MongoDB安装完成后,MongoDB服务并不会自动启动,需要使用systemctl命令来启动,具体命令如下:sudosystemctlstartmongod#启动MongoDBsudosystemctlenablemongod#把MongoDB设置为开机启动提示:在Ubuntu18.04中执行systemctl命令时,MongoDB对应的名字为“mongodb”。在Ubuntu16.04中,MongoDB对应的名字为“mongod”,请注意区分。\h3.2.3在macOS中安装1.使用Homebrew安装并启动MongoDBHomebrew是macOS系统中非常优秀的第三方包管理工具。如果读者已经安装过Homebrew,则再安装MongoDB就变得极其简单。执行以下命令即可完成安装。brewupdatebrewinstallmongodb使用Homebrew安装的MongoDB会自动生成配置文件。在安装完成以后,直接使用以下命令启动MongoDB:mongod--config/usr/local/etc/mongod.conf2.使用普通方式安装在终端中输入以下命令来下载、解压MongoDB到~/chapter_3/mongo/mongodb文件夹中,见代码3-3。代码3-3手动安装MongoDB其中,主要代码说明如下。●第1、2行代码:创建文件夹。●第3行代码:进入刚刚创建的文件夹。●第4行代码:下载MongoDB的压缩包。tgz是一种压缩格式。●第5行代码:把压缩包解压到当前文件夹。●第7行代码:把解压后的MongoDB文件复制到刚刚新创建的mongodb文件夹中。运行效果如图3-8所示。图3-8手动安装MongoDB安装完成后,在~/chapter_3/mongo/mongodb/bin文件夹下可以看到如图3-9所示的各个文件。图3-9MongoDB文件夹与Windows一样,在macOS下使用这种方式,MongoDB不会自动创建配置文件,因此需要进一步配置。(1)在~/chapter_3/mongo/mongodb/bin文件夹下,手动创建两个文件夹——log和data。提示:可以直接在终端里使用“mkdir”命令创建。也可以用访达(Finder)打开~/chapter_3/mongo/mongodb/bin文件夹,如图3-10所示,然后在图形界面下创建log和data文件夹。图3-10在图形界面中进入~/chapter_3/mongo/mongodb/bin文件夹(2)使用任何一个适合写代码的文本编辑器(如Vim/VisualStudioCode/Sublime/Atom等),编写内容见代码3-4中的内容,然后将编写的代码保存到~/chapter_3/mongo/mongodb/bin/mongodb.conf中。代码3-4MongoDB的配置文件(3)配置后的文件结构如图3-11所示。图3-11添加配置文件后的文件结构接下来,启动MongoDB的方法和通过Homebrew安装MongoDB后的启动方式差不多了。在终端中,先进入存放MongoDB的文件夹,再启动MongoDB:cd~/chapter_3/mongo/mongodb/binmongod--configmongodb.conf如同另外两个系统一样,运行以后不会有内容打印出来,但是MongoDB已经正常启动了,如图3-12所示。图3-12运行MongoDB\h3.3MongoDB的图形化管理软件——Robo3TMongoDB虽然自带了一个终端环境下的客户端,但是操作起来比较繁琐,数据显示也不够直观。因此需要使用一个图形界面管理软件来提高MongoDB数据的可读性。\h3.3.1安装Robo3T是一个跨平台的MongoDB管理工具,采用图形界面查询或者修改MongoDB。Robo3T的下载地址为:/download。提示:在下载页面中可以看到另一个叫作Studio3T的软件,它是一个功能更加强大的MongoDB图形化管理软件。但它是一个商业软件,需要收费。而Robo3T是开源软件并且免费,它的功能足够应付本书的所有应用场景,因此本书选择使用Robo3T。1.安装Robo3TRobo3T的安装没有任何需要特别说明的地方,和安装普通软件一样简单。●如果系统是Windows与Linux,则安装完成后就可以使用了。●如果系统是macOS,则安装完成后第一次运行时可能会看到如图3-13所示的安全提示。图3-13MacOS的安全提示解决这个问题的方法如下:(1)打开macOS的“系统设置”,单击“Security&Privacy”(中文名为“安全和隐私”)图标,如图3-14所示。图3-14单击“安全和隐私”图标(2)在“安全和隐私”设置界面,单击“OpenAnyway”(中文名为“仍然运行”)按钮,如图3-15所示。图3-15单击“仍然运行”按钮(3)在弹出的对话框中单击“Open”(中文名为“运行”)按钮即可打开Robo3T,如图3-16所示。图3-16单击“运行”按钮打开Robo3T(4)第一次成功启动Robot3T时,会看到一个用户协议,如图3-17所示。勾选“Iagree”并单击“Next”按钮。(5)在下一个界面中添加名字公司之类的信息,可以直接忽略,单击“Finish”按钮跳过即可。图3-17用户协议2.用Robo3T连接MongoDB(1)打开Robo3T,看到如图3-18所示对话框,单击左上角“Create”链接。图3-18初次运行RoboMongo的界面(2)弹出如图3-19所示对话框。如果MongoDB就在本地电脑中运行,则只需在“Name”栏中填写一个名字,其他地方不需要修改,然后直接单击“Save”按钮。图3-19在“Name”这一栏填写名字即可(3)回到如图3-18所示界面,单击“Connect”按钮就可以连接MongoDB了。\h3.3.2认识Robo3T的界面Robo3T的主界面如图3-20所示。重点关注A、B、C三个区域。图3-20Robo3T主界面●数据库列表区(后简称A区域),用于选择数据库和集合。●数据展示区(后简称B区域),用于显示数据。●命令执行区(后简称C区域),用于编写MongoDB代码。在A区域中,单击数据库图标左边的箭头,展开数据库;单击“Collections”左边的箭头,展开集合。双击集合的名字,则B区域和C区域发生相应的变化。本书主要和A、B、C这三个区域打交道。每一个区域的具体功能会在使用时详细介绍。\h3.4MongoDB的基本操作增、查、改、删是所有数据库必备的功能。本节将介绍如何使用MongoDB来实现这四个功能。\h3.4.1实例3:创建数据库与集合,写入数据实例描述在Robo3T中进行如下操作。(1)创建一个名为“chapter_3”的数据库,以及其中的多个集合。(2)往集合里逐条插入数据。(3)往集合里批量插入数据。使用Robo3T打开刚刚安装完成的MongoDB,可以看到A区域是空的,还没有数据库,如图3-21所示。图3-21MongoDB是空的1.创建数据库与集合(1)鼠标右击“小电脑”图标,在弹出的菜单中选择“CreateDatabase”命令,如图3-22所示。(2)在弹出的对话框中输入数据库的名字,单击“Create”按钮完成数据库的创建,如图3-23所示。图3-22选择“CreateDatabase”命令图3-23输入数据库名字并单击Create按钮(3)新创建的数据库会出现在A区域中。单击数据库左边的小箭头将其展开,然后右击“Collections(0)”文件夹,在弹出的菜单中选择“CreateCollection...”命令,如图3-24所示。(4)在弹出的对话框中输入集合的名字,然后单击“Create”按钮(如图3-25所示)创建一个集合。图3-24选择“CreateCollection...”命令图3-25输入集合名字并单击“Create”按钮(5)创建完集合后,原来的“Collections(0)”变成了“Collections(1)”。由此可以推测:括号里面的数字表示这个数据库里面有多少个集合。单击“Collections(1)”左侧的小箭头将其展开,可以看到集合“example_data_1”已经创建好了。双击集合名字,可以看到当前集合里什么都没有,如图3-26所示。图3-26空集合什么都没有2.插入单条数据插入单条数据的命令为“insertOne()”。Robo3T自带插入数据的功能。但是本书不准备介绍。本书会直接介绍如何在C区域执行MongoDB命令插入数据。(1)创建一条JSON字符串。例如:{"name":"张小二","age":17,"address":"浙江"}(2)对C区域的内容做一些修改。原来是:db.getCollection('example_data_1').find({})修改为:db.getCollection('example_data_1').insertOne({"name":"张小二","age":17,"address":"浙江"})(3)使用Windows与Linux的读者,可以按键盘上的“Ctrl+R”组合键;使用macOS的读者按“Command+R”组合键。运行后的界面如图3-27所示。可以看到,一条数据已经插入到了MongoDB中。图3-27插入数据提示:还可以通过单击Robo3T上面的绿色三角形来运行命令。(4)在A区域双击集合“example_data_1”,从新打开的选项卡中可以看到数据已经成功插入,如图3-28所示。图3-28数据已经成功插入被插入的数据就是JSON字符串:{"name":"张小二","age":17,"address":"浙江"}提示:JSON字符串必须使用双引号,不过这个规定在MongoDB中并非强制性的,用单引号也没有问题。例如,在C区域执行以下命令:db.getCollection('example_data_1').insertOne({'name':’王小六’,'age':25,'work':’厨师’})插入以后,集合“example_data_1”中的数据如图3-29所示。图3-29插入第二条数据如果将Python的字典直接复制到MongoDB的insertOne命令中,则绝大部分情况下这些字典都可以直接使用,只有极少数情况下需要做一些修改。3.4节将会讲到这些少数情况。提示:MongoDB还允许Key不带引号,直接写成{name:’王小六’,age:25,work:’厨师’}。但这种写法存在一些局限性,并且会导致MongoDB的命令不方便平滑移植到Python中。因此,建议读者一律使用带单引号的写法或者带双引号的写法。3.调整插入的字段(1)任意修改、添加、删除字段。在图3-29中,第1条数据没有“work”这个字段,第2条数据没有“address”这个字段。这就说明:在MongoDB里,插入数据的字段是可以任意修改、添加、删除的。例如,再插入一条新的数据:这一次所有的字段都和前两条数据不一样,但MongoDB仍然可以轻松处理——遇到新来的字段,加上去就是了,没什么大不了的,如图3-30所示。图3-30遇到新的字段,MongoDB会自动添加上去(2)插入同一个字段,但格式却不同。即使是同一个字段,其数据格式也可以不一样。例如,再插入一条数据:添加后的数据如图3-31所示。图3-31同一个字段的数据格式也可以不一样提示:“能不能做”是一回事,“应不应该做”是另一回事。虽然MongoDB能够处理同一个字段的不同数据类型,也可以随意增减字段,但并不意味着应该这样做。在设计数据库时,应尽量保证同一个字段使用同一种类型的数据,并提前考虑好应该有哪些字段。3.批量插入数据批量插入数据的命令是“insertMany”。现在把一个包含很多个字典的列表传给“insertMany”。列表为:对应的MongoDB批量插入语句为:运行后返回的数据如图3-32所示。图3-32批量插入数据提示:可以通过换行和缩进让代码更美观、易读。换行和缩进不影响代码功能。运行以后的集合数据如图3-33所示。图3-33插入数据以后的集合无论是插入一条数据还是插入多条数据,每一条数据被插入MongoDB后都会被自动添加一个字段“_id”。“_id”读作“ObjectId”,它是由时间、机器码、进程pid和自增计数器构成的。“_id”始终递增,但绝不重复。●同一时间,不同机器上面的“_id”不同。●同一机器,不同时间的“_id”也不同。●同一机器同一时间批量插入的数据,“_id”依然不同。提示:_id的前8位字符转换为十进制就是时间戳。例如“5b2f2e24e0f42944105c81d2”,前8位字符“5b2f2e24”转换为十进制就是时间戳“1529818660”,对应的北京时间是“2018-06-2413:37:40”。\h3.4.2实例4:查询数据实例描述对数据集example_data_1进行如下查询:(1)查询所有数据。(2)查询特定数据:查询“age”为25岁的员工。(3)查询特定数据:查询“age”不小于25的所有记录。(4)限定返回的数据字段类型。在Robo3T中双击集合名字,实际上是自动执行了以下这条查询语句:db.getCollection('example_data_1').find({})下面先来了解一下查询结果的三种显示模式。1.三种显示模式Robo3T显示出来的查询结果如图3-34所示。注意右上角方框框住的三个图标。图3-34查询并返回所有数据Robo3T对于返回的数据有三种组织方式,从左到右分别是:“树形模式(TreeMode)”“表格模式(TableMode)和“文本模式(TextMode)”。提示:这三种显示模式是Robo3T提供的,不是MongoDB的功能。(1)树形模式。优点是:可以直观地看到每一条记录有哪些字段,每一个字段是什么内容和什么格式,如图3-35所示。弊端是:每次都要单击每一条记录左边的三角形,非常麻烦。图3-35树形模式(2)表格模式(本书用得最多的显示模式)。优点是:便于对数据整体有一个全面的认识。在表格模式里可以看到很多行数据,便于观察数据的全貌、对比不同记录的相同字段,如图3-36所示。弊端是:不能显示嵌入式文档的内容。图3-36表格模式(3)文本模式(如图3-37所示)。优点是:便于对数据进行复制/粘贴,便于对特殊格式数据进行深入认识。弊端是:一屏只能显示少量内容,要反复拖动滚动条才能完整看完数据;不方便不同记录之间进行对比。图3-37文本模式2.查询固定值数据(1)查询所有数据。如要查询所有数据值,则直接使用下面两种写法的任意一种即可:db.getCollection('example_data_1').find()或db.getCollection('example_data_1').find({})(2)查询特定数据。如要查询某个或者某些具体字段,则可以使用下面的语法来查询。如果有多个字段,则这些字段需要同时满足。例如,对于数据集example_data_1,要查询所有“age”字段为25的记录。则查询语句可以写为:db.getCollection('example_data_1').find({'age':25})查询结果如图3-38所示。图3-38查询所有“age”为25的记录由于“age”为25的记录有两条,于是需要进一步缩小查询范围——再增加一个限制条件:运行结果如图3-39所示。总结一下,“find”的参数相当于一个字典。字典的Key就是字段名,字典的值就是要查询的值。如果字典有多个Key,则这些字段需同时满足。图3-39多个查询条件同时满足3.查询范围值数据如要查询的字段值能够比较大小,则查询时可以限定值的范围。例如,对数据集example_data_1,要查询所有“age”字段不小于25的记录,则需要使用大于等于操作符“$gte”。查询语句如下:db.getCollection('example_data_1').find({'age':{'$gte':25}})运行效果如图3-40所示。图3-40查询范围数据查询某个范围的数据会用到的操作符见表3-2。表3-2范围操作符及其意义使用范围操作符的查询语句格式如下:可以看出,在使用范围操作符后,原本填写被查询值的地方现在又变成了一个字典。这个字典的Key是各个范围操作符,而它们的值是各个范围的边界值。【举例1】查询所有“age”大于21并小于等于24的数据。查询语句如下:db.getCollection('example_data_1').find({'age':{'$lt':25,'$gt':21}})运行效果如图3-41所示。图3-41“age”大于21并且小于等于24的所有记录【举例2】查询所有“age”大于21并小于等于24的数据,且“name”不为“夏侯小七”的记录,见代码3-5。代码3-5查询“age”大于21并小于等于24,且“name”不为“夏侯小七”的数据运行效果如图3-42所示。图3-42查询的结果4.限定返回哪些字段“find”命令可以接收两个参数:第1个参数用于过滤不同的记录,第2个参数用于修改返回的字段。如果省略第2个参数,则MongoDB会返回所有的字段。如要限定字段,则查询语句的格式如下:其中,用于限定字段的字典的Key为各个字段名。其值只有两个——0或1。●如果值为0,则表示在全部字段中剔除值为0的这些字段并返回。●如果值为1,则表示只返回值为1的这些字段。例如,查询数据集example_data_1,但不返回“address”和“age”字段。查询语句如下:db.getCollection('example_data_1').find({},{'address':0,'age':0})运行结果为如图3-43所示。图3-43不返回“address”字段和“age”字段再例如,要求只返回name字段和age字段,则查询语句如下:db.getCollection('example_data_1').find({},{'name':1,'age':1})运行效果如图3-44所示。图3-44只返回“name”和“age”字段读者可能已经发现,不论是选择“只返回某些字段”还是“不返回某些字段”,结果里始终有“_id”。这是因为,“_id”比较特殊,它是默认要返回的,除非明确说明不需要它。即,如果不想要“_id”,则必须在限定字段的字典中把“_id”字段的值设为0,如图3-45所示。图3-45明确申明不需要“_id”如果不考虑“_id”,则限定字段的字典里面的值只可能全都是0或全都是1,不可能1和0混用,一旦混用则MongoDB就会报错。这从逻辑上很好理解:(1)如果只要A、B、C,则没有提到的自然都是不需要的。(2)如果除A、B、C外其他的全都要,则没有提到的自然全都是需要的。提示:只有“_id”很特别,不论其他字段的值是0还是1,如果不需要返回“_id”,则需要把它的值设为0。5.修饰返回结果(1)满足要求的数据有多少条——count()命令。如果想知道满足要求的数据有多少条,则可以使用“count()”命令。例如,要查询所有“age”字段大于21的记录有多少条,则查询语句如下:db.getCollection('example_data_1').find({'age':{'$gt':21}}).count()运行结果如图3-46所示。返回数字“6”表示有6条记录满足要求。图3-46查询结果条数(2)限定返回结果——“limit()”命令。如果查询的结果非常多,则可能需要限定返回结果。此时就需要使用“limit()”命令。它的用法如下:●如果限制返回的条数为一个数字,则表示最多返回这么多条记录。如果超过限定条数,则只返回限定的条数。●如果不足限定的条数,则有多少就返回多少。例如,对于数据集example_data_1,限制只返回4条数据。具体命令如下:db.getCollection('example_data_1').find().limit(4)运行效果如图3-47所示。图3-47最多返回4条记录(3)对查询结果进行排序——“sort()”命令。有时也需要对查询结果进行排序,此时需要使用“sort()”命令。使用方法如下:其中,字段的值为-1表示倒序,为1表示正序。例如,对所有“age”大于21的数据,按“age”进行倒序排列。查询语句如下:db.getCollection('example_data_1').find({'age':{'$gt':21}}).sort({'age':-1})运行结果如图3-48所示。图3-48将查询结果倒序排列\h3.4.3实例5:修改数据实例描述数据集example_data_1,“name”为“王小六”的这个记录是没有“address”字段的。现在需要为它增加这个字段,同时把“work”从“厨师”改为“工程师”。(1)更新集合中的单条数据。(2)批量更新同一个集合中的多条数据。修改操作也就是更新(Update)操作,对应的MongoDB命令为“updateOne()”和“updateMany()”。这两个命令只有以下区别,它们的参数完全一致。●updateOne:只更新第1条满足要求的数据。●updateMany:更新所有满足要求的数据。下面以“updateMany”为例来介绍更新记录的操作。1.更新操作的语法更新操作的语法如下:updateMany的第1个参数和“find”的第1个参数完全一样,也是一个字典,用来寻找所有需要被更新的记录。第2个参数是一个字典,它的Key为“$set”,它的值为另一个字典。这个字典里面是需要被修改的字段名和新的值。2.举例修改“name”为“王小六”的文档,添加“address”字段,并把“work”字段从“厨师”改为“工程师”。更新语句见代码3-6。代码3-6修改name为“王小六”的文档运行效果如图3-49所示。图3-49更新字段信息再次查看数据集,发现“王小六”的信息已经发生了变化,如图3-50所示。图3-50数据发生了变化\h3.4.4实例6:删除数据实例描述例如,要从数据集example_data_1中删除字段“hello”值为“world”的这一条记录。(1)从集合中删除单条数据。(2)从集合中批量删除多条数据。只要会查询数据,就会删除数据。为了防止误删数据,一般的做法是先查询要删除的数据,然后再将查出的数据删除。(1)查询字段“hello”中值为“world”的这一条记录。具体如下:db.getCollection('example_data_1').find({'hello':'world'})运行效果如图3-51所示。图3-51首先查询出需要删除的记录(2)把查询语句的“find”修改为“deleteOne”(如果只删除第1条满足要求的数据),或把查询语句的“find”修改为“deleteMany”(如果要删除所有满足要求的数据)。具体命令如下:db.getCollection('example_data_1').deleteMany({'hello':'world'})运行效果如图3-52所示。图3-52删除数据(3)在返回的数据中,“acknowledged”为“true”表示删除成功,“deletedCount”表示一共删除了1条数据。(4)再次查询example_data_1,发现已经找不到被删除的数据了,如图3-53所示。图3-53已经找不到被删除的数据了提示:慎用删除功能。一般工程上会使用“假删除”,即:在文档里面增加一个字段“deleted”,如果值为0则表示没有删除,如果值为1则表示已经被删除了。默认情况下,deleted字段的值都是0,如需要执行删除操作,则把这个字段的值更新为1。而查询数据时,只查询deleted为0的数据。这样就实现了和删除一样的效果,即使误操作了也可以轻易恢复。\h3.4.5实例7:数据去重实例描述在数据集example_data_1中,进行以下两个去重操作。(1)对“age”字段去重。(2)查询所有“age”大于等于24的数据,再对“age”进行去重。去重操作用到的命令为“distinct()”。格式如下:db.getCollection('example_data_1').distinct(’字段名’,查询语句的第一个字典)distinct()可以接收两个参数:●第1个参数为字段名,表示对哪一个字段进行去重。●第2个参数就是查询命令“find()”的第1个参数。distinct命令的第2个参数可以省略。1.对“age”字段去重对“age”字段去重的语句如下:db.getCollection('example_data_1').distinct('age')运行效果如图3-54所示。图3-54对“age”字段去重在MongoDB中返回的数据是一个数组,里面是去重以后的值。2.对满足特定条件的数据去重首先查询所有“age”大于等于24的数据,然后对“age”进行去重。具体语句见代码3-7。代码3-7对“age”大于等于24的记录的“age”字段去重运行结果如图3-55所示。图3-55先筛选再去重也许有读者会问,能否去重以后再带上其他字段呢?答案是,用“distinct()”命令不能实现。要实现这个功能,需要学习第7章的内容。\h3.5使用Python操作MongoDB在工程中,一般都需要一种编程语言来操作数据库。使用Python来操作数据库有着天然的优势,因为Python的字典和MongoDB的文档几乎是一样的格式。\h3.5.1连接数据库1.安装PyMongo使用Python操作MongoDB需要使用一个第三方库——PyMongo。安装这个库与安装Python其他的第三方库一样,使用pip安装即可:python3-mpipinstallpymongo安装完成以后,打开Python交互环境,导入PyMongo。如果不报错(如图3-56所示),则表示安装成功。图3-56不报错表示安装成功2.连接数据库要使用PyMongo操作MongoDB,首先需要初始化数据库连接。(1)如果MongoDB就运行在本地电脑上,而且也没有修改端口或者添加用户名和密码,则初始化MongoClient的实例不需要带参数,直接写为以下格式:(2)如果MongoDB运行在其他服务器上,则需要使用“URI(UniformResourceIdentifier,统一资源标志符)”来指定链接地址。MongoDBURI的格式如下:mongodb://用户名:密码@服务器IP或域名:端口例如:(3)如果没有设置权限验证,则不需要用户名和密码,可以写为:本章使用不设置密码、不改端口、本地运行的MongoDB。3.连接库与集合PyMongo连接库与集合有两种方式。●方式1,见代码3-8。代码3-8连接数据库与集合的方法1需要注意,在使用这种方式时,代码中的“数据库名”和“集合名”都不是变量名,它们直接就是库的名字和集合的名字。例如,要连接上example_data_1所在的集合,则Python代码如下:●方式2,见代码3-9。代码3-9连接数据库与集合方法2在使用这种方式时,在方括号中可以直接填变量来指定库名和集合名。当然,也可以直接填字符串,例如:方式1和方式2效果是完全相同的。读者可以任意选择一种自己喜欢的方式。方式2主要用在需要批量操作数据库的情况下。例如在工程中,有时有多个测试环境,现在需要同时更新这些环境对应的数据库,则可以使用方式2。因为,这样可以将多个数据库的名字或者是多个集合的名字保存在列表中,然后再使用循环来进行操作,见代码3-10。代码3-10使用循环连接多个集合其中第3行代码,在循环里面每次连接不同的库。这样写可以同时更新多个数据库的信息。对于同一个数据库里面的多个集合,也可以使用这个方法来操作。\h3.5.2MongoDB命令在Python中的对应方法在获取到集合连接对象collection后,就可以用这个对象的各个方法来操作MongoDB了。虽然MongoDB的命令和collection的方法名在写法上有微小的差异,但绝大多数的MongoDB语句的参数直接复制到Python代码中都可以使用。MongoDB的命令使用的是驼峰命名法,而PyMongo使用的是“小写字母加下划线”的方式。它们的对比见表3-3。表3-3MongoDB命令与PyMongo方法对照表例如,Robo3T执行的批量插入语句见代码3-11。代码3-11在Robo3T中批量插入数据对应到Python中,见代码3-12。代码3-12使用Python批量插入数据其中,第4行代码中使用了新的集合名字,用以区别。使用Python操作MongoDB还有一个好处:如果当前使用的库或者集合不存在,则在调用了插入方法以后,PyMongo会自动创建对应的库或集合。总之,绝大部分的操作,直接从Robo3T中复制到Python中都可以运行,几乎不需要修改。\h3.5.3实例8:插入数据到MongoDB实例描述在Python中,将字典{'name':’王小六’,'age':25,'work':’厨师’}插入到MongoDB中。具体命令如下:collection.insert_one({'name':’王小六’,'age':25,'work':’厨师’})提示:PyMongo还有一个通用方法——collection.insert()。•如果传入的是一个字典,则collection.insert()相当于insert_one。•如果传入的是一个包含字典的集合,则collection.insert()相当于insert_many。但是PyMongo开发者准备移除它,因此不推荐读者在正式环境中使用这个方法。\h3.5.4实例9:从MongoDB中查询数据实例描述在Python中,从MongoDB中查询所有“age”大于21小于25,并且“name”不等于“夏侯小七”的记录。具体见代码3-13。代码3-13在Python中查询所有“age”大于21小于25,并且“name”不等于“夏侯小七”的记录运行效果如图3-57所示。图3-57使用Python查询MongoDB\h3.5.5实例10:更新/删除MongoDB中的数据实例描述在Python中更新数据和删除数据:(1)对于“name”为“公孙小八”的记录,将“age”更新为80,将“address”更新为“美国”。(2)删除“age”为0的数据。1.更新MongoDB中的数据在Python中,可以使用udate_many方法来批量更新数据,见代码3-14。代码3-14在Python中更新多条数据更新操作还支持一个“upsert”参数。该参数的作用是:如果数据存在,则更新;如果数据不存在,则创建。例如,对于“name”为“隐身人”的记录,将“age”改为0,将“address”改为“里世界”。由于example_data_1中没有这一条记录,因此直接更新会报错,如图3-58所示。图3-58直接更新不存在的记录会导致报错加上“upsert”参数,见代码3-15。代码3-15在Python中更新或者插入一条数据运行效果如图3-59所示。图3-59运行效果提示:如果打开了更
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 装修进度款支付合同
- 药品冷链运输保密合同
- 商业空间装修施工合同范本
- 包包购销合同
- 咨询服务合同终止协议书年
- 互联网广告投放策略与实践案例
- 建筑项目居间合同
- 出租打印机合同年
- 图书购销合同范例
- 工程管理咨询合同
- 2 找春天 公开课一等奖创新教学设计
- 2025年江苏护理职业学院高职单招语文2018-2024历年参考题库频考点含答案解析
- 2025年江苏南京水务集团有限公司招聘笔试参考题库含答案解析
- 护理人文知识培训课件
- 建筑工程施工安全管理课件
- 2025年春新人教版数学七年级下册教学课件 7.2.3 平行线的性质(第1课时)
- 安徽省合肥市2025年高三第一次教学质量检测地理试题(含答案)
- 2025年上半年毕节市威宁自治县事业单位招考考试(443名)易考易错模拟试题(共500题)试卷后附参考答案
- 处方点评知识培训
- 超星尔雅学习通《大学生心理健康教育(兰州大学版)》章节测试含答案
- 2020译林版高中英语选择性必修二单词默写表
评论
0/150
提交评论