具有"日期之间"的CakePHP模型

5 mysql cakephp date

我有一个大型数据集(超过十亿行).数据按日期在数据库中分区.因此,我的查询工具必须在每个查询中指定一个SQL between子句,否则它将必须扫描每个分区..而且,它会在它返回之前超时.

所以..我的问题是,分区数据库中的字段是一个日期..

使用CakePHP,如何在表单中指定"之间"日期?

我正在考虑在表单中执行"start_date"和"end_date",但这可能会给我带来两个问题..如何在链接到表的模型中验证?

dei*_*zel 8

如果我正确地关注你:

  • 用户必须指定从表单生成的查找查询的开始/结束日期
  • 您需要验证这些日期,例如:
    • 开始日期后的结束日期
    • 结束日期距离开始日期不远
  • 您希望验证错误在表单中内联出现(即使这不是保存)

由于您要验证这些日期,因此当它们隐藏在条件数组中时,它们将更难获取.我建议尝试单独传递这些,然后再处理它们:

$this->Model->find('all', array(
    'conditions' => array(/* normal conditions here */),
    'dateRange' => array(
        'start' => /* start_date value */,
        'end'   => /* end_date value */,
    ),
));
Run Code Online (Sandbox Code Playgroud)

您应该希望能够处理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;
}
Run Code Online (Sandbox Code Playgroud)

我没有尝试Model::invalidate()在查找操作期间使用,所以这可能甚至不起作用.我们的想法是,如果使用FormHelper这些消息创建表单,则应将其返回到表单字段旁边.

如果做不到这一点,您可能需要在控制器中执行此验证并使用Session::setFlash().如果是这样,你也可以摆脱beforeFind并将BETWEEN条件数组放入其他条件.


ink*_*dmn 0

您可以在模型中编写自定义方法来在日期之间进行搜索:

function findByDateRange($start,$end){
    return $this->find('all',array('date >= '.$start,'data >= .'$end));
}
Run Code Online (Sandbox Code Playgroud)

至于验证,您可以使用模型的beforeValidate()回调来验证两个日期。有关此的更多信息,请参见此处

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();
}
Run Code Online (Sandbox Code Playgroud)

这是否回答你的问题?