【问题标题】:Single Pagination on multiple models in cakephpcakephp中多个模型的单分页
【发布时间】:2016-09-28 03:33:45
【问题描述】:

我的要求是搜索 2 个不同的表格:Vets 和 Clinics。它们之间可能存在关系,即结果应获取名称中包含“a”的诊所和名称中包含“a”的兽医。兽医可能与诊所有关,也可能与诊所无关。目前我正在做以下事情。有什么方法可以避免运行 2 个查询,也可以帮助我使用 cakephp 分页助手?

$this->paginate = array(
        'Vet' => array(
            'conditions' => $conditions,
            'fields' => array('Vet.id', 'Vet.name', 'Vet.professionnal_address', 'phone_number', 'Vet.email', 'Vet.type', 'Vet.latitude', 'Vet.longitude','Vet.city','Vet.clinic_id','Vet.zipcode'),
            'joins' => array( 
                array(
                    'table' => 'vet_appointment_types',
                    'alias' => 'VetAppointmentType',
                    'type' => 'LEFT',
                    'conditions' => array(
                        'Vet.id = VetAppointmentType.vet_id',
                    )
                )
            ),
            'limit' => $limit, 
            'group' => array(
                'Vet.id'
            ), 
            'order' => array(
                'Vet.name' => 'ASC'
            )
        ),
        'Clinic' => array(
            'conditions' => $conditions1,
            'fields' => array('Clinic.*'),
            'limit' => $limit, 
            'order' => array(
                'Clinic.name' => 'ASC'
            )
        )
    );

$results = $this->paginate('Vet');
$results2 = $this->paginate('Clinic');

我尝试在非数据库模型中扩展默认分页组件并使用联合,但数据库结构有点复杂,因此无法使用联合。另外,我认为实现基于临时表的模型是一种选择,但由于它将用于搜索,所以究竟如何实现它,我无法思考。任何帮助都会 +1 ;)

【问题讨论】:

  • 如果您不能使用联合或视图,您将很难对来自两个表的非关联数据进行分页。为此,我将使用 Elastic Search 实现搜索索引。
  • 如果我使用临时表来存储tabled和search中的数据,这会是一个乏味的方法吗?
  • 它会,当任何数据发生变化时,您必须更改临时表。也许您应该查看数据库视图?
  • 谢谢。我是使用数据库视图完成的。

标签: php mysql cakephp view pagination


【解决方案1】:

根据建议,我通过使用数据库视图来完成它。下面是代码。非常感谢任何改进建议。

// \app\Model\Search.php
App::uses('ConnectionManager', 'Model');
App::uses('AppModel', 'Model');
App::uses('CakeLog', 'Log');

class Search extends AppModel {

    public function __construct() {
        parent::__construct();

        $connection = ConnectionManager::getDataSource('default');
        $return = $connection->execute("CREATE OR REPLACE VIEW `search` AS
            SELECT Vet.id, (CONCAT( `Vet`.`fname` , ' ', `Vet`.`lname` )) AS name, 'vet' AS TYPE , Vet.latitude, Vet.longitude, Vet.zipcode, Vet.speciality FROM `db`.`vets` AS `Vet` 
            UNION 
            SELECT Clinic.id, Clinic.name, 'clinic' AS TYPE , Clinic.lat, Clinic.long, Clinic.zipcode, Clinic.address FROM `db`.`clinics` AS `Clinic`");
        $return = ($return == true)?'Search View created successfully on '.date('Y-m-d H:i:s'):$return;
        CakeLog::write('search', $return);
    }

    public $useTable = 'search';// This model does not use a database table
    public $primaryKey = 'id'; // Define primary key
    public $useDbConfig = 'default'; // Define db

}

这是模型。每次用户搜索任何内容时,当模型加载到控制器中时,都会创建/替换视图,以便可以获取更新的值。它可以用作 cakephp 中的任何其他模型。它也支持 virtualFields。要为数据库视图构建查询,您还可以使用我使用的查询构建器,如下所示。

$joins = array(
        array(
            'table' => 'vet_appointment_types',
            'alias' => 'VetAppointmentType',
            'type' => 'LEFT',
            'conditions' => array(
                'Vet.id = VetAppointmentType.vet_id',
            )
        )
    );

    $dbo = $this->Vet->getDataSource();
    $subQuery = $dbo->buildStatement(
        array(
            'fields' => array('Vet.id', 'Vet.name'),
            'table' => $dbo->fullTableName($this->Vet),
            'alias' => 'Vet',
            'limit' => $limit, 
            'group' => array(
                'Vet.id'
            ), 
            'order' => array(
                'Vet.name' => 'ASC'
            ),
            'offset' => null,
            'joins' => $joins,
            'conditions' => $conditions
        ),
        $this->Vet
    );
    $query = $subQuery;

    $query .= ' UNION ';

    $dbo = $this->Clinic->getDataSource();
    $subQuery = $dbo->buildStatement(
        array(
            'fields' => array('Clinic.id', 'Clinic.name'),
            'table' => $dbo->fullTableName($this->Clinic),
            'alias' => 'Clinic',
            'limit' => $limit,
            'conditions' => $conditions1,
            'limit' => $limit, 
            'order' => array(
                'Clinic.name' => 'ASC'
            ),
            'offset' => null
        ),
        $this->Clinic
    );

    $query .= $subQuery;

    print_r($query);

【讨论】:

    猜你喜欢
    • 2010-12-29
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 2012-10-06
    • 1970-01-01
    • 1970-01-01
    • 2011-05-03
    • 1970-01-01
    相关资源
    最近更新 更多