LinuxEye - Linux系统教程

LinuxEye - Linux系统教程

当前位置: 主页 > 脚本编程 >

Python实现MongoDB数据导入及自定义复杂查询函数

时间:2013-06-20 21:10来源:wubiaoblog.com/archives/597 编辑:吴飚 点击:
主要包含两部分: 1、从源文件中加载数据至数据库中。 2、自定义特定的查询函数。 Python 对MongoDB的支持实在是太强悍了!活生生的MongoDB原生语法,在mongo中表示大于的操作符是$gt,在
主要包含两部分:
1、从源文件中加载数据至数据库中。
2、自定义特定的查询函数。

Python对MongoDB的支持实在是太强悍了!活生生的MongoDB原生语法,在mongo中表示大于的操作符是‘$gt’,在Python中也是这样。。。
测试数据:
wubiao,chinese,91
wubiao,math,11
zhangsan,english,40
zhangsan,politics,95
zhangsan,physics,84
lisi,computer,92
lisi,english,95
lisi,chinese,88
wanger,mathematics,90
wanger,english,60
wanger,chinese,40
zhaoliu,economics,96
zhaoliu,computer,94

计划数据库中存储数据结构为:
{ "course" : "chinese", "score" : 91, "name" : "wubiao" }
{ "course" : "math", "score" : 11, "name" : "wubiao" }
{ "course" : "english", "score" : 40, "name" : "zhangsan" }
{ "course" : "politics", "score" : 95, "name" : "zhangsan" }
{ "course" : "physics", "score" : 84, "name" : "zhangsan" }
{ "course" : "computer", "score" : 92, "name" : "lisi" }
{ "course" : "english", "score" : 95, "name" : "lisi" }
{ "course" : "chinese", "score" : 88, "name" : "lisi" }
{ "course" : "mathematics", "score" : 90, "name" : "wanger" }
{ "course" : "english", "score" : 60, "name" : "wanger" }
{ "course" : "chinese", "score" : 40, "name" : "wanger" }
{ "course" : "economics", "score" : 96, "name" : "zhaoliu" }
{ "course" : "computer", "score" : 94, "name" : "zhaoliu" }

源文件每行数据包含姓名、课程、得分,以逗号分隔。对于这几条数据来说,完全可以用Mongo客户端手段插入,但是如果几十万条,几百万条呢?不可能一行一行自己插,所以必须要借助工具或脚本实现。

本次查找的需求是:找出有至少两门课程成绩达到90以上的学员名单。这只是个很简单的需求,其实我们完全可以很轻松的自定义各种复杂的查询函数。

MongoDB略

启动mongod
[root@biao ~]# mongod -f /etc/mongod.conf
all output going to: /mongodb/log/mongodb.log
forked process: 32465
child process started successfully, parent exiting
[root@biao ~]# service mongod status
mongod (pid 32465) is running...
[root@biao ~]# ps aux|grep mongod
root     32465  0.6  0.7 118388 22008 ?        Sl   02:00   0:00 mongod -f /etc/mongod.conf
root     32559  0.0  0.0   4032   684 pts/11   R+   02:01   0:00 grep mongod
[root@biao ~]# netstat -aux|grep mongod
unix  2      [ ACC ]     STREAM     LISTENING     519024 /tmp/mongodb-27017.sock
如上所示,mongod启动成功,监听端口为27017。

Python代码:
import pymongo
import string

#建立连接
conn = pymongo.MongoClient()

#获取数据库
db = conn.test_python

#获取集合
stu = db.stu

##############从源文件中加载数据至数据库中 begin##############
#打开文件
f = open("data.txt")

#文件包含的行数计数器
counter = 0

print "***下列行将会作为文档被插入至数据库中...***"
while True:
    #读取源数据文件中的每一行并插入数据库中
    line = f.readline()
    if not line:
        break
    lines = line.replace("\n","").split(",")
    counter = counter + 1
    #由于从文件中读取的数据都是字符串类型,使用string.atoi()函数将分数转换为数值类型
    doc = {"name":lines[0],"course":lines[1],"score":string.atoi(lines[2])}
    stu.insert(doc)  
    print lines       

print "***总计有%d行作为文档已被插入数据库中...***" %counter

#关闭文件 
f.close()
##############源文件中加载数据至数据库中 end################

