2009-08-25 23 views
5

Tengo un gran conjunto de datos (más de mil millones de filas). Los datos están divididos en la base de datos por fecha. Como tal, mi herramienta de consulta DEBE especificar una cláusula SQL entre cada consulta, o tendrá que escanear cada partición ... y bueno, se agotó el tiempo de espera antes de que vuelva a aparecer.Modelo CakePHP con "Entre fechas"

Así que .. mi pregunta es, en el campo de la eso de base de datos particionada es una fecha ..

con CakePHP, ¿cómo puedo especificar "entre" las fechas en mi formulario?

Estaba pensando en hacer "start_date" y "end_date" en el formulario en sí, pero esto puede hacerme una segunda pregunta ... ¿cómo lo valido en un modelo que está vinculado a una tabla?

Respuesta

0

Se puede escribir un método personalizado en su modelo para buscar entre las fechas:

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

En cuanto a la validación, se puede usar beforeValidate() devolución de llamada del modelo para validar las dos fechas. Más información sobre esto 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(); 
} 

¿Eso responde su pregunta?

8

Si te estoy siguiendo correctamente:

  • El usuario debe especificar fechas de inicio/finalización para encontrar las consultas generadas a partir de una forma
  • Es necesario validar estas fechas de manera que, por ejemplo:
    • fecha de finalización después de la fecha de inicio
    • fecha de finalización no siglos de distancia de la fecha de inicio
  • desea que los errores de validación aparecen en línea dentro de la forma (a pesar de que esto no es una salvación)

Desde desea validar estas fechas van a ser más difíciles de agarrar cuando se encuentran escondidos dentro de su gama condiciones. Sugiero tratando de pasar éstos por separado y luego tratar con ellos más adelante:

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

Si todo funciona correctamente será capaz de manejar todo lo demás en el beforeFind filtro:

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; 
} 

no he intentado usar Model::invalidate() durante una operación de búsqueda, por lo que esto podría no funcionar. La idea es que si el formulario se crea usando FormHelper, estos mensajes deben volver al lado de los campos del formulario.

Si falla, es posible que deba realizar esta validación en el controlador y usar Session::setFlash(). Si es así, también puede deshacerse del beforeFind y poner el conjunto de condiciones BETWEEN con sus otras condiciones.

1

si desea encontrar los últimos 20 días de datos.

$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'))); 

de otra forma entre dos fechas

$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) 
Cuestiones relacionadas