MongoDB安装+Python操作MongoDB
一、MongoDB安装及服务启动
1、安装
2、创建数据库目录
在你想要存放数据的地方,新建一个文件夹,如db,推荐的数据库目录设置是
1 | data/ |
3、启动配置
mongod是mongodb服务的启动工具。常用参数如下
参数 | 描述 |
---|---|
–bind_ip | 绑定可访问mongoDB的IP,若绑定127.0.0.1,则只能本机访问;0.0.0.0表示任意IP均可连接 |
–logpath | 指定MongoDB日志文件,注意是指定文件不是目录 |
–logappend | 使用追加的方式写日志 |
–dbpath | 指定数据库路径 |
–port | 指定服务端口号,默认端口27017 |
–serviceName | 指定服务名称 |
–fork | 以守护进程形式启动(避免退出窗口后关闭) |
–engine | 存储引擎类型,mongodb 3.0之后支持“mmapv1”、“wiredTiger”两种引擎,默认值为“mmapv1”;官方宣称wiredTiger引擎更加优秀 |
上述参数都可以写入 mongod.conf 配置文档里例如:
1 | dbpath = /data/db |
4、服务开启
(1)在winodws下启动服务
方案一:进入bin目录下,参数启动
1 | mongod --dbpath "f:\data\db" --logpath "f:\data\log\mongodb.log" --serviceName "mongodb" --logappend --fork |
方案二:进入bin目录下,配置启动
1 | mongod --f "f:\data\conf\mongod.conf" |
方案三:注册成服务,服务启动(配置中声明了服务名称)
1 | mongod --f "f:\data\conf\mongod.conf" --install |
(2)在linux下启动服务
方案一:进入bin目录下,参数启动
1 | mongod --dbpath=/data/db --logpath=/data/db/log/mongodb.log --serviceName=mongodb --logappend --fork |
方案二:进入bin目录下,配置启动
需要注意32位系统关闭需加入参数:–journal
1 | mongod --f /data/conf/mongodb.conf |
方案三:开机启动
将mongodb启动项目追加入/etc/rc.local保证mongodb在服务器开机时启动
1 | echo "/usr/local/mongodb/bin/mongod --f /data/conf/mongodb.conf" >> /etc/rc.local |
5、服务关闭
(1)使用数据库命令关闭
1 | use admin; |
(2)使用mongod 命令关闭
1 | mongod --shutdown --dbpath=/data/db |
二、pymongo安装
连接MongoDB需要用到Python的PyMongo库,安装方法如下
1 | install pymongo |
三、使用pymongo操作MongoDB数据库
创建连接,获取db和collection
1 | import pymongo |
注意:db和collection都是延时创建的,在添加Document时才真正创建
1、插入数据
(1)调用collection的insert()方法插入数据
在MongoDB中,每条数据都有一个_id属性来唯一标识,如果没有显式指明_id,MongoDB会自动产生一个ObjectId类型的_id属性。insert()方法会在执行后返回_id值
1 | # 新建一条测试数据,以字典的形式表示 |
插入多条数据,只需要以列表形式传递即可
1 | # 新建一条测试数据,以字典的形式表示 |
(2)调用collection的insert_one()和insert_many()方法插入数据
在PyMongo 3.X版本中,insert()方法官方已经不推荐使用了,当然继续使用也没有什么问题,官方推荐使用insert_one()和insert_many()方法将插入单条和多条记录分开。
1 | result = mongo_collection1.insert_one(data_test1) |
insert_one()方法返回的是InsertOneResult对象,调用其inserted_id属性可以获取插入数据的_id。
1 | result = mongo_collection1.insert_many([data_test1, data_test2]) |
insert_many()方法返回的是InsertManyResult对象,调用inserted_ids属性可以获取插入数据的_id列表。
2、基础查询
插入数据后我们可以利用find_one()或find()方法进行查询,find_one()查询得到是单个结果,find()则返回多个结果。
1 | result1 = mongo_collection1.find({'name': 'test02'}) |
也可以直接根据ObjectId来查询,这里需要使用bson库里面的ObjectId。
1 | from bson.objectid import ObjectId |
3、条件查询
如果要查询年龄大于20的数据,则写法如下:
1 | results = mongo_collection1.find({'age': {'$gt': 20}}) |
在这里查询的条件键值已经不是单纯的数字了,而是一个字典,其键名为比较符号$gt,意思是大于,键值为20,这样便可以查询出所有年龄大于20的数据。
比较符号归纳如下表:
符号 | 含义 | 示例 |
---|---|---|
$lt | 小于 | {‘age’: {‘$lt’: 20}} |
$gt | 大于 | {‘age’: {‘$gt’: 20}} |
$lte | 小于等于 | {‘age’: {‘$lte’: 20}} |
$gte | 大于等于 | {‘age’: {‘$gte’: 20}} |
$ne | 不等于 | {‘age’: {‘$ne’: 20}} |
$in | 在范围内 | {‘age’: {‘$in’: [20, 23]}} |
$nin | 不在范围内 | {‘age’: {‘$nin’: [20, 23]}} |
另外还可以进行正则匹配查询,例如查询名字以M开头的学生数据,示例如下:
1 | results = mongo_collection1.find({'name': {'$regex': '^M.*'}}) |
在这里使用了$regex来指定正则匹配,^M.*代表以M开头的正则表达式,这样就可以查询所有符合该正则的结果。
在这里将一些功能符号再归类如下:
符号 | 含义 | 示例 | 示例含义 |
---|---|---|---|
$regex | 匹配正则 | {‘name’: {‘$regex’: ‘^M.*’}} | name以M开头 |
$exists | 属性是否存在 | {‘name’: {‘$exists’: True}} | name属性存在 |
$type | 类型判断 | {‘age’: {‘$type’: ‘int’}} | age的类型为int |
$mod | 数字模操作 | {‘age’: {‘$mod’: [5, 0]}} | 年龄模5余0 |
$text | 文本查询 | {‘$text’: {‘$search’: ‘Mike’}} | text类型的属性中包含Mike字符串 |
$where | 高级条件查询 | {‘$where’: ‘obj.fans_count == obj.follows_count’} | 自身粉丝数等于关注数 |
4、计数,排序与偏移
(1)计数
要统计查询结果有多少条数据,可以调用count()方法,如统计所有数据条数
1 | count = mongo_collection1.find().count() |
或者统计符合某个条件的数据
1 | count = mongo_collection1.find({'age': 20}).count() |
(2)排序
调用sort方法,传入排序的字段及升降序标志即可
1 | results = mongo_collection1.find().sort('name', pymongo.ASCENDING) |
(3)偏移
在某些情况下我们可能想只取某几个元素,在这里可以利用skip()方法偏移几个位置,比如偏移2,就忽略前2个元素,得到第三个及以后的元素。
1 | results = mongo_collection1.find().sort('name', pymongo.ASCENDING).skip(2) |
另外还可以用limit()方法指定要取的结果个数,示例如下:
1 | results = mongo_collection1.find().sort('name', pymongo.ASCENDING).skip(2).limit(2) |
值得注意的是,在数据库数量非常庞大的时候,如千万、亿级别,最好不要使用大的偏移量来查询数据,很可能会导致内存溢出,可以使用类似下面这样的方法来查询,记录好上次查询的_id。
1 | mongo_collection1.find({'_id': {'$gt': ObjectId('593278c815c2602678bb2b8d')}}) |
5、更新
对于数据更新可以使用update()方法,指定更新的条件和更新后的数据即可
1 | condition = {'name': 'Kevin'} |
在这里我们将name为Kevin的数据的年龄进行更新,首先指定查询条件,然后将数据查询出来,修改年龄,之后调用update方法将原条件和修改后的数据传入,即可完成数据的更新。
另外update()方法其实也是官方不推荐使用的方法,在这里也分了update_one()方法和update_many()方法,用法更加严格,第二个参数需要使用$类型操作符作为字典的键名。
1 | condition = {'name': 'Kevin'} |
在这里调用了update_one方法,第二个参数不能再直接传入修改后的字典,而是需要使用{‘$set’: student}这样的形式。然后调用matched_count和modified_count属性分别可以获得匹配的数据条数和影响的数据条数。
1 | condition = {'age': {'$gt': 20}} |
在这里我们指定查询条件为年龄大于20,然后更新条件为{‘$inc’: {‘age’: 1}} ,也就是年龄加1,执行之后会讲第一条符合条件的数据年龄加1。
如果调用update_many()方法,则会将所有符合条件的数据都更新。
1 | condition = {'age': {'$gt': 20}} |
6、删除
删除操作比较简单,直接调用remove()方法指定删除的条件即可,符合条件的所有数据均会被删除。
1 | result = collection.remove({'name': 'Kevin'}) |
依然存在两个新的推荐方法,delete_one()和delete_many()方法。
1 | result = collection.delete_one({'name': 'Kevin'}) |
delete_one()即删除第一条符合条件的数据,delete_many()即删除所有符合条件的数据,返回结果是DeleteResult类型,可以调用deleted_count属性获取删除的数据条数。