2016-12-22 1 views
0

Je construis une application cake3 qui rassemble beaucoup de données de séries chronologiques dans une table double_measures:Limiter/données Rééchantillonnage dans CakePhp3

select * from double_measures limit 20; 
+----+--------------------+---------------------+-------+--------+ 
| id | physical_sensor_id | time    | milis | value | 
+----+--------------------+---------------------+-------+--------+ 
| 1 |     1 | 2016-11-25 00:50:01 |  0 | 306.15 | 
| 2 |     2 | 2016-11-25 00:50:01 |  0 | 300.15 | 
| 3 |     3 | 2016-11-25 00:50:01 |  0 | 308.15 | 
| 4 |     4 | 2016-11-25 00:50:01 |  0 | 308.15 | 
| 5 |     6 | 2016-11-25 00:50:01 |  0 | 310.15 | 
| 6 |     7 | 2016-11-25 00:50:01 |  0 | 310.15 | 
| 7 |     8 | 2016-11-25 00:50:01 |  0 | 305.15 | 
| 8 |     9 | 2016-11-25 00:50:01 |  0 | 306.15 | 
| 9 |     10 | 2016-11-25 00:50:01 |  0 | 304.15 | 
| 10 |     11 | 2016-11-25 00:50:01 |  0 | 309.15 | 
| 11 |     1 | 2016-11-25 00:55:01 |  0 | 306.15 | 
| 12 |     2 | 2016-11-25 00:55:01 |  0 | 300.15 | 
| 13 |     3 | 2016-11-25 00:55:01 |  0 | 308.15 | 
| 14 |     4 | 2016-11-25 00:55:01 |  0 | 308.15 | 
| 15 |     6 | 2016-11-25 00:55:01 |  0 | 310.15 | 
| 16 |     7 | 2016-11-25 00:55:01 |  0 | 310.15 | 
| 17 |     8 | 2016-11-25 00:55:01 |  0 | 305.15 | 
| 18 |     9 | 2016-11-25 00:55:01 |  0 | 306.15 | 
| 19 |     10 | 2016-11-25 00:55:01 |  0 | 304.15 | 
| 20 |     11 | 2016-11-25 00:55:01 |  0 | 309.15 | 
+----+--------------------+---------------------+-------+--------+ 

Actuellement, je suis la sélection de valeurs par la requête $measures = $table->find('all',['order'=>['id'=>'DESC']])->select(['time','milis','value'])->where(['physical_sensor_id'=>$sid])->limit($limit); suivante qui retourne la dernière $ limite les entrées pour un capteur donné. Cependant

, je préférerais rééchantillonner uniformément la table pour chaque nième valeur, n étant

[le nombre de valeurs pour sid $]/limite de $.

Grâce à How do you select every n-th row from mysql, je sais comment le faire en MySql, mais y a-t-il un moyen de le faire dans Cakephp3?

Bien sûr, je pourrais rééchantillonner AFTER query, mais ce n'est pas une option, car je manque de mémoire pour les jeux de résultats HUGE.

+0

La solution liée utilise une colonne calculée qui ajoute une numérotation consécutive à une requête interne, puis la sélectionne par une opération modulo sur la table virtuelle créée. Existe-t-il un moyen d'ajouter une telle colonne calculée au niveau de la requête (avant que toutes les données ne soient effectivement récupérées) dans le gâteau? Puis-je créer une vue et utiliser cette vue? Comment est-ce que je ferais ceci, en ayant en tête que je veux sélectionner par physical_sensor_id? –

Répondre

0

trouvé une solution:

dans mon AppController je définissais une fonction comme suit:

protected function initRowNumbering(){ 
    $conn = ConnectionManager::get('default'); 
    $conn->execute("SET @i = 0"); 
} 

Ensuite, dans le contrôleur où je besoin de la ré-échantillonnage, je donne les résultats suivants:

 $query = $table->find('all',['order'=>['id'=>'DESC']])->select(['time','milis','value'])->where(['physical_sensor_id'=>$sid]); 

     if ($sample != null){ // if the number of samples is set: 
      $this->initRowNumbering(); // add index variable 
      $count = $query->count(); // count total number of values for given sensor 
      $step = (int)($count/$sample); // calculate sample step size 
      if ($step > 0){ 
       $measures = $query->where(['(@i := @i+1)%'.$step.'=0']); // add resampling filter 
      } else { 
       $measures = $query; 
      }        
     } else { 
      $measures = $query->limit($limit); 
     } 

Cela fonctionne bien, même si ce n'est peut-être pas la solution la plus élégante.

Des idées d'amélioration?