cakephp查找(全部)优化

时间:2014-07-10 15:57:32

标签: cakephp relationship

我正在使用cakephp 2.5.2
我有5张桌子

1-用户
2-项目
3-标签
4- project_tags
5-图像

用户可以有很多项目 一个项目可以有很多(标签,图像)

我有两个问题

$projects = $this->Project->find('all',array('conditions'=>array('User.id'=>$this->Auth->user('id'))));
debug($projects);exit();

这给出了

array(
(int) 0 => array(
    'Project' => array(
        'id' => '1',
        'name' => 'project 1'
    ),
    'User' => array(
        'password' => '*****',
        'id' => '1',
        'name' => 'User 1',
        'email' => 'user1@gmail.com'
    ),
    'Image' => array(),
    'ProjectTag' => array(
        (int) 0 => array(
            'id' => '1',
            'project_id' => '1',
            'tag_id' => '1'
        ),
        (int) 1 => array(
            'id' => '2',
            'project_id' => '1',
            'tag_id' => '8'
        ),
        (int) 2 => array(
            'id' => '3',
            'project_id' => '1',
            'tag_id' => '6'
        ),
        (int) 3 => array(
            'id' => '4',
            'project_id' => '1',
            'tag_id' => '10'
        ),
        (int) 4 => array(
            'id' => '5',
            'project_id' => '1',
            'tag_id' => '4'
        )
    )
),
(int) 1 => array(
    'Project' => array(
        'id' => '2',
        'name' => 'project 2'
    ),
    'User' => array(
        'password' => '*****',
        'id' => '1',
        'name' => 'user 1',
        'email' => 'user1@gmail.com'
    ),
    'Image' => array(),
    'ProjectTag' => array(
        (int) 0 => array(
            'id' => '6',
            'project_id' => '2',
            'tag_id' => '1'
        ),
        (int) 1 => array(
            'id' => '7',
            'project_id' => '2',
            'tag_id' => '8'
        ),
        (int) 2 => array(
            'id' => '8',
            'project_id' => '2',
            'tag_id' => '4'
        )
    )
)

我需要Project& ProjectTag数组虽然不希望用户和图像阵列
我试过递归-1,0,1,2但是得不到我需要的东西

我的问题编号2是
如何找到标记=' html'

的项目
$projects = $this->Project->find('all',array('conditions'=>array('Tag.tag'=>'HTML')));

它说

  

错误:SQLSTATE [42S22]:未找到列:1054未知列' Tag.tag'在' where子句'

2 个答案:

答案 0 :(得分:1)

首先,请注意。始终使用$recursive=-1;。理想的只是在AppModel中设置它,然后再也不要乱用递归。如果您想获取其他数据,请使用CakePHP's Containable Behavior,而不是递归。

整体问题 - 您无法针对递归(或包含)模型添加条件,这是您在两个问题中的表现。如果你想对你正在进行查找的模型以外的模型进行条件化,你需要使用JOIN或交换查询以在另一个模型上运行。

回答问题1

改变这个:

$projects = $this->Project->find('all',array(
    'conditions'=>array(
        'User.id'=>$this->Auth->user('id')
    )
));

对此:

$projects = $this->Project->find('all',array(
    'conditions'=>array(
        'user_id'=>$this->Auth->user('id')  // <-- notice this
    ),
    'contain' => array(
        'ProjectTag' => array(
            'Tag' // <-- optional, as you didn't mention you needed
        )
    )
));

回答问题2:

有很多方法可以做到这一点。我会建议使用连接:

$projects = $this->Project->find('all', array(
    'fields' => array(
        'Project.*',
        'Tag.*'
    ),
    'joins'=>array(
        array(
            'table' => 'tags',
            'alias' => 'Tag',
            'type' => 'inner',
            'conditions' => array(
                'Tag.project_id = Project.id',
                'Tag.tag' => 'HTML'
            )
        )
    )
));

另一种方法是交换查询以在标签上运行,只需使用contain来包含该标签的项目。我更喜欢连接,因为如果你想扩展它以检索不止一个标签的项目,你的数据仍将是一种易于使用的方式,而不是Containable,这将把你的项目放在不同的数组下他们相应的标签。

答案 1 :(得分:0)

如果要在CakePHP中优化查询,请关闭递归(将其设置为-1),然后使用可包含行为来挑选并准确选择所需的数据。

对于您的特定查询,默认情况下,关联模型由左连接获得,这意味着如果您从项目中执行查询,您将获得所有项目以及他们在其标记字段中具有“html”的任何标记。解决此问题的最简单方法是从标签中进行搜索:

$tags = $this->Tag->find('first', array('conditions' => array('tag' => 'html'), 'contain' => array('Project')));

这将获得标签字段中包含'html'的标签,以及与之关联的所有项目。