我正在使用CakePHP 2.0开发搜索引擎,并且很难找到最有效的方法来获得我想要的结果。
说我在询问人,我得到20个结果,其中5岁20岁,10岁30岁,5岁40岁。此外,这些人中有15人有棕色眼睛,3人有蓝色,2人有绿色。我想找到最有效的方法来获得这些特定的计数。然后,我将在页面上显示这些结果,以便用户可以使用这些参数查看结果中的内容。然后,他们可以单击其中一个将该搜索参数添加到当前查询中。
这根本不能存储在数据库或缓存中,因为每次搜索都可能不同,可能/会返回不同的结果。
如果我没有解释我正在尝试做什么(这很可能),有几个网站可以做到这一点。 Cars.com在搜索汽车时使用此方法。您搜索通用搜索,然后侧面的链接允许您缩小搜索范围。这些链接包括属于特定参数的当前结果集的计数。
一个想法是获取完整的结果集,然后通过它解析生成计数,这将工作,但在我的具体项目中,我正在处理成千上万的记录,似乎这可能会增加额外的加载时间服务器上的页面和/或压力。
这是一个直观的例子:
答案 0 :(得分: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记录,可以有多个功能记录。这些通过cars_features表与每辆车相关联。当有人搜索并找到Car XXXX时,您可以查找该车的功能,并显示有多少辆车具有该功能的缓存计数。
修改强>
缩小计数范围,使其仅限于搜索中发现的汽车。您需要首先获取所有Car 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`
这将报告每个功能的计数仅限于找到的Car记录。
我将尝试以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'
));