从数据库中进行最佳抽样

Optimal sampling from the database

我在城市周围做一个样本,城市有地区,有综合体,还有公寓大楼。最后,我需要获得某个城市的公寓,并指明相关的过滤器(地区、综合体等)。目前我这样做了:

public function actionIndex()
{
    $cities = Cities::find()->where(['id' => Yii::$app->request->get('city_id')])->with([
        'districts' => function ($query){
            $query->filterWhere([
                'id' => Yii::$app->request->get('district_id'),
            ]);
        },
        'districts.complexes' => function ($query) {
            $query->filterWhere([
                'id' => Yii::$app->request->get('complex_id'),
                'type_id' => Yii::$app->request->get('complex_type_id'),
                'developer_id' => Yii::$app->request->get('developer_id'),
            ]);
        },
        'districts.complexes.apartments' => function ($query) {
            $query->filterWhere([
                'amount_room' => Yii::$app->request->get('amount_room'),
                'yardage' => Yii::$app->request->get('yardage'),
                'level' => Yii::$app->request->get('level'),
                'price' => Yii::$app->request->get('price'),
            ]);
        },
    ])->all();
    $query = [];
    foreach ($cities as $city) {
        foreach ($city->districts as $district) {
            foreach ($district->complexes as $complex) {
                foreach ($complex->apartments as $apartment) {
                    $query[] = $apartment;
                }
            }
        }
    }
    return new ArrayDataProvider([
        'allModels' => $query,
    ]);
}

但是看起来有点歪,可能是我走错了,我可以做得更好吗?

UPD:我和 Yasin Patel 差不多。

$cities = Cities::find()
        //->select('cities.id') //  list your attributes comma saperated
        ->leftJoin('districts','cities.id=districts.city_id') // join districts table
        ->leftJoin('complex','districts.id=complex.district_id') // join complex table
        ->leftJoin('apartment','complex.id=apartment.complex_id') // join apartment table
        ->where(['cities.id' => Yii::$app->request->get('city_id')])
        ->andWhere(['cities.id' => Yii::$app->request->get('city_id')])
        ->filterWhere(['districts.id' => Yii::$app->request->get('district_id')])
        ->filterWhere(['complex.id' => Yii::$app->request->get('complex_id')])
        ->filterWhere(['complex.type_id' => Yii::$app->request->get('complex_type_id')])
        ->filterWhere(['complex.developer_id' => Yii::$app->request->get('developer_id')])
        ->filterWhere(['apartment.amount_room' => Yii::$app->request->get('amount_room')])
        ->filterWhere(['apartment.yardage' => Yii::$app->request->get('yardage')])
        ->filterWhere(['apartment.level' => Yii::$app->request->get('level')])
        ->filterWhere(['apartment.price' => Yii::$app->request->get('price')]);

    return new ActiveDataProvider([
        'query' => $cities,
    ]);

Returns:

[
   {
      "name":"City1",
      "region":{
         "id":7,
         "name":"Region city1."
      }
   }
]

但是现在如何选择找到的所有公寓?

试试这个查询。

$cities = Cities::find()
   ->select('city.id') //  list your attributes comma saperated
   ->leftJoin('districts','city.id=districts.city_id') // join districts table
   ->leftJoin('complexes','districts.id=complexes.districts_id') // join complexes table
   ->leftJoin('apartments','complexes.id=apartments.complexe_id') // join apartments table
   ->where(['id' => Yii::$app->request->get('city_id')])
   ->andWhere(['city.id' => Yii::$app->request->get('district_id')])
   ->andWhere(['districts.id' => Yii::$app->request->get('district_id')])   
   ->andWhere(['complexes.id' => Yii::$app->request->get('complex_id')])      
   ->andWhere(['complexes.type_id' => Yii::$app->request->get('complex_type_id')])     
   ->andWhere(['complexes.developer_id' => Yii::$app->request->get('developer_id')])     
   ->andWhere(['apartments.amount_room' => Yii::$app->request->get('amount_room')])     
   ->andWhere(['apartments.yardage' => Yii::$app->request->get('yardage')])     
   ->andWhere(['apartments.level' => Yii::$app->request->get('level')])     
   ->andWhere(['apartments.price' => Yii::$app->request->get('price')])     
    ->asArray();

根据需要使用您的 table 名称和属性名称。 比在 ArrayDataProvider 中使用此查询。

return new ArrayDataProvider([
        'allModels' => $query,
    ]);

这将return您记录为数组。

原来是这样优化代码::

public function actionIndex()
{        
    $query = Apartment::find()
        ->joinWith('complex')
        ->joinWith('complex.district')
        ->joinWith('complex.district.city')
        ->where(['cities.id' => Yii::$app->request->get('city_id')])
        ->filterWhere(['districts.id' => Yii::$app->request->get('district_id')])
        ->filterWhere(['complex.id' => Yii::$app->request->get('complex_id')])
        ->filterWhere(['complex.type_id' => Yii::$app->request->get('complex_type_id')])
        ->filterWhere(['complex.developer_id' => Yii::$app->request->get('developer_id')])
        ->filterWhere(['apartment.amount_room' => Yii::$app->request->get('amount_room')])
        ->filterWhere(['apartment.yardage' => Yii::$app->request->get('yardage')])
        ->filterWhere(['apartment.level' => Yii::$app->request->get('level')])
        ->filterWhere(['apartment.price' => Yii::$app->request->get('price')]);

    return new ActiveDataProvider([
        'query' => $query,
    ]);
}

感谢大家的帮助。