python mongoengine基本使用

model设定

在mongoengine里,如果想要多个嵌入Document组成的list,应该写成:

1
2
attribute = EmbeddedDocumentListField(YourEmbeddedDocument)
而不应该再在中间写EmbeddedDocumentField,因为这只是单个嵌入Document的写法。

查询

给定数据类型document,查询单个对象:
document.objects(foo=bar)[0]

不过更推荐这么干:
oneObject = document.objects.get(foo=bar)
但是这么干的话,在条件返回多个对象的时候会报错。如果仅是想要第一个结果,可以使用
oneObject = document.objects(foo=bar).first()

想在查询单个对象后进行修改并保存,如$set的使用,
oneObject.update(set__foo=bar) # 这里set就相当于$set,所有原子操作都应该是这个格式

嵌套查询:比如有model:(以下不是合法语法,仅作为示例)Father.son=ReferenceField(Son);Son.age=IntField(),我们想要查询有一个多少岁的儿子的father,可以这么干:
father = Father.objects.filter(son__age=18) # 这个写法是固定的

在ReferenceField的查询里,通常指定原来属性即可。例如:class Father有一个属性son = ReferenceField(Person),那么我们拿到一个实例Person1的时候,要找到有Person1作为son的Father,写法为:
father = Father.objects(son=Person1) # 这样就可以了,剩下的事情mongoengine自然做了

查出来之后想要只取某个字段的值,使用only:
oneObject = document.objects(foo=bar).only('attribute')

同理,也可以使用except来达到only相反的效果。

在查表的时候,有与、或的逻辑没法处理的时候,可以使用Q类。

修改

在对mongoengine的某个ReferenceField做传值的时候,直接传字符串修改就可以了,不必将对象拿到再赋值。
但是这一条对判断是不行的,比如要判断ReferenceField里的_id和给定字符串相不相同,还是需要拿属性,比如:

1
2
3
4
5
6
7
8
class C(Document):
oid = StringField()

class D(Document):
ref = ReferenceField(C)

# 判断D里C的oid和给定字符串"tt"是否相等
D.ref.oid == 'tt' # 而不是D.ref == 'tt'

对于给定文档Doc,如果要删除它的某个属性attr,就要:
Doc.update(unset__attr=True)

删除

oneObject.delete() # 其中oneObject已经是一个文档对象了

sequencefield

自增的field,其使用一般在oid中。如果在schema中加上了value_decorator,那么在查找的时候也需要对decorator处理之后的id反向处理变成自增序号,如:
object = datamodel.document(oid=reverseDealing(outsideValue))

然而在其读取的时候,这个id是经value_decorator处理之后得到的,不是自增的序号,如:
object.oid # 这个值不是自增序号,而是value_decorator(自增序号)