首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在ZF2应用程序中实现自动完成的服务器端缓存?

问如何在ZF2应用程序中实现自动完成的服务器端缓存?
EN

Stack Overflow用户
提问于 2016-10-30 19:32:42
回答 1查看 180关注 0票数 1

首先是实际状态:有一个带有表单的ZF2应用程序。表单包含一些自动完成字段(在前端用jQuery自动完成实现)。

它后面的SQL语句如下所示:

代码语言:javascript
复制
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-based缓存机制了。但是,我看到了下一个问题:使用像APCu这样的公共缓存,我不能动态地过滤结果。因此,这样的缓存似乎不适用于使用自动完成的情况。

我很肯定,这是一个常见的问题,而且已经有了解决办法。

如何在ZF2应用程序中实现自动完成功能的缓存机制?

EN

回答 1

Stack Overflow用户

发布于 2016-10-30 23:54:06

这里与ZF2没有任何关系。这都是一个定制的搜索服务设计,它的挑战。

如果没有适当的缓存层和/或全文搜索引擎,构建一个自动完成的实现对应用程序来说将是一种自杀。您可以很容易地在很短的时间内完成成千上万不必要的重复查询。

在“理想”世界中,一个好的自动完成实现利用了一个隐藏的全文搜索引擎,比如弹性搜索或阿帕奇索尔。并分别使用它们的完形暗示器和暗示者组件。

无论如何,一个简单的自动完成功能仍然可以使用对象缓存和数据库实现。唯一需要的是一个帮助方法来为每个字母组合创建一个正确的“缓存键”。例如:

代码语言:javascript
复制
   function createKeyByQuery($str)
   {
      return 'autocomplete-prefix-'.(string) $str;
   }

在您的suggest()方法中:

代码语言:javascript
复制
   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;
   }

如果你的过滤器数量不多,那就让它们也成为关键的一部分。在这种情况下,建议方法的签名将是:

代码语言:javascript
复制
  public function suggest($keyword, array $filters = []);

密钥生成器需要更新:

代码语言:javascript
复制
   function createKeyByQuery($str, array $filters = [])
   {
      return 'autocomplete-prefix-' . (string) $str . md5(serialize($filters));
   }

这个解决方案可能不适合于复杂的/领域相关的数据,因为它有一个相当大的无效挑战。例如:如何在有效载荷中找到存放“阿根廷”的缓存密钥?

因为你只处理名单的国家和大陆作为过滤器,它应该解决问题。

对于england关键字和共有10个筛选器选项的两个不同的过滤器,将有10x2x7 =140个不同的缓存键。对于具有5选项的单个筛选器,5x1x7 =37个不同的键。

APCu是此实现的一个很好的选择。

希望能帮上忙。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40332779

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档