#通过查询所有数据,验证前面插入的数据,当然,用客户端看也可以,只是测试。
##############从数据库中查询所有文档 start################
#获取文档的游标
cursor = stu.find()
#迭代打印所有文档
print "****当前数据库中包含的所有文档 begin****"
while True:
    try:
        #使用str.replace()方法把控制台打印的文档中带有'u'字符串去掉,否则就会是这个样子:
        #{u'course': u'chinese', u'_id': ObjectId('516721f8ddefe42c122a1a2b'),
        #u'score': 88, u'name': u'lisi'}这不是数据编码有问题,而是我本地Python环境的问题,
        #不去掉也可以,只是个人感觉影响美观,有强迫症的孩子伤不起啊~~
        print "* %s" %str(cursor.next()).replace("u'","")
    except:
        break
print "****当前数据库中包含的所有文档 end******"
##############从数据库中查询所有文档 end##################

##################实现查找的需求 begin##################
#找出有至少两门课成绩达到90以上的同学名单,见证奇迹的时刻就要到了!
#首先查询出所有学员的姓名
names = stu.distinct("name")
#迭代学员姓名,按学员姓名与成绩大于90作为条件查询数据,
#当查询所得的结果集大于2时,即实现了需求。
print "***至少两门课成绩达到90以上的同学名单:"
for name in names:
    cursor = stu.find({"name":name,"score":{"$gt":90}})
    if cursor.count() > 1:
        print name
##################实现查找的需求 end####################

"""
控制台打印信息:
***下列行将会作为文档被插入至数据库中...***
['wubiao', 'chinese', '91']
['wubiao', 'math', '11']
['zhangsan', 'english', '40']
['zhangsan', 'politics', '95']
['zhangsan', 'physics', '84']
['lisi', 'computer', '92']
['lisi', 'english', '95']
['lisi', 'chinese', '88']
['wanger', 'mathematics', '90']
['wanger', 'english', '60']
['wanger', 'chinese', '40']
['zhaoliu', 'economics', '96']
['zhaoliu', 'computer', '94']
***总计有13行作为文档已被插入数据库中...***
****当前数据库中包含的所有文档 begin****
* {course': chinese', _id': ObjectId('516726e7ddefe42fe75b7861'), score': 91, name': wubiao'}
* {course': math', _id': ObjectId('516726e9ddefe42fe75b7862'), score': 11, name': wubiao'}
* {course': english', _id': ObjectId('516726e9ddefe42fe75b7863'), score': 40, name': zhangsan'}
* {course': politics', _id': ObjectId('516726e9ddefe42fe75b7864'), score': 95, name': zhangsan'}
* {course': physics', _id': ObjectId('516726e9ddefe42fe75b7865'), score': 84, name': zhangsan'}
* {course': computer', _id': ObjectId('516726e9ddefe42fe75b7866'), score': 92, name': lisi'}
* {course': english', _id': ObjectId('516726e9ddefe42fe75b7867'), score': 95, name': lisi'}
* {course': chinese', _id': ObjectId('516726eaddefe42fe75b7868'), score': 88, name': lisi'}
* {course': mathematics', _id': ObjectId('516726eaddefe42fe75b7869'), score': 90, name': wanger'}
* {course': english', _id': ObjectId('516726eaddefe42fe75b786a'), score': 60, name': wanger'}
* {course': chinese', _id': ObjectId('516726eaddefe42fe75b786b'), score': 40, name': wanger'}
* {course': economics', _id': ObjectId('516726eaddefe42fe75b786c'), score': 96, name': zhaoli}
* {course': computer', _id': ObjectId('516726eaddefe42fe75b786d'), score': 94, name': zhaoli}
****当前数据库中包含的所有文档 end******
***至少两门课成绩达到90以上的同学名单:
lisi
zhaoliu
"""
代码除了连接、获取数据库、获取集合之外,包含三部分:
1、从源文件中加载数据至数据库中。
2、查询所有的文档验证导入的数据。
3、实现自定义查询。
这三部分是相对独立的,我用###分隔开了,可以一起执行,也可以分别执行不同部分,
不想执行的部分注释掉就好了,用两对三个英文双引号“”"不想执行的代码块“”"注释即可。

对于实现特定查询那部分,可以封装成函数,以后就可以直接用了

转载请保留固定链接: https://linuxeye.com/program/1778.html

------分隔线----------------------------
标签:Pythonmongodb
栏目列表
推荐内容