如何加快mongoengine查询速度

时间:2016-11-15 19:57:14

标签: python mongodb mongodb-query mongoengine

如果我有两个对象,如:

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))

这不是缩放,而且变得慢得多。我该怎么做才能加快这些类型的复杂查询的性能?

2 个答案:

答案 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',)
            ]
        }

3)使用project your fields

将返回的数据限制为只需要only()所需的字段

在您的查询上使用explain()对其进行规划并在oder中进行改进以达到covered query

答案 1 :(得分:1)

如果您打算在制作大型文档的情况下使用mongoengine,请查看以下帖子:https://github.com/MongoEngine/mongoengine/issues/1230

我们使用的是mongoengine,但由于上述帖子中解释的原因,它变得非常慢。

我们最终使用https://github.com/mongodb/pymodm重写了整个后端 对于mongodb团队来说,这是一个相对较新的项目。我们正在将它与Django一起使用,它的工作速度比mongoengine快得多,而且数据库完全相同。