1

私は CakePHP 2.5.2 を使用していますが、データを効率的に検索するのに少し苦労しています。

私のアプリケーションでは、3 つのテーブル、チーム、プレーヤー、スキルがあります... チームには 80 レコード、プレーヤー 2400 レコード、スキル 2400 レコードがあります... チームの平均スキルを計算したい...

 //Team model
 public $actsAs = array('Containable');
 public $hasMany = array('Player');

    //Player model
 public $actsAs = array('Containable');
 public $hasOne = array('Skill');
 public $belongsTo = array('Team');

  //Skill model
 public $actsAs = array('Containable');
 public $belongsTo = array('Player');

私の研究は:

$team =  $this->Team->find('all', array(
    'contain' => array(
        'Player' => array(
             'Skill'
        )
    ),
));
   $this->set('team', $team);

これにより、期待される結果が得られます。

Array
(
    [0] => Array
        (
            [Team] => Array
                (
                    [id] => 1
                    [name] => my_team_name
                )

            [Player] => Array
                (
                    [0] => Array
                        (
                            [id] => 000000419
                            [name] => Name
                            [surname] => Surname
                            [age] => 21
                            [team_id] => 1
                            [Team_id] => 1
                            [Skill] => Array
                                (
                                    [id] => 20
                                    [player_id] => 000000419
                                    [skill] => 599
                                )

                        ), ecc.....

この構造は、少なくとも 1680 のクエリを使用します...これは私には多すぎます...

私は別の方法を試しました.1つのクエリだけを含み、悪いデータ構造を返しますが、必要なすべての情報を返します(これも冗長です)。残念ながら、この方法に従ってください。ビューで反復して必要なものを表示することはできません。

$player =  $this->Team->Player->find('all', array(
            'contains' => array(
            'Skill',
            ),

それが返す

Array
(
    [0] => Array
        (
            [Player] => Array
                (
                    [id] => 000000400
                    [nome] => my_player_name
                    [cognome] => my_player_surname
                    [nation_id] => 380
                    [age] => 29
                    [team_id] => 2
                )


            [Team] => Array
                (
                    [id] => 2
                    [nome] => my_team_name
                )

            [Skill] => Array
                (
                    [id] => 1
                    [player_id] => 000000400
                    [average] => 632
                )

        )

    ecc.

すべてのチームの平均スキルを取得するために VIEV で反復する方法はありますか? 他の解決策はありますか?

ありがとう!

4

2 に答える 2

1

CakePHP を 2.6 以降にアップグレードできる場合は、私のプラグインを使用してこの問題を解決できます。このプラグインは ContainableBehavior との互換性が高く、より優れたクエリを生成します。その場合、検索操作は2つのクエリのみを実行すると思います。お試しいただければ幸いです。

https://github.com/chinpei215/cakephp-eager-loader

使用法

1. EagerLoader プラグインを有効にする

// In your model
$actsAs = ['EagerLoader.EagerLoader'];

プラグインをロードするとどこかで何かが壊れるのではないかと心配な場合は、その場で有効にすることもできます。

// On the fly
$this->Team->Behaviors->load('EagerLoader.EagerLoader');

2. 同じ検索操作を実行します

$this->Team->find('all', ['contain' => ['Player' => ['Skill']]]);

3. クエリ ログを参照する

次のようなクエリ ログが表示されます。

SELECT ... FROM teams AS Team WHERE 1 = 1;
SELECT ... FROM players AS Player LEFT JOIN skills AS Skill ON Player.id = Skill.player_id WHERE Player.id IN ( ... );
于 2016-02-13T13:40:56.687 に答える