我有一个大型数据集(超过十亿行)。数据按日期在数据库中分区。因此,我的查询工具必须在每个查询中指定一个SQL between子句,否则它将必须扫描每个分区..而且,它会在它返回之前超时。
所以..我的问题是,分区数据库中的字段是日期..
使用CakePHP,如何在表单中指定“之间”日期?
我正在考虑在表单中执行“start_date”和“end_date”,但这可能会给我带来两个问题..如何在链接到表的模型中验证它?
答案 0 :(得分:8)
如果我正确地关注你:
由于您要验证这些日期,因此当它们隐藏在条件数组中时,它们将更难获取。我建议尝试单独传递这些内容,然后再处理它们:
$this->Model->find('all', array(
'conditions' => array(/* normal conditions here */),
'dateRange' => array(
'start' => /* start_date value */,
'end' => /* end_date value */,
),
));
您应该能够处理beforeFind
过滤器中的所有其他内容:
public function beforeFind() {
// perform query validation
if ($queryData['dateRange']['end'] < $queryData['dateRange']['start']) {
$this->invalidate(
/* end_date field name */,
"End date must be after start date"
);
return false;
}
/* repeat for other validation */
// add between condition to query
$queryData['conditions'][] = array(
'Model.dateField BETWEEN ? AND ?' => array(
$queryData['dateRange']['start'],
$queryData['dateRange']['end'],
),
);
unset($queryData['dateRange']);
// proceed with find
return true;
}
我在搜索操作期间没有尝试使用Model::invalidate()
,所以这可能甚至不起作用。我们的想法是,如果使用FormHelper
创建表单,这些消息应该在表单字段旁边返回。
如果失败,您可能需要在控制器中执行此验证并使用Session::setFlash()
。如果是这样,你也可以摆脱beforeFind
并将BETWEEN
条件数组与其他条件放在一起。
答案 1 :(得分:1)
如果您想查找过去20天的数据。
$this->loadModel('User');
//$this->User->recursive=-1;
$data=$this->User->find('all', array('recursive' => 0,
'fields' => array('Profile.last_name','Profile.first_name'),'limit' => 20,'order' => array('User.created DESC')));
两个日期之间的其他明智
$start = date('Y-m-d') ;
$end = date('Y-m-d', strtotime('-20 day'));
$conditions = array('User.created' =>array('Between',$start,$end));
$this->User->find("all",$conditions)
答案 2 :(得分:0)
您可以在模型中编写自定义方法,以便在日期之间进行搜索:
function findByDateRange($start,$end){
return $this->find('all',array('date >= '.$start,'data >= .'$end));
}
就验证而言,您可以使用模型的beforeValidate()
回调来验证这两个日期。有关此here的更多信息。
function beforeValidate(){
if(Validation::date($this->data['Model']['start_date'])){
return false;
}
if(Validation::date($this->data['Model']['end_date'])){
return false;
}
return parent::beforeValidate();
}
这会回答你的问题吗?