2016-11-15 5 views
1

Wenn ich zwei Objekte wie:wie mongoengine beschleunigen Abfragen

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

und wenn ich will, die folgende Bedingung sehen, wo es nicht verborgen ist, und sein Besitzer ist jemand, den ich folgende bin und es war vor kurzem Posted, ich habe eine Abfrage wie folgt:

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

die nicht Skalierung und wird viel langsamer. Was kann ich tun, um die Leistung dieser Art von komplexen Abfragen zu beschleunigen?

Antwort

1

1) Verwenden Sie User.objects.get(id=user_id) anstelle von first(). Tough ich bin nicht wirklich sicher, ob das einen Unterschied machen wird, denke ich, und das ist eine find Operation, wo MongoDB einen Cursor zurückgibt und Mongoengine zum ersten Dokument iteriert. Stattdessen macht get() eine findOne und gibt nur 1 Dokument zurück. Wenn ich mich irre, sollte mich jemand bitte korrigieren.

2) Verwenden Sie einen compound index (nicht mehrere einzelnen Index), da Ihre Abfrage mehr Felder (zB here also) mit:

meta = { 
      'indexes': [ 
       ('owner', 'posted_date', 'is_hidden',) 
      ] 
     } 

3) Grenzdaten nur auf die Felder zurückkehren Sie benötigen, project your fields, only() mit

Verwenden Sie explain() auf Ihre Abfrage, um es zu verbessern und es zu verbessern, um eine covered query zu erreichen.

1

Wenn Sie mongoengine in der Produktion zu verwenden, um mit großen Dokumenten einen Blick auf dieses Thema nehmen: https://github.com/MongoEngine/mongoengine/issues/1230

Wir mongoengine verwendet haben, aber es wurde wirklich langsam aus dem Grund, erklärt in der Post oben.

Wir haben unser gesamtes Backend umgeschrieben mit https://github.com/mongodb/pymodm Das ist ein relativ neues Projekt für das mongodb Team. Wir verwenden es mit Django und es arbeitet viel schneller als Mongoengine mit genau der gleichen Datenbank.