如果我有两个对象,如:
class User(Document):
name = StringField()
following = ListField(ReferenceField('User'))
meta = {
'indexes': [
'following',
]
}
class Media(Document):
owner = ReferenceField('User')
url = StringField()
is_hidden = BooleanField()
posted_date = Date
meta = {
'indexes': [
'owner',
'posted_date',
'is_hidden',
]
}
当我想查看以下条件时,它没有被隐藏,它的所有者是我关注的人,并且最近发布了,我有这样的查询:
user = User.objects.first()
Media.objects(Q(owner__in=user.following) &
Q(is_hidden=False) &
Q(posted_date__gte=dt.now()-dt.timedelta(days=3))
这不是缩放,而且变得慢得多。我该怎么做才能加快这些类型的复杂查询的性能?
答案 0 :(得分:1)
1)使用User.objects.get(id=user_id)
代替first()
。
很难,我不确定这是否有所作为,我认为是,这是一个find
操作,其中MongoDB将返回一个游标并且mongoengine迭代到第一个文档。相反,get()
正在执行findOne
并且只返回1个文档。如果我弄错了,请有人纠正我。
2)使用compound index(不是多个索引),因为您的查询使用多个字段(例如here also):
meta = {
'indexes': [
('owner', 'posted_date', 'is_hidden',)
]
}
将返回的数据限制为只需要only()
所需的字段
在您的查询上使用explain()对其进行规划并在oder中进行改进以达到covered query。
答案 1 :(得分:1)
如果您打算在制作大型文档的情况下使用mongoengine,请查看以下帖子:https://github.com/MongoEngine/mongoengine/issues/1230
我们使用的是mongoengine,但由于上述帖子中解释的原因,它变得非常慢。
我们最终使用https://github.com/mongodb/pymodm重写了整个后端 对于mongodb团队来说,这是一个相对较新的项目。我们正在将它与Django一起使用,它的工作速度比mongoengine快得多,而且数据库完全相同。