【问题标题】:$this->find('all', array(...))$this->find('all', array(...))
【发布时间】:2014-09-04 15:57:21
【问题描述】:

我知道 find-all 的工作原理,我编写了一个搜索查询,它将在数据表的不同列中搜索表达式。一切正常。

但是现在,我不仅要在平面数据数组中搜索表达式,还要在子数组中搜索。我有以下结构:

[Company] => Array
            (
                [id] => 1
                [user_id] => 3
                [name] => TEAM-Security
                [address1] => Dorfstrasse 9
            )
 [Service] => Array
            (
                [0] => Array
                    (
                        [id] => 2
                        [cat] => Reinigung
                        [name] => Baureinigung
                        [created] => 2014-07-13 00:00:00
                        [modified] => 2014-07-13 00:00:00
                    )

                [1] => Array
                    (
                        [id] => 3
                        [cat] => Reinigung
                        [name] => Wohnungsreinigung
                        [created] => 2014-07-13 00:00:00
                        [modified] => 2014-07-13 00:00:00
                    )
            )

现在,我可以在不同的“公司栏”中进行搜索。现在,我还想在 Service-childs 的列中进行搜索。我阅读了很多博客、网页等,但找不到任何解决方法的提示。

到目前为止我的简单解决方案:

$searchterm = 'TEAM';
$pending = $this->Company->find('all', array(
    'conditions' => array('Company.name like' => '%$searchterm%')
));

我遇到的麻烦,我现在想在一个带有子数组的孩子中搜索。我想搜索 "Baureinigung" 等。我必须手动执行“foreach”或其他操作吗?或者有没有我目前不知道的蛋糕方式?

