1

まずは実態:フォーム付きのZF2アプリがあります。フォームにはいくつかのオートコンプリート フィールドが含まれています ( jQuery Autocompleteを使用してフロントエンド側に実装されています)。

その背後にある 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基づくキャッシング メカニズムの実装を開始しています。しかし、次の問題が発生しました。APCuのような一般的なキャッシュを使用すると、結果を動的にフィルター処理できません。したがって、このようなキャッシュは、オートコンプリートの場合には機能しないようです。

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

オートコンプリート機能のために ZF2 アプリケーションでキャッシュメカニズムを実現する方法は?

4

1 に答える 1

0

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

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

「理想的な」世界では、適切なオートコンプリートの実装では、内部でElasticsearchApache Solrなどの全文検索エンジンを利用します。また、Completion SuggesterおよびSuggesterコンポーネントをそれぞれ使用します。

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

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

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

  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 つのオプションを持つ 1 つのフィルターの場合、5x1x7 = 37 個の個別のキー。

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

それが役に立てば幸い。

于 2016-10-30T23:54:06.660 に答える