Changeset 82816 in spip-zone


Ignore:
Timestamp:
Jun 1, 2014, 10:46:08 PM (5 years ago)
Author:
rastapopoulos@…
Message:

Un nouveau filtre dans l'API tableau + son critère dans la boucle SPHINX, afin de définir un filtre de distance.

{filtrerdistance, test, point1, point2, distance[, comparaison]}

La comparaison est optionnelle, et vaut "<=" par défaut, ce qui correspond à beaucoup de recherches (tous les docs à maximum 5km de...).

Et ya déjà la doc dans le markdown marcimat. :)

Location:
_plugins_/indexer/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • _plugins_/indexer/trunk/doc/boucle_sphinx.md

    r82772 r82816  
    236236```
    237237
     238### Filtre de distance
     239* @syntaxe `{filterdistance test, point1, point2, distance[, comparaison[, nom du champ]]}`
     240
     241Ce critère sélectionne uniquement les réponses qui font que la distance entre le point 1 et le point 2 correspond à la comparaison demandée avec la distance passée en paramètre.
     242
     243La comparaison est optionnelle est vaut "<=" par défaut.
     244Le nom de la distance calculée est optionnelle et vaudra par défaut "distance_0" pour la première distance demandée, puis "distance_1", etc. Ce paramètre permet de maîtriser le nom afin de pouvoir plus facilement demander un tri par le nom voulu, et récupérer la valeur avec une balise.
     245
     246**Exemple**
     247```
     248// Tous les documents qui sont à moins de 5km de Bordeaux, avec comme nom #DISTANCE
     249#SET{bordeaux, #ARRAY{lat, 44.83717, lon, -0.57403}}
     250#SET{point_document, #ARRAY{lat, properties.geo.lat, lon, properties.geo.lon}}
     251{filterdistance , testok, #GET{bordeaux}, #GET{point_document}, 5000, '<=', distance}
     252```
     253
    238254PAGES
    239255-----
  • _plugins_/indexer/trunk/iterateur/sphinx.php

    r82793 r82816  
    115115                        'facet'             => array(),
    116116                        'filter'            => array(),
    117                         'filters_mono'       => array(),
    118                         'filters_multijson'  => array(),
     117                        'filters_mono'      => array(),
     118                        'filters_multijson' => array(),
     119                        'filters_distance'  => array(),
    119120                );
    120121
     
    137138                $this->setFiltersMono($this->command['filters_mono']);
    138139                $this->setFiltersMultiJson($this->command['filters_multijson']);
     140                $this->setFiltersDistance($this->command['filters_distance']);
    139141
    140142                $this->setSnippet($this->command);
     
    632634        }
    633635       
     636        function setFiltersDistance($filters){
     637                $filters = array_filter($filters);
     638                if (!$filters) {
     639                        return false;
     640                }
     641               
     642                $ok = true;
     643                foreach ($filters as $filter){
     644                        $ok &= $this->queryApi->setApiFilterDistance($filter);
     645                }
     646               
     647                return $ok;
     648        }
     649       
    634650        /**
    635651         * Revenir au depart
     
    887903                . (isset($crit->param[1]) ? "\t\t\t'field'       => $field,\n" : '')
    888904                . (isset($crit->param[2]) ? "\t\t\t'values'      => $values,\n" : '')
     905                . "\t\t);\n";
     906       
     907        // Fin de test
     908        $boucle->hash .= "\t}\n";
     909}
     910
     911/**
     912 * Indiquer les filtres de distance de la requête
     913 *
     914 * @param string $idb
     915 * @param object $boucles
     916 * @param object $crit
     917 */
     918function critere_SPHINX_filterdistance_dist($idb, &$boucles, $crit) {
     919        $boucle = &$boucles[$idb];
     920       
     921        if (isset($crit->param[0])) {
     922                $test = calculer_liste($crit->param[0], array(), $boucles, $boucles[$idb]->id_parent);
     923        }
     924        if (isset($crit->param[1])) {
     925                $point1 = calculer_liste($crit->param[1], array(), $boucles, $boucles[$idb]->id_parent);
     926        }
     927        if (isset($crit->param[2])) {
     928                $point2 = calculer_liste($crit->param[2], array(), $boucles, $boucles[$idb]->id_parent);
     929        }
     930        if (isset($crit->param[3])) {
     931                $distance = calculer_liste($crit->param[3], array(), $boucles, $boucles[$idb]->id_parent);
     932        }
     933        if (isset($crit->param[4])) {
     934                $comparison = calculer_liste($crit->param[4], array(), $boucles, $boucles[$idb]->id_parent);
     935        }
     936        if (isset($crit->param[5])) {
     937                $as = calculer_liste($crit->param[5], array(), $boucles, $boucles[$idb]->id_parent);
     938        }
     939       
     940        // Test
     941        $boucle->hash .= "\n\tif ($test) {\n";
     942       
     943        // Critere multiple
     944        $boucle->hash .= "\t\tif (!isset(\$filters_distance_init)) { \$command['filters_distance'] = array(); \$filters_distance_init = true; }\n";
     945
     946        $boucle->hash .= "\t\t\$command['filters_distance'][] = array(\n"
     947                . (isset($crit->param[1]) ? "\t\t\t'point1'      => $point1,\n" : '')
     948                . (isset($crit->param[2]) ? "\t\t\t'point2'      => $point2,\n" : '')
     949                . (isset($crit->param[3]) ? "\t\t\t'distance'    => $distance,\n" : '')
     950                . (isset($crit->param[4]) ? "\t\t\t'comparison'  => $comparison,\n" : '')
     951                . (isset($crit->param[5]) ? "\t\t\t'as'          => $as,\n" : '')
    889952                . "\t\t);\n";
    890953       
  • _plugins_/indexer/trunk/lib/Sphinx/SphinxQL/QueryApi.php

    r82782 r82816  
    367367                                                $ok &= $this->setApiFilterMultiJson($filter);
    368368                                                break;
     369                                        case 'distance':
     370                                                $ok &= $this->setApiFilterDistance($filter);
     371                                                break;
    369372                                }
    370373                        }
     
    431434                static $as_count = 0;
    432435
    433                 // Multi value JSON
     436                // Field and values must be there
    434437                if (
    435438                        !isset($filter['field'])
     
    479482                static $as_count = 0;
    480483
    481                 // Multi value JSON
     484                // Mandatory parameters
    482485                if (
    483486                        !isset($filter['point1']['lat'])
     
    498501                }
    499502               
    500                 //$this->select('geodist(' .
     503                // Default "as"
     504                if (!isset($filter['as'])){
     505                        $filter['as'] = 'distance_' . $as_count;
     506                        $as_count++;
     507                }
     508               
     509                $this->select('geodist(double(' . $filter['point1']['lat'] . '), double(' . $filter['point1']['lon'] . '), double(' . $filter['point2']['lat'] . '), double(' . $filter['point2']['lon'] . '), {in=deg}) as ' . $filter['as']);
     510                $this->where($filter['as'] . ' ' . $filter['comparison'] . ' ' . $this->quote($filter['distance']));
    501511               
    502512                return true;
Note: See TracChangeset for help on using the changeset viewer.