2016-11-15 101 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快得多。