NoSQL-MongoDB with python
前言: MongoDB,文档存储型数据库(document store)。NoSQL数据库中,它独占鳌头,碾压其他的NoSQL数据库。 使用C++开发的,性能仅次C。与redis一样,开源、高扩展、高可用。 基于分布式文件存储。分布式:文件分开存的(由Google提出的mapreduce,是目前分布式的鼻祖)。就像苹果的iCloud,照片、文件分开存储的。 纽约时报用的数据库就是它(from wiki),360部分业务的数据库也是它。而且据说伟大的wiki,也是从曾经的MySQL迁移到了MongoDB。 MongoDB的适用场景可以看下这篇文章:https://yq.aliyun.com/articles/64352 但要注意,MongoDB在使用过程中会消耗大量磁盘空间和内存。而且,MongoDB它非事务机制,无法保证事件的原子性。 MongoDB不适合的场景: (1).需高度事务性的系统。当原子性操作失败时,传统的关系型数据库支持回滚操作,以保证数据在操作过程中的正确性。而目前,MongoDB暂不支持此事务。例如银行或会计系统。 (2).传统的商业智能应用。针对特定问题的BI数据库需要高度优化的查询方式。 (3).使用SQL方便时(关联查询)。MongoDB的查询方式是JSON类型的查询方式,虽然查询也比较灵活,但如果使用SQL进行统计会比较方便时,这种情况就不适合使用MongoDB。 ? MongoDB描述: MongoDB是文档数据库,以文档为单位。Bson文档(Json的二进制) 与JS相关,内部引擎用了JS解释器。 把一个文档存储为Bson结构,在查询时,转换位Json对象,并可以通过JS语法来操作。 ? MongoDB PK?传统型数据库: 传统型数据库:结构化数据,定好表结构后,每一行内容必须符合表结构,以至于每一行看起来都长得差不多。 MongoDB:以文档为单位,没有表结构。表中的每篇文档都可以有自己独特的属性和结构。 MongoDB最大的特点就是反范式化,管你几张表,都可以一个文档解决。每个文档相当于一棵树,可以无限伸枝。文档与文档之间相互独立,没有固定的结构。 (一).文档的表现形式:一个Json对象,一个文档 # 一个文档 { id: 3 name: "lisi" age: 10 } # 另一个文档 { id: 4 name: "wangwu" age: 20 area: "nb" hobby: ["swimming","football"] } (二).思考这么一个问题: 以此https://movie.douban.com/subject/26861685/?from=showing为例,设计一个影评数据库。 传统数据库:影片信息一张表,影评一张表,回复评论一张表,打分一张表。查询起来相当费劲,关联相当复杂。 MongoDB:上述内容全部丢进一个文档中解决: { file_name: "红海行动" long_time: 120 comment: [ { comment1: "影评1" reply1: "好评" } ] } 一、install MongoDB for win7 32bit(万事从安装开始) 悲催的win7 32位系统,安装这只芒果可是受尽折磨,不是执行命令后没反应、就是因为32/64位的问题……(读音像mango,叶子图标也像芒果叶子,本人就干脆喊芒果了)。 第一步操作成功:(开心)MongoDB的默认端口为27017 第二步配置:(注意环境变量的路径大小写,第一次没成功,后来直接在地址栏上复制了路径,成了!所以猜测,可能是因为路径大小写问题造成) 有时候电脑会抽风,即使配置好了环境变量,在C盘盘符下打这串命令会提示不是内部命令。那么直接cd进入mongodb/bin目录,再执行这条命令,就行了。 可在系统服务中看到它了: 相对现在的新版本,这个算是很老的版本了,不过学习用应该是够了。 MongoDB使用内存映射文件,32位系统上,数据库容量最大上限为2G(学习用而已,有那么多数据吗[糗])关于这个内存映射文件,不了解也没关系,影响不大 第三步:搞一个可视化管理工具 本来想用Robomongo(因为它界面很好看),但没找到适用于win7 32位系统的[/喷血]。如有大大找到的话,恳请提供。 现在在用MongoVUE,专门用于windows系统的。填写连接卡的时候,最后下面三个不填也可以连上。Name随便写,可以写你喜欢的人的名字;Server:具体情况具体填,可以填一个远程主机的IP;Database(s)这项不填,就会获得所有数据库。 ? 二、python3操作MongoDB (一).连接localhost server,创建一个新数据库 注意:MongoDB的默认端口号是27017,跟其他数据库一样,创建连接时要写上。 from pymongo import MongoClient conn = MongoClient("localhost",27017) # 也可以写成 # conn = MongoClient("mongodb://localhost:27017") db = conn.testdb # 创建数据库 conn.close() MongoDB不需要提前创建好数据库,可以直接"连接对象.数据库名称"。如果没有这个数据库,则会自动创建。如果有这个数据库了,就会连接上。 但是,如果该数据库中没有数据,则不会显示在管理工具里面。 (二).增。 (1).插入单条记录 from pymongo import MongoClient conn = MongoClient("localhost",27017) db = conn.testdb # db = MongoClient("localhost",27017).testdb # 这样写的话,后面数据库连接就没法关闭了。所以别偷懒,还是要分开写。 db.col.insert({"name": "jack613","province": "江南","age": 23}) # col是表名 conn.close() (2).插入多条记录 from pymongo import MongoClient conn = MongoClient("localhost",27017) db = conn.testdb db.col.insert([ {"name": ‘张三‘,‘province‘: ‘江苏‘,‘age‘: 24},{"name": ‘mkcry‘,‘province‘: ‘辽宁‘,{"name": ‘jack‘,‘province‘: ‘山西‘,‘age‘: 30} ]) conn.close() 总结:插入多条记录,insert()的括号中,需要用[]把元素包裹起来。insert([{},{},{}]) (三).删。特别注意:remove()括号中不加条件,就会把表中的记录全删了!切记注意! from pymongo import MongoClient conn = MongoClient("localhost",27017) db = conn.testdb db.col.remove({"name": "张三"}) conn.close() (四).改。update({条件},{更新的数据}) 把条件和更新的数据放进去update()的括号里就可以了。更新语句,注意格式别写错了,应该是{"$set":{"key":value}} from pymongo import MongoClient conn = MongoClient("localhost",27017) db = conn.testdb db.col.update({"name": "jack"},{"$set": {"age": 29}}) conn.close() (五).查。 (1).使用find_one()查询并返回第一个匹配到的文档 from pymongo import MongoClient conn = MongoClient("localhost",27017) db = conn.testdb db.col.find_one() conn.close() 可以把"db.col.find_one()"放在print()中,这样就可以看到打印出来的查询结果了。print()之后的结果:{‘_id‘: ObjectId(‘5a924d0f36af002d307cc30b‘),‘name‘: ‘jack‘,‘province‘: ‘江苏‘,‘age‘: 88} 这个‘_id‘:ObjectId(‘xxxxxxxxx‘)是自动生成的唯一值。 db.col.find_one({"name":"abc"}) 没有找到文档则返回None (2).查询所有记录。可以使用find()函数,执行后返回的是一个结果集对象,需要用for循环遍历出来。 from pymongo import MongoClient conn = MongoClient("localhost",27017) db = conn.testdb # print(db.col.find()) # <pymongo.cursor.Cursor object at 0x01D96210> for item in db.col.find(): print(item) conn.close() """ # 远行结果: {‘_id‘: ObjectId(‘5a924d0f36af002d307cc30b‘),‘age‘: 30} {‘_id‘: ObjectId(‘5a92520f36af001ca0fb665c‘),‘name‘: ‘张三‘,‘province‘: ‘湖南‘,‘age‘: 24} {‘_id‘: ObjectId(‘5a92520f36af001ca0fb665d‘),‘name‘: ‘mikcry‘,‘province‘: ‘北京‘,‘age‘: 24} {‘_id‘: ObjectId(‘5a92520f36af001ca0fb665e‘),‘name‘: ‘it‘,‘province‘: ‘陕西‘,‘age‘: 30} (3).条件查询 只需要将条件当作参数放进find()的括号中即可: from pymongo import MongoClient conn = MongoClient("localhost",27017) db = conn.testdb for item in db.col.find({"name": "jack"}): print(item) conn.close() 例1:查询所有小于某个值的记录 from pymongo import MongoClient conn = MongoClient("localhost",27017) db = conn.testdb for item in db.col.find({"age": {"$lt": 25}}): print(item) conn.close() """ 运行结果: {‘_id‘: ObjectId(‘5a92520f36af001ca0fb665c‘),‘province‘: ‘山东‘,‘age‘: 24} """ #大于的话,就把{"age":{"$lt":25}}中的lt换成gt (4).统计记录 from pymongo import MongoClient conn = MongoClient("localhost",27017) db = conn.testdb db.col.find({"age": {"$eq": 88}}).count() # 返回int,但不会直接显示结果,需要赋值变量或者打印 # print(db.col.find({"age": {"$eq": 88}}).count()) # 2 conn.close() (5).根据_id查询记录 需要引入一个库,这个库python3自带了。from bson.objectid import ObjectId from pymongo import MongoClient from bson.objectid import ObjectId conn = MongoClient("localhost",27017) db = conn.testdb # ObjectId是唯一的,所以用find_one()就可以了 db.col.find_one({‘_id‘: {ObjectId(‘5a924d0f36af002d307cc30b‘)}}) # print(db.col.find_one({‘_id‘: ObjectId(‘5a924d0f36af002d307cc30b‘)})) # {‘_id‘: ObjectId(‘5a924d0f36af002d307cc30b‘),‘age‘: 88} conn.close() (6).排序。MongoDB默认升序排序。 sort()小括号中放入指定的key就可以了: from pymongo import MongoClient conn = MongoClient("localhost",27017) db = conn.testdb for item in db.col.find().sort("age"): print(item) conn.close() """ 运行结果: {‘_id‘: ObjectId(‘5a92520f36af001ca0fb665c‘),‘age‘: 24} {‘_id‘: ObjectId(‘5a924d0f36af002d307cc30b‘),‘age‘: 88} {‘_id‘: ObjectId(‘5a92520f36af001ca0fb665e‘),‘age‘: 30} """ 另外,可以加入参数去设定排序方式。 比如倒序,例1:(需要引入pymongo) import pymongo from pymongo import MongoClient conn = MongoClient("localhost",27017) db = conn.testdb for item in db.col.find().sort("age",pymongo.DESCENDING): # descending降序 print(item) conn.close() (六).补充内容 (1).删除一张表:db.drop_collection("table_name") 表和其中的数据同时删除 (2).查看一个数据库中所有的表:db.collection_names() (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- c# – 使用EF Core在通用存储库中使用Reflection包含所有导
- 单元测试 – 有限时间的工作代码库的单元测试:如何?
- Flex4之元数据标签:[ArrayElementType] [Bindable] [Defau
- ruby-on-rails – 在Rails 2.2.2中动态地向ActiveRecord模型
- 能让你少写1000行代码的20个正则表达式
- 依赖注入 – 泽西岛:如何将EJB注入子资源?
- 单元测试 – 在测试该API的包装器时,我的单元测试是否应该直
- ruby-on-rails – Rails gem Ransack – >搜索’或conditio
- oracle sql语言模糊查询--通配符like的使用教程详解
- ruby-on-rails – 如何使某些属性仅对具有特定角色的用户可