2016-10-30 3 views
1

Zuerst die aktuellen Zustand: Es gibt eine ZF2-Anwendung mit einem Formular. Das Formular enthält einige Autovervollständigungsfelder (implementiert auf der Frontend-Seite mit jQuery Autocomplete).Wie wird das serverseitige Caching für die automatische Vervollständigung in einer ZF2-Anwendung realisiert?

Die SQL-Anweisungen dahinter wie folgt aussehen:

SELECT name FROM countries WHERE countries.name LIKE %en% 
-> should find "Arg[en]tina", "Arm[en]ia", "B[en]in", "Turkm[en]istan" etc. 
or 
SELECT name FROM countries WHERE countries.continent_id = 2 
-> should find "Afghanistan", "Armenia", "Azerbaijan" etc. (2 = Asia) 
or 
SELECT name FROM countries WHERE countries.continent_id = 2 AND countries.name LIKE %en% 
-> should find "Arm[en]ia", "Turkm[en]istan" etc. (2 = Asia) 

Natürlich führt es zu dem Problem , dass die Datenbank von vielen kleinen Anfragen zur automatischen Vervollständigung terrorisiert wird. Caching sollte helfen - und ich habe bereits damit begonnen, einen Zend\Cache\Storage\Adapter\Apcu-basierten Caching-Mechanismus zu implementieren. Aber dann sah ich das nächste Problem: Mit einem gemeinsamen Cache wie APCu kann ich die Ergebnisse nicht dynamisch filtern. Ein solcher Cache scheint also für einen Fall mit Autocomplete nicht zu funktionieren.

Ich bin mir ziemlich sicher, dass es ein häufiges Problem ist und es bereits eine Lösung dafür gibt.

Wie realisiert man einen Caching-Mechanismus in einer ZF2-Anwendung für die Autocomplete-Funktionalität?

Antwort

0

Hier ist nichts mit dem ZF2 zu tun. Hier geht es um ein benutzerdefiniertes Suchdienstdesign und seine Herausforderungen.

Ohne eine ordnungsgemäße Caching-Layer und/oder Volltext-Suchmaschine, Erstellen einer Autocomplete-Implementierung so wäre dies Selbstmord für die Anwendung. Sie können leicht Zehntausende von unnötigen wiederholten Abfragen in einer sehr kurzen Zeit erreichen.

In einer "idealen" Welt verwendet eine gute Autocomplete-Implementierung eine Volltext-Suchmaschine unter der Haube wie Elasticsearch oder Apache Solr. Und verwendet ihre Completion Suggester und Suggester Komponenten jeweils.

Wie dem auch sei, eine einfache Autokomplettierungsfunktion, die nur mit einem Objektcache und einer Datenbank erreichbar ist. Sie brauchen nur eine Hilfsmethode, um einen richtigen "Cache-Schlüssel" für die einzelnen Buchstabenkombinationen zu erstellen. Zum Beispiel:

function createKeyByQuery($str) 
    { 
     return 'autocomplete-prefix-'.(string) $str; 
    } 

und in Ihrer suggest() Methode:

public function suggest($keyword) 
    { 
     $key = $this->createKeyByQuery($keyword); 
     if($this->cache->hasItem($key)) { 
      return $this->cache->getItem($key); 
     } 

     // fetch form the database here 
     $data = $this->db->query(); 
     $this->cache->setItem($key, $data); 

     return $data; 
    } 

Wenn die Zählung Ihrer Filter nicht zu viel, machen sie nur einen Teil der zu drücken. In diesem Szenario würde die Unterschrift der vorschlagen Methode:

public function suggest($keyword, array $filters = []); 

und Schlüsselgenerator benötigt ein Update:

function createKeyByQuery($str, array $filters = []) 
    { 
     return 'autocomplete-prefix-' . (string) $str . md5(serialize($filters)); 
    } 

Diese Lösung nicht geeignet für die komplizierte/Domain kann Daten im Zusammenhang, weil es eine recht hat große Entwertung Herausforderung. Z.B. Wie würden Sie die Cache-Schlüssel finden, die das "Argentinien" in der Nutzlast enthält?

Da Sie nur mit der Liste der Länder und Kontinente als Filter arbeiten, sollte es das Problem lösen.

Für das Schlüsselwort england und zwei verschiedene Filter mit insgesamt 10 Filteroptionen wird es 10x2x7 = 140 unterschiedliche Cache-Schlüssel geben. Für einen einzelnen Filter mit 5 Optionen, 5x1x7 = 37 verschiedene Schlüssel.

APCu ist eine gute Wahl für diese Implementierung.

Ich hoffe, es hilft.

Verwandte Themen