2016-10-30 8 views
1

最初実際の状態:フォームを持つZF2アプリケーションがあります。フォームにはいくつかのオートコンプリートフィールドが含まれています(フロントエンド側にjQuery Autocompleteで実装されています)。その背後にあるZF2アプリケーションでオートコンプリート用のサーバーサイドキャッシングを実現するにはどうすればよいですか?

SQL文は次のようになります。もちろん

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) 

を、それがデータベースが小さなオートコンプリートリクエストの多いことで恐怖されることを、問題につながります。キャッシングが助けになるでしょう - そして私はすでにZend\Cache\Storage\Adapter\Apcuベースのキャッシングメカニズムを実装し始めました。しかし、次のトラブルが発生しました。​​のような共通のキャッシュを使用すると、結果を動的にフィルタリングできません。だから、このようなキャッシュはオートコンプリートの場合には機能しないようです。

私はそれが一般的な問題であり、すでにこれに対する解決策があると確信しています。

オートコンプリート機能のZF2アプリケーションでキャッシュメカニズムを実現するにはどうすればよいですか?

答えて

0

ここではZF2とは関係ありません。これはすべてカスタム検索サービスの設計に関するものであり、その課題です。

適切なキャッシングレイヤーやフルテキスト検索エンジンがないと、このようなオートコンプリート実装を構築することはアプリケーションにとって自殺につながります。非常に短時間で何千もの不必要に繰り返されるクエリを簡単に達成することができます。

"理想的な"世界では、良いオートコンプリートの実装では、ElasticsearchまたはApache Solrなどのフードのフルテキスト検索エンジンを使用します。それぞれCompletion SuggesterSuggesterのコンポーネントを使用します。

とにかく、単純なオートコンプリート機能は、オブジェクトキャッシュとデータベースのみを使用しても実現できます。必要なのは、すべての文字の組み合わせに対して適切な "キャッシュキー"を作成するヘルパーメソッドだけです。たとえば、次のように

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

とあなたのsuggest()方法で:

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; 
    } 

あなたのフィルタの数があまりない場合は、ちょうどそれらあまりにもキーの一部にします。このシナリオでは、提案するメソッドのシグネチャは次のようになります。

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

とキージェネレータは、更新が必要です。

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

このソリューションは、複雑な/ドメイン関連のデータのために適切ではないかもしれそれはかなりを持っているので、大きな無効化チャレンジ。例えば。ペイロードに "Argentina"を保持するキャッシュキーを見つけるにはどうすればよいですか?

フィルタとして国と大陸のリストだけを扱っているので、問題を解決するはずです。

englandキーワードと合計10個のフィルタオプションを持つ2つの異なるフィルタの場合、10x2x7 = 140個の異なるキャッシュキーが存在します。 5つのオプションを持つ単一のフィルターの場合、5x1x7 = 37個の別個のキー。

この実装にはAPCuが適しています。

希望します。

関連する問題