2016-10-30 10 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 기반 캐싱 메커니즘을 구현하기 시작했습니다. 하지만 다음 문제가 생겼습니다. 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)); 
    } 

이 꽤 있기 때문에이 솔루션은 복잡한/도메인에 적합하지 관련 데이터를 수 큰 무효화 도전. 예 : 페이로드에서 "아르헨티나"를 보유하고있는 캐시 키를 찾는 방법은 무엇입니까?

국가 및 대륙 목록 만 필터로 다루기 때문에 문제가 해결됩니다.

england 키워드와 총 10 개의 필터 옵션이있는 2 개의 다른 필터의 경우 10x2x7 = 140 개의 고유 한 캐시 키가 있습니다. 5 개의 옵션이있는 단일 필터의 경우, 5x1x7 = 37 개의 별개 키.

APCu는이 구현에 적합한 선택입니다.

희망이 있습니다.