2016-11-15 65 views
1

如果我有两个对象,如:如何加快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)) 

这是不缩放,变得更慢。我能做些什么来加快这些复杂查询的性能?

回答

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()来styudy它并在oder中改进它以达到covered query

1

如果你打算使用mongoengine在生产中使用大型文档在这篇文章看看:https://github.com/MongoEngine/mongoengine/issues/1230

我们使用mongoengine但它成为的原因很慢在后解释以上。

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