20 Mongodb数据库编程

MongoDB 是一个介于关系数据库和非关系数据库之间的产品有称NoSQL数据库,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。

如何理解关系型和非关系型数据库?

举一个简单例子一门课程的成绩单,多行多列,行称之为记录,列称之为字段,某位置上的数据有严格的数据格式、类型要求。而非关系型数据库就像一本流水帐,随便咋记录都行,只要自己能找到能理解即可,所以非关系型数据库比较适合网络提取回来的大数据,每条数据记录间未必有任何关系,但数据有价值。

也就是说关系型数据库存储的是有规定格式的记录,而非关系型数据库存储的是随意格式的记录。

20.1 Mongodb相关软件安装

本节主要围绕Mongodb服务器的安装以及客户端的安装、Python编程访问Mongodb的接口模块(又称driver)pymongo的安装。

20.1.1 Mongodb的安装

MongoDB安装很简单,无需下载源文件,可以直接用apt-get命令进行安装。 打开终端,输入以下命令:

sudo apt-get install mongodb

尽管只是指定安装mongodb但apt-get命令会将和mongodb相关的一些软件一起安装,例如访问mongodb数据库服务器的客户端命令mongo也被安装了。

Windows平台的Mongodb安装

在windows下安装mongodb只需去Mongodb官方网站下载相应版本的安装文件即可完成安装。需要注意的是如果想在cmd下使用mongo.exe客户端命令访问mongodb数据库,则需要把mongo.exe客户端命令所在的目录(通常是C:\practicalmongodb\bin\这个目录)配置到系统变量Path里,否则cmd会提示找不到mongo.exe,如何配置Path系统环境变量,可参考16.3节的内容。

20.1.2 python访问Mongodb的接口模块的安装

Python编程Mongodb数据库的接口模块是PyMongo,在Linux下可以通过以下命令进行安装。

sudo apt-get install python-pymongo

检验模块是否安装成功,可以在Python的shell里测试一下:

liao@Liao:~$ python
Python 2.7.12 (default, Nov 19 2016, 06:48:10) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pymongo
>>> 

没有报错,说明模块安装成功,可以通过Python编程访问Mongodb数据库。

20.2 Mongodb的基本使用

Mongodb数据库服务器安装完毕后可以使用一些Mongodb提供的增删改查指令来访问Mongodb数据库服务器,可以创建自己的数据库和表。

20.2.1 客户端访问mongodb服务器

在shell下执行mongo(客户端命令)便可进入mongodb服务器(如果mongo被拒绝连接可以先运行mongod之后在通过mongo客户端命令访问mongo服务器服务)。

liao@Liao:~$ mongo
MongoDB shell version: 2.6.10
connecting to: test
Welcome to the MongoDB shell.
...<此处省略>...
2018-07-19T10:36:13.641+0800 [initandlisten] 
> show dbs #查看当前服务器上的数据库
admin  (empty)
local  0.078GB
>

现在看到的结果是Mongodb数据库刚刚安装完毕后的内容,此时的Mongodb里尚未有任何自己的数据库,可以使用show dbs命令查看当前登录的Mongodb上的数据库有那些。

20.2.2 创建数据库和数据插入操作

在Mongodb里创建数据库和使用(打开某)数据库都用use命令。但要想新建一个数据库仅仅用use还不行,还需插入一些数据后才真正的创建了新的数据库。接下来用两个例子来展示一下Mongodb下是如何创建新的数据库的。

示例1:库名cpython、其下一表表名为info

> use cpython # 使用、创建数据库
switched to db cpython
> show dbs # 查看当前有那些数据库存在
admin  (empty)
local  0.078GB
test   (empty) # 此时还没真正产生cpython
> use cpython
switched to db cpython
> db.info.insert({"id":1, "name" : "liming"})#插入数据
WriteResult({ "nInserted" : 1 })
> show dbs# 查看此时是否存在新建的数据库
admin    (empty)
cpython  0.078GB #创建成功了
local    0.078GB
test     (empty)
> db.info.find()
{ "_id" : ObjectId("5b4fffad15674b364abdcca3"), "id" : 1, "name" : "liming" }

示例2:新建数据库名为mydb、其下新表表名为record

# 假设此时没有mydb,insert之后才真正创建了mydb数据库
> use mydb 
switched to db mydb
# 向表record插入数据,如果record表不存在,insert之后创建表record
> db.record.insert({"id" : 1, "name" : "yangmi"})
WriteResult({ "nInserted" : 1 })
# 查询服务器上有那些数据库
> show dbs
admin    (empty)
cpython  0.078GB
local    0.078GB
mydb     0.078GB
test     (empty)
# 看看record表里的数据
> db.record.find() 
{ "_id" : ObjectId("5b50068415674b364abdcca4"), "id" : 1, "name" : "yangmi" }
> 

两个例子里的db代表通过use命令打开的数据库,通过db可以访问打开(如果没有则创建新表)数据库下的表调用insert或者find指令可以进行数据的插入和查询。

# 打开或者新建数据库
use 某数据库 
# db代表正打开或新建的数据库,如果表名不存在则新建表
db.表名字.insert(记录数据)
# 查询表的数据
db.表名字.find(条件)

这种即创建又使用的思维需要适应。

示例3:使用cpython数据库、再建一个表sales、查询表信息

# getname可以获得当前打开正在操作的数据库的名字
> db.getname()
2018-07-19T20:50:39.493+0800 TypeError: Property 'getname' of object cpython is not a function
# show collections可查看库下有那些表
> show collections
info
system.indexes
# 通过insert创建新表,因为sales此时不存在
> db.sales.insert({"id":1, "name" : "liming"})
WriteResult({ "nInserted" : 1 })
> show collections
info
sales # 新增表sales
system.indexes
# 查询当前库下的sales表里的数据
> db.sales.find()
{ "_id" : ObjectId("5b508953bfd023d9aecc803d"), "id" : 1, "name" : "liming" }
> db.getCollectionNames()
[ "info", "sales", "system.indexes" ]
> 

