2009-08-25 27 views
5

Tôi có một tập dữ liệu lớn (hơn một tỷ hàng). Dữ liệu được phân đoạn trong cơ sở dữ liệu theo ngày. Như vậy, công cụ truy vấn của tôi PHẢI chỉ định một mệnh đề SQL giữa mỗi truy vấn, hoặc nó sẽ phải quét mọi phân vùng .. và tốt, nó sẽ hết thời gian chờ trước khi nó trở lại.Mô hình CakePHP có "Giữa các ngày"

Vì vậy .. câu hỏi của tôi là, lĩnh vực trong thats cơ sở dữ liệu phân vùng là một ngày ..

Sử dụng CakePHP, làm thế nào tôi có thể xác định "giữa" ngày dưới hình thức của tôi?

Tôi đã suy nghĩ về việc "start_date" và "end_date" trong biểu mẫu, nhưng điều này có thể mang lại cho tôi hai câu hỏi thứ hai .. làm cách nào để xác thực trong mô hình được liên kết với bảng?

Trả lời

0

Bạn có thể viết một phương pháp tùy chỉnh trong mô hình của bạn để tìm kiếm giữa các ngày:

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

Theo như xác nhận, bạn có thể sử dụng beforeValidate() callback của mô hình để xác nhận hai ngày. Thông tin thêm về điều này 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(); 
} 

Điều đó có trả lời câu hỏi của bạn không?

8

Nếu tôi sau bạn một cách chính xác:

  • Người dùng phải chỉ định bắt đầu/ngày kết thúc để tìm các truy vấn được tạo ra từ một hình thức
  • Bạn cần phải xác nhận những ngày này sao cho, ví dụ:
    • ngày kết thúc sau ngày bắt đầu
    • ngày kết thúc không nhiều thế kỷ xa ngày bắt đầu
  • Bạn muốn các lỗi xác thực xuất hiện bên trong biểu mẫu (mặc dù đây không phải là sự lưu)

Vì bạn muốn xác thực những ngày này, chúng sẽ khó lấy khi chúng được giấu trong mảng điều kiện của bạn. Tôi đề nghị cố gắng để vượt qua những ở riêng biệt và sau đó đối phó với chúng sau:

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

Bạn hy vọng sẽ có thể xử lý mọi thứ khác trong beforeFind lọc:

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

tôi đã không cố gắng sử dụng Model::invalidate() trong một hoạt động tìm kiếm, vì vậy điều này có thể thậm chí không hoạt động. Ý tưởng là nếu biểu mẫu được tạo bằng cách sử dụng FormHelper, những thông báo này sẽ làm cho nó trở lại bên cạnh các trường biểu mẫu.

Nếu không, bạn có thể cần thực hiện xác thực này trong bộ điều khiển và sử dụng Session::setFlash(). nếu có, bạn cũng có thể loại bỏ beforeFind và đặt mảng điều kiện BETWEEN với các điều kiện khác của bạn.

1

nếu bạn muốn tìm dữ liệu 20 ngày qua.

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

khôn ngoan giữa hai ngày khác

$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) 
Các vấn đề liên quan