2

我正在使用 CakePHP 2.0 开发一个搜索引擎,并且很难找到最有效的方法来获得我想要的结果。

假设我正在查询人,我得到一组 20 个结果,其中 5 个 20 岁、10 个 30 岁和 5 个 40 岁。此外,其中 15 个人的眼睛是棕色的,3 个是蓝色的,2 个是绿色的。我想找到获得这些特定计数的最有效方法。然后,我将在页面上显示这些结果,以便用户可以使用这些参数查看结果中的内容。然后,他们将能够单击其中一个以将该搜索参数添加到当前查询中。

这根本不是我可以存储在数据库或缓存中的东西,因为每次搜索都可能不同,并且可能/将返回不同的结果。

如果我没有解释我正在尝试做什么(这很可能),那么有几个网站可以做到这一点。Cars.com 在搜索汽车时使用此方法。您搜索通用搜索,然后侧面的链接可让您缩小结果范围。这些链接包括属于特定参数的当前结果集的计数。

一个想法是获取完整的结果集,然后通过它解析生成计数,这会起作用,但在我的特定项目中,我正在处理数千条记录,看起来这可能会增加页面的加载时间和/或对服务器造成压力。

这是一个视觉示例: 我试图实现的问题/结果的视觉示例

4

1 回答 1

2

Cars.com 可能会为每个计数的功能使用关联标签。带有关联标签的表记录有许多并且属于许多特征标签。

这样他们就不必为每辆汽车的价格创建标签。他们创建价格范围标签。

对于每条汽车记录,都有关联的标签记录,其中包含该汽车的所有功能。然后,您可以在标签记录中缓存具有该功能的汽车数量。

SQL 表结构可能是这样的。

 CREATE TABLE `cars` (
   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
   `make` varchar(45) DEFAULT NULL,
   `model` varchar(45) DEFAULT NULL,
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

 CREATE TABLE `features` (
   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
   `name` varchar(45) DEFAULT NULL,
   `count` int(11) NOT NULL DEFAULT '0',
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

 CREATE TABLE `cars_features` (
   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
   `car_id` int(11) NOT NULL,
   `feature_id` int(11) NOT NULL,
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

对于每个 Car 记录,可以有多个 Fe​​ature 记录。这些通过 cars_features 表与每辆汽车相关联。当有人搜索并找到汽车 XXXX 时,您可以查找该汽车的功能,并显示缓存的有多少汽车具有该功能的计数。

编辑:

缩小计数范围,使其仅限于在搜索中发现的汽车。您需要首先获取所有汽车 ID 的列表,然后使用 cars_features 表和功能之间的 JOIN 执行 COUNT。

这是一些示例数据。

  INSERT INTO `cars` (`make`, `model`) VALUES ('Ford', 'Explorer');
  INSERT INTO `cars` (`make`, `model`) VALUES ('Hond', 'Civic');
  INSERT INTO `cars` (`make`, `model`) VALUES ('Hond', 'Civic');

  INSERT INTO `features` (`name`, `count`) VALUES ('Red', 2);
  INSERT INTO `features` (`name`, `count`) VALUES ('Green', 1);

  INSERT INTO `cars_features` (`car_id`, `feature_id`) VALUES (1, 1);
  INSERT INTO `cars_features` (`car_id`, `feature_id`) VALUES (2, 1);
  INSERT INTO `cars_features` (`car_id`, `feature_id`) VALUES (3, 2);

假设我们搜索返回了两个项目,因此我们的汽车 ID 为 (1,2)。我们可以使用以下 SQL 查询找到特征计数。

 SELECT `features`.`id`,COUNT(`features`.`id`)
     FROM `cars_features` 
     JOIN `features` ON (`cars_features`.`feature_id`=`features`.`id`)
     WHERE `cars_features`.`car_id` IN (1,2)
     GROUP BY `features`.`id`

这将报告每个功能的计数仅限于找到的汽车记录。

我将尝试以 CakePHP 模型格式编写以上内容。

 $this->CarFeature->find('all',array(
    'conditions'=>array('CarFeature.car_id'=>$ids),
    'fields'=>array('Feature.id','COUNT(Feature.id)'),
    'group'=>array('Feature.id'),
    'contain'=>'Feature'
 ));
于 2013-01-14T22:17:41.783 回答