【问题讨论】:

    标签: php arrays cakephp conditional-statements


    【解决方案1】:

    这是我在使用 Cake 时最大的痛苦之一 - 尝试搜索更深的列并使用除了 LEFT 连接之外的任何东西。这对我有用。我假设你在公司模式下工作——如果不是,你应该是。这可以稍微修改以在控制器中工作,但它属于模型。我还假设您的 HABTM 正在使用一个名为 companies_services 的连接表

    首先将当前关联取消绑定到您要为查询进行内部联接的表:

    $this->unbindModel(array('hasAndBelongsToMany' => array('Service')));
    

    然后您需要使用 INNER 联接显式联接您的表。要在 CakePHP 2.x 中做到这一点,您可以在 find 方法的 options 参数中使用 join 键:

    $this->find('all', array(
        'joins' => array(
            array(
                'table' => 'companies_services',
                'alias' => 'CompanyServices',
                'type' => 'INNER',
                'conditions' => array(
                    'CompanyServices.company_id = Company.id'
                )
            ),
            array(
                'table' => 'services',
                'alias' => 'Service',
                'type' => 'INNER',
                'conditions' => array(
                    'Service.id = CompanyServices.id',
                    'Service.name LIKE ' => '%' . $service_search_term . '%'
                )
            ),
         ),
         'conditions' => array('Company.name LIKE ' => '%'. $company_search_term . '%',
         'recursive' => -1
    ));
    

    我要注意的另一件事是,我遇到了一些情况,我必须在执行此操作后显式声明我想要返回的字段。为此,您需要在上面的选项数组中添加一个“字段”键,例如(从上面的“递归”行开始):

    ...
    'recursive' => -1,
    'fields' => array(
        'Company.id',
        'Company.name',
        'CompanyServices.company_id',
        'CompanyServices.service_id',
        'Service.id',
        'Service.name'
    )
    ....
    

    【讨论】:

    • 我喜欢加入解决方案,但数据不是以 cakephp 方式提供的。它类似于 Company1/Service1、Company1/Service2、Company1/Service3、Company2/Service3、Company4/Service1、Company4/Service6。我想要 Company1/Service1/Service2/Service3、Company2/Service2、Company4/Service1/Service6
    • 现在,我实现了这个解决方案。这不完全是我想要的。但它现在有效。我按company.id分组,所以我只得到了每家公司一次。不幸的是,我失去了这家公司的所有其他服务(未被搜索)。但我可以做一个解决方法。在这种情况下,搜索功能更为重要。非常感谢大家。我学到了很多关于可包含的知识-> 什么是不可用的。它去sql,但更多的是显示信息而不是搜索......
    • @cleverketchup 表之间的现有关系是 LEFT 联接,根据我的经验,如果您在创建新的 INNER 联接之前不取消绑定该关系,cake 将生成错误的 SQL,从而导致错误跨度>
    • @user1970565 通常递归设置为-1 已经足够了。好吧,随便。
    【解决方案2】:

    您可以使用可包含行为对关联数据进行一些搜索。示例:

      $this->find(
          'all', 
          array(
             'conditions' => array('Company.name like' => '%$searchterm%'),  
             'contain' => array(
                   'Service' => array(
                          'conditions' => array(
                                'Service.name like' => '%$searchterm%'
                          )
                    )
               )
          )
      );
    

    请注意,在像这样同时对多个表进行搜索时,您必须特别注意连接类型。默认情况下,模型关联表现为左连接。

    【讨论】:

    • 我对此有一些问题......我认为它在你写 Kai 时可以工作。我与模型有 HABTM 关系。不起作用,但这是原因吗?
    • @FishWave 因为您需要在 Company 模型中声明 public $actsAs = array('Containable') 变量
    • 它有效,但我收到的公司也没有任何服务。服务阵列在那里并且是空的。我根本不想要没有服务的公司。
    • @FishWave 正如我所说,您必须特别注意连接类型。我不知道你到底想找到什么,所以我无法提供更多细节,但听起来你正在寻找的可能是一个内部连接。因此,要么将模型关系更改为内部联接类型,要么进行手动内部联接。
    【解决方案3】:

    在您的 Company 模型中,您定义了直接关联,例如

    class Company extends AppModel
    {
        var $name = 'Company';
        var $hasAndBelongsToMany = array('Service' =>
                            array(
                                  'fields'   => array('name')
                            )
                      );
    } 
    

    之后你可以尝试关注

    $pending = $this->Company->find('all', array(
        'conditions' => array("OR" => array(
                  'Company.name like' => '%$searchterm%',
                  'Service.name like' => '%$searchterm%'
            )))
    );
    

    【讨论】:

    • 不,此解决方案不起作用。我在模型中有一个 HABTM。 Cake 分别 MySQL 说: Column not found: 1054 Unknown column 'Service.name' in 'where Clause'
    • 阅读这篇文章可能会有所帮助cakephp.1045679.n5.nabble.com/…
    【解决方案4】:

    这个解决方案有点复杂,可能没有优化,但可以工作:

            $data = $this->Company->find('all', array(
                    'conditions' => array(
                        "OR" => array(
                            'Company.name like' => '%$searchterm%',
                            'Service.name like' => '%$searchterm%'
                        )
                    ),
                    'contain' => array(
                        'Service' => array(
                            'conditions' => array(
                                'Service.name like' => '%$searchterm%'
                            )
                        )
                    ),
                    'joins' => array(
                        array(
                            'table' => 'companies_services',
                            'alias' => 'CompanyServices',
                            'type' => 'INNER',
                            'conditions' => array(
                                'CompanyServices.company_id = Company.id'
                            )
                        ),
                        array(
                            'table' => 'services',
                            'alias' => 'Service',
                            'type' => 'INNER',
                            'conditions' => array(
                                'Service.id = CompanyServices.id'
                            )
                        )
                    )
                )
            );
    

    【讨论】:

    • 是的,这行得通。但因此我不需要可包含的行为。仅带有搜索词的条件就足够了。但是当我写信给另一个连接解决方​​案时,数据不是以 cakephp 方式出现的。
    • @FishWave,joins 无法返回蛋糕格式的数据。这就是我在这个例子中使用 contains 的原因。
    • 谢谢。我试过了,但数据不是以 cakephp 的方式出现的。但无论如何,我跳过了包含,它适用于搜索功能,但我没有获得每家公司的所有信息。在我勾选绿色的解决方案中阅读我的其他评论。谢谢聪明的番茄酱!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    • 2017-06-23
    • 1970-01-01
    • 2017-11-02
    • 1970-01-01
    相关资源
    最近更新 更多