转自 mongoengine 基本使用
上一篇博文介绍了 pymongo
的基本使用,本文则介绍 mongoengine 的基本使用,mongoengine
底层使用的是pymongo
库。
本文所使用的 mongoengine
版本是 0.10.6。
定义文档模式
与pymongo
不同的是,使用mongoengine
需要先定义文档模式,比如,我们定义一个Student
的文档:
1
2
3
4
5
6
7
8
9
|
class Student(DynamicDocument):
meta = {
'collection': 'student',
'strict': False
}
stu_id = IntField()
age = IntField()
name = StringField()
gender = StringField()
|
基本操作
下面的代码主要介绍了 mongoengine
的基本操作: 插入数据,更新数据,查找数据,删除数据。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
# -*- coding: utf-8 -*-
# mongoengine==0.10.6
from mongoengine import *
# 定义文档模式
class Student(DynamicDocument):
meta = {
'collection': 'student',
'strict': False
}
stu_id = IntField()
age = IntField()
name = StringField()
gender = StringField()
def insert_data():
""" 插入数据 """
# 一种方法
peter = Student()
peter.stu_id = 101
peter.name = 'Peter'
peter.gender = 'male'
peter.save()
# 另一种方法
john = Student(stu_id=102, name="John Smith", gender='male').save()
def update_data():
""" 更新数据 """
# 年龄,注意用双下划线
Student.objects(stu_id=101).update_one(set__age=23)
Student.objects(stu_id=102).update_one(set__age=26)
# 新增联系方式
peter_contact = dict(phone='13238985676', email='peter@example.com')
john_contact = dict(phone='18034567890', email='john@example.com')
# peter
Student.objects(stu_id=101).update_one(set__contact=peter_contact, upsert=True)
# john
Student.objects(stu_id=102).update_one(set__contact=john_contact, upsert=True)
def search_data():
""" 查找数据 """
# 查找全部
result_all = Student.objects().all()
print "count of all records is : ", result_all.count()
# 查找 stu_id 为 101 的学生
result_1 = Student.objects(stu_id=101).first()
print "result_1.name is : ", result_1.name
print "result_1.gender is : ", result_1.gender
# 查找性别为男, 手机号为 18034567890, 注意用双下划线
result_2 = Student.objects(gender='male', contact__phone='18034567890').first()
print "result_2.name is : ", result_2.name
# 查找年龄大于 25, 注意用双下划线
result_3 = Student.objects(age__gt=25).all()
for element in result_3:
print element.name
def delete_data():
""" 删除数据 """
# 删除 stu_id 为 101 的联系方式, 注意用双下划线
Student.objects(stu_id=101).update(unset__contact=1)
if __name__ == '__main__':
# 连接数据库 'people', 没有则创建
connect('people', host='127.0.0.1', port=27017)
insert_data()
update_data()
search_data()
delete_data()
|
常用查询操作符
- gt 大于,如
Student.objects(age__gt=18)
- gte 大于等于
- ne 不等于
- lt 小于
- lte 小于等于
- mod 取模
- not 取反,用在其他操作符前面,如
Student.objects(age__not__mod=5)
- in 值在列表中,如
Blog.objects(authors__in=[peter, john])
- nin 值不在列表中
- all 与列表的值相同,如
Blog.objects(authors__all=[peter, john])
- size 数组的大小
- exists 字段是否存在,如
Student.objects(age__exists=1)
高级查询
有时我们需要进行 与查询
和 或查询
,也就是对多个条件进行查询,这时可以使用 MongoEngine 的 Q 类 (Q class)
1
2
3
4
5
6
7
8
|
from mongoengine.queryset.visitor import Q
# 查找性别为男, 且手机号为 18034567890 的记录
result = Student.objects(Q(gender='male') & Q(contact__phone='18034567890'))
# 查找性别为男, 或者手机号为 18034567890 的记录
result = Student.objects(Q(gender='male') | Q(contact__phone='18034567890'))
# 查找性别为男, 且手机号为 18034567890 的记录 或者 性别为女的记录
result = Student.objects((Q(gender='male') & Q(contact__phone='18034567890')) | Q(gender='female'))
|
常用更新操作符
这里我们以一个 Blog
的文档为例,定义如下:
1
2
3
4
|
class Blog(Document):
title = StringField()
authors = ListField()
content = StringField()
|
set
设置某个值,如 Blog.objects(id=...).update_one(set__title='my first blog')
unset
删除某个值
push
将某个值添加到列表中,如 Blog.objects(id=...).update_one(push__authors='john')
push_all
将某些值添加到列表中
pull
将某个值从列表移除,如 Blog.objects(id=...).update_one(pull__authors='john')
pull_all
将某些值从列表移除
add_to_set
当某个值不在列表中的时候,将其添加到列表,如果存在则不添加,如
Blog.objects(id=...).update_one(add_to_set__authors='john')
连接多个数据库
假设有两个数据库 people
和 course
,定义如下的两个文档模式:
1
2
3
4
5
6
7
8
9
10
|
class Student(DynamicDocument):
meta = {
'db_alias': 'people-db',
'collection': 'student',
'strict': False
}
stu_id = IntField()
age = IntField()
name = StringField()
gender = StringField()
|
1
2
3
4
5
6
7
8
9
|
class Math(DynamicDocument):
meta = {
'db_alias': 'course-db',
'collection': 'math',
'strict': False
}
math_id = IntField()
math_name = StringField()
teacher = StringField()
|
如果要连接这两个数据库,可以这么使用:
1
2
3
4
5
6
7
8
9
10
|
# -*- coding: utf-8 -*-
if __name__ == '__main__':
# 连接数据库 people
register_connection('people-db', 'people')
# 连接数据库 course
register_connection('course-db', 'course')
math_records = Math.objects().all()
student_records = Student.objects().all()
|
参考资料