至此,我们可以看出Mongodb下的表不是成为table而叫collection。可以通过show collections查看库下有那些表,也可用db.getCollectionsName()来得到当前使用的数据库里的表的信息。

示例4:删除记录和表、库

> db.sales.find()
{ "_id" : ObjectId("5b508c0cbfd023d9aecc803e"), "id" : 1, "name" : "liming" }
# 用命令可删除记录
> db.sales.remove({"name" : "liming"})
WriteResult({ "nRemoved" : 1 })
> db.sales.find()
> show collections
info
sales
system.indexes
# drop可以删除表:sales
> db.sales.drop()
true
> show collections
info
system.indexes

# 准备新建库newdb
> use newdb
switched to db newdb
# 查看当前是那个库?
> db
newdb
# 查看当前是那个库?
> db.getName()
newdb
# 查看当前有那些库?
> show dbs
admin    (empty)
cpython  0.078GB
local    0.078GB
# 向newdb的newtable表出入数据
> db.newtable.insert({12 : 13})
WriteResult({ "nInserted" : 1 })
# 查询一下表newtable里的数据
> db.newtable.find()
{ "_id" : ObjectId("5b508cfdbfd023d9aecc803f"), "12" : 13 }
# 删除当前正在用的库即newdb
> db.dropDatabase()
{ "dropped" : "newdb", "ok" : 1 }
# 查看当前有那些库?
> show dbs
admin    (empty)
cpython  0.078GB
local    0.078GB
> 

通过这几个例子已经基本会使用Mongodb了,为何便于理解在示例里解释依然沿用了关系型数据库里的术语,其实在Mongodb里表的学术名词是collection,记录对应的学术名词是document。

20.3 Mongodb数据库编程

Mongodb的一些高级使用特性,例如帐号管理,不是本网站主题,如果对Mongodb想深入理解,可参阅一些书籍,本网站主旨是推广Python介绍Python周边的生态圈,故Mongodb数据库的深入学习读者们可自行阅读掌握。欢迎把体会或者对本网站没考虑到的必须补充的内容发邮件给我吧。

邮箱地址 : mailliao艾特126点儿com

接下来聊聊Python如何编程访问Mongodb?Python通过编程访问Mongodb数据库相当简单,和访问其他数据库的流程相似,但更节俭。下面以两个例子来展示Python是如何访问Mongodb数据库的。

20.3.1 插入数据表

Python编程访问Mongodb的接口即pymongo模块。可以通过MongoClient建立与MongoClient的连接,需要指定访问那台计算机上的Mongodb,即指定host的值,如果访问本地host = "localhost"这感觉和MySQLdb的connect函数很像,还需要指定的是端口port = 27017,为何是这个端口号?可以通过sudo netstat-lp查看到Mongodb的服务进程mongod占用了这个端口号。

然后通过连接的点运算指定要读写的数据库,语句db = c.cpython的作用就是让db代表Mongodb数据库服务器下的cpython这个数据库。接下来就是插入数据创建了info表,如果服务器上cpython下没有info表,这里插入同时也就创建了表info。Mongodb好就好在一切可以事先不存在,只要插入(修改)就存在了。

import sys
from pymongo import MongoClient
import random
def main():
        c = MongoClient(host="localhost", port=27017)
        print "Connected successfully"
        db = c.cpython
        print "Successfully set up a database handle"
        for x in range(100):
            doc = {"name" : "cpython", "value" : random.randint(100, 900)}
            db.info.insert(doc)
            print doc
if __name__ == "__main__":
    main()

程序执行完毕后,可以在Mongodb的客户端查看是否插入了数据?如下图所示:

20.3.2 查询数据表

下面的程序指示用了一下find函数查询数据。很简单,没有MySQLdb编程那么复杂,感觉在Python里写Mongodb的编程和在mongo客户端里操作一样。

import sys
from pymongo import MongoClient
import random
def main():
        c = MongoClient(host="localhost", port=27017)
        print "Connected successfully"
        db = c.cpython
        print "Successfully set up a database handle"
        ret = db.info.find()
        i = 0
        for x in ret:
            if "value" in x.keys():
                print x["name"], x["value"]
            i += 1
        print i
if __name__ == "__main__":
    main()

程序执行结果如下图所示:

20.3.3 条件查询

mongodb支持find函数带复杂条件的查询。pymongo支持的关系运算符如下表所示:

示例1:查询value > 300的语句为db.info.find({"value" : {"$gt" : 300}})

执行结果如下图所示:

示例2: 查询200 <value< 300的记录语句为db.info.find({"value" : {"$lt" : 300, "$gt" : 200}}),执行结果如图所示:

其他操作符号就不再一一举例子了,把这样的条件写入find函数就可以在Python里进行条件查询了,代码如下所示。

import sys
from pymongo import MongoClient
import random
def main():
        c = MongoClient(host="localhost", port=27017)
        print "Connected successfully"
        db = c.cpython
        print "Successfully set up a database handle"
        ret = db.info.find({"value" : {"$gt" : 300}})
        i = 0
        for x in ret:
            if "value" in x.keys():
                print x["name"], x["value"]
            i += 1
        print i
if __name__ == "__main__":
    main()

20.4 总结

Mongodb数据库非常好!可以存储网络爬下来的各类关系松散的数据,通过pymongo模块实现Python读写数据库步骤少、简单!建议阅读本章之后读者在深入学学。