Changeset 82591 in spip-zone


Ignore:
Timestamp:
May 19, 2014, 8:04:02 PM (5 years ago)
Author:
marcimat@…
Message:

Critère de boucle {select_filter #TRUCE, si oui, si - } en attendant mieux. Cela couvre la sélection de tags, auteurs et date qu'il y avait sans la boucle Sphinx. + Affichage plus smart des mots trouvés dans les metas.

Location:
_plugins_/indexer/trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • _plugins_/indexer/trunk/content/sphinx.html

    r82571 r82591  
    2929
    3030
    31 <!--
    32         {filtre auteurs, properties.authors, ALL, #ENV*{auteur}}
    33         {filtre tags, properties.mots.fr, IN, #ENV*{auteur}}
    34 
    35         {mono #ENV{date}, date, =}
    36         {mono #ENV{date}, date, >}
    37         {mono #ENV{date}, date, IN}
    38         {mono #ENV{date}, date, INTERVAL, 100, 200, 300}
    39 
    40         {filtres #ENV*{f}} => tableau ? f[auteurs][description...]
    41 -->
    4231
    4332<BOUCLE_recherche_sphinx(SPHINX)
    4433        {index #ENV{source,spip}}
    4534        {recherche #ENV*{recherche}}
    46         {facet auteurs, properties.authors ORDER BY COUNT(*) DESC}
    47         {facet tags, properties.tags ORDER BY COUNT(*) DESC}
    48         {facet date, YEAR(date) ORDER BY date DESC}
     35
     36        {select_filter #ENV{annee},  'YEAR(date) = @valeur' }
     37        {select_filter #ENV{tag},    'IN(properties.tags, @valeurs)',    'LENGTH(properties.tags) = 0'}
     38        {select_filter #ENV{auteur}, 'IN(properties.authors, @valeurs)', 'LENGTH(properties.auteurs) = 0'}
     39
     40        {facet auteur, properties.authors ORDER BY COUNT(*) DESC}
     41        {facet tag,    properties.tags ORDER BY COUNT(*) DESC}
     42        {facet annee, YEAR(date) ORDER BY date DESC}
    4943>
    5044
     
    5852</BOUCLE_recherche_sphinx>
    5953
    60 <hr />
    6154
    62 
    63 [(#SET{sql, [(#ENV{source,''}|sphinx_get_query_documents{#ENV*{recherche},#ENV*{tag},#ENV*{auteur},#ENV{annee},#GET{order}})]})]
    64 
    65 <BOUCLE_recherche(DATA) {source SphinxQL, #GET{sql}, #ENV{debut_documents}}>
    66 
    67         <h1>Dans la boucle oldschool</h1>
    68         <pre>#QUERY</pre>
    69 
    70         [(#INCLURE{fond=liste/sphinx_documents,docs,meta,env})]
    71         [(#INCLURE{fond=liste/sphinx_facettes,facets,env})]
    72         [(#INCLURE{fond=liste/sphinx_metas,meta,env})]
    73 
    74 </BOUCLE_recherche>
    75 
    76 
  • _plugins_/indexer/trunk/doc/boucle_sphinx.md

    r82577 r82591  
    138138TRI SÉLECTIF
    139139----------------
    140 Exemple de tri sur une formule de calcul de « time segment », reprise ici de
     140Exemple de tri sur une formule de calcul de « time segment », reprise ici de
    141141http://sphinxsearch.com/blog/2010/06/27/doing-time-segments-geodistance-searches-and-overrides-in-sphinxql/
    142142
     
    156156>
    157157```
     158
     159
     160
     161FILTRER
     162-------
     163
     164En attendant mieux…
     165
     166Cette histoire de filtres n'est vraiment pas simple.
     167En attendant mieux, on propose de définir la présence d'un sélect (et d'un where associé)
     168si la valeur transmise possède du contenu, sinon le filtre n'est pas appliqué.
     169
     170Le 3è paramètre utilise une autre sélection, si la valeur vaut '-'.
     171Les clés @valeur et @valeurs sont remplacés par la donnée attendue quotée, ou les données attendues quotées et séparés par des virgules.
     172
     173Si `#ENV{tags}` vaut array('toto','tata'), @valeurs aura `"'toto', 'tata'"`
     174
     175Chaque filtre crée le where associé (filtre = 1).
     176
     177----
     178
     179    {select_filter #TRUC, select si contenu, select si '-'}
     180    {select_filter #ENV{auteur}, 'IN(properties.authors, @valeurs)', 'LENGTH(properties.authors) = 0'}
     181    {select_filter #ENV{tag}, 'IN(properties.tag, @valeurs)', 'LENGTH(properties.tags) = 0'}
     182    {select_filter #ENV{annee}, 'YEAR(date) = @valeur' }
  • _plugins_/indexer/trunk/iterateur/sphinx.php

    r82579 r82591  
    6363        /**
    6464         * Instance de SphinxQL
    65          * @var \SphinxQL
     65         * @var \Sphinx\SphinxQL\SphinxQL
    6666         */
    6767        protected $sphinxQL = null;
    6868
    6969        /**
    70          * Instance de SphinxQLQuery
    71          * @var \SphinxQLQuery
    72          */
    73         protected $sphinxQLQuery = null;
     70         * Instance de SphinxQL\QueryApi
     71         * @var \Sphinx\SphinxQL\QueryAPi
     72         */
     73        protected $queryApi = null;
    7474
    7575        /**
     
    105105                        'snippet'   => array(),
    106106                        'facet'     => array(),
     107
     108                        'select_filter' => [],
    107109                );
    108110
     
    113115                include_spip('inc/indexer');
    114116
    115                 $this->sphinxQL      = new \Sphinx\SphinxQL\SphinxQL(SPHINX_SERVER_HOST, SPHINX_SERVER_PORT);
    116                 $this->sphinxQLQuery = new \Sphinx\SphinxQL\Query();
     117                $this->sphinxQL  = new \Sphinx\SphinxQL\SphinxQL(SPHINX_SERVER_HOST, SPHINX_SERVER_PORT);
     118                $this->queryApi  = new \Sphinx\SphinxQL\QueryApi();
    117119
    118120                $this->setIndex($this->command['index']);
     
    122124                $this->setFacet($this->command['facet']);
    123125
     126                $this->setSelectFilter($this->command['select_filter']);
     127
    124128                $this->setSnippet($this->command);
    125129
     
    129133
    130134        public function runQuery() {
    131                 $query  = $this->sphinxQLQuery->get();
     135                $query  = $this->queryApi->get();
    132136                $result = $this->sphinxQL->allfetsel($query);
    133137                if (!$result) {
     
    140144
    141145        public function quote($m) {
    142                 return $this->sphinxQLQuery->quote($m);
     146                return $this->queryApi->quote($m);
    143147        }
    144148
     
    159163                }
    160164                foreach ($index as $i) {
    161                         $this->sphinxQLQuery->from($i);
     165                        $this->queryApi->from($i);
    162166                }
    163167                return true;
     
    182186                }
    183187                foreach ($select as $s) {
    184                         $this->sphinxQLQuery->select($s);
     188                        $this->queryApi->select($s);
    185189                }
    186190                return true;
     
    202206                }
    203207                $match = implode(' ',$recherche);
    204                 $this->sphinxQLQuery
     208                $this->queryApi
    205209                        ->select('WEIGHT() AS score')
    206210                        ->where('MATCH(' . $this->quote( $recherche ) . ')');
     
    219223                                $order .= ' ASC';
    220224                        }
    221                         $this->sphinxQLQuery->orderby($order);
     225                        $this->queryApi->orderby($order);
    222226                }
    223227                return true;
     
    263267                }
    264268
    265                 $desc['phrase'] = $this->getSnippetWordsFromPhrase($desc['phrase']);
     269                $desc['phrase'] = $this->queryApi->get_snippet_words($desc['phrase']);
    266270
    267271                if (!$desc['phrase'] OR !$desc['champ']) {
    268272                        return false;
    269273                }
    270                 $this->sphinxQLQuery->select("SNIPPET($desc[champ], " . $this->quote($desc['phrase']) . ", 'limit=$desc[limit]') AS $desc[as]");
     274                $this->queryApi->select("SNIPPET($desc[champ], " . $this->quote($desc['phrase']) . ", 'limit=$desc[limit]') AS $desc[as]");
    271275                return true;
    272276        }
     
    301305                return $phrase;
    302306        }
    303 
    304         /**
    305          * Extrait les mots pertinents d'une phrase pour un snippet
    306          *
    307          * @param string $phrase
    308          * @return string Mots séparés par espace.
    309         **/
    310         public function getSnippetWordsFromPhrase($phrase) {
    311                 if (!is_string($phrase)) return '';
    312 
    313                 // extraction des mots (évitons les opérateurs, guillements…)
    314                 preg_match_all('/\w+/u', $phrase, $mots);
    315                 #var_dump($phrase, $mots);
    316                 $mots = array_filter($mots[0], function($m) {
    317                         // nombres >= 4 chiffres
    318                         if (is_numeric($m)) {
    319                                 return (strlen($m) >= 4);
    320                         }
    321                         // mots >= 3 lettres
    322                         return (strlen($m) >= 3);
    323                 });
    324                 return implode(' ', $mots);
    325         }
    326 
    327307
    328308
     
    351331                        }
    352332                        $this->facet[] = array('alias' => $alias, 'query' => $query);
    353                         $this->sphinxQLQuery->facet($query);
     333                        $this->queryApi->facet($query);
    354334                }
    355335                return $ok;
    356336        }
    357337
     338
     339
     340        public function setSelectFilter($filters) {
     341                // compter le nombre de filtres ajoutés à la requête.
     342                static $nb = 0;
     343
     344                $facets = array_filter($filters);
     345                if (!$filters) {
     346                        return false;
     347                }
     348                foreach ($filters as $filter) {
     349                        // ignorer toutes les données vides
     350                        if (!is_array($filter) OR !isset($filter['valeur']) OR !$valeur = $filter['valeur']) {
     351                                continue;
     352                        }
     353                        if (is_string($valeur)) {
     354                                $valeur = trim($valeur);
     355                                $valeurs = [$valeur];
     356                        } else {
     357                                $valeurs = $valeur;
     358                                $valeur = 'Array !';
     359                        }
     360                        $valeurs = array_unique(array_filter($valeurs));
     361                        if (!$valeurs) {
     362                                continue;
     363                        }
     364
     365                        $filter += [
     366                                'select_oui'  => '',
     367                                'select_null' => '',
     368                        ];
     369
     370                        // préparer les données
     371                        $valeur = $this->quote($valeur);
     372                        $valeurs = array_map([$this, 'quote'], $valeurs);
     373                        $valeurs = implode(', ', $valeurs);
     374
     375                        if (($valeur == '-') and $filter['select_null']) {
     376                                $f = $filter['select_null'];
     377                        } elseif ($filter['select_oui']) {
     378                                $f = $filter['select_oui'];
     379                        }
     380
     381                        // remplacer d'abord le pluriel !
     382                        $f = str_replace(['@valeurs', '@valeur'], [$valeurs, $valeur], $f);
     383                        $this->queryApi->select("($f) AS f$nb");
     384                        $this->queryApi->where("f$nb = 1");
     385                        $nb++;
     386                }
     387        }
    358388
    359389        /**
     
    504534}
    505535
     536
     537
     538/**
     539 * Indiquer les filtres de la requête
     540 *
     541 * @param string $idb
     542 * @param object $boucles
     543 * @param object $crit
     544 */
     545function critere_SPHINX_select_filter_dist($idb, &$boucles, $crit) {
     546        $boucle = &$boucles[$idb];
     547        // critere multiple
     548        $boucle->hash .= "\n\tif (!isset(\$sfilter_init)) { \$command['select_filter'] = []; \$sfilter_init = true; }\n";
     549
     550        $boucle->hash .= "\t\$command['select_filter'][] = [\n"
     551                . (isset($crit->param[0]) ? "\t\t'valeur'      => ". calculer_liste($crit->param[0], array(), $boucles, $boucles[$idb]->id_parent) . ",\n" : '')
     552                . (isset($crit->param[1]) ? "\t\t'select_oui'  => ". calculer_liste($crit->param[1], array(), $boucles, $boucles[$idb]->id_parent) . ",\n" : '')
     553                . (isset($crit->param[2]) ? "\t\t'select_null' => ". calculer_liste($crit->param[2], array(), $boucles, $boucles[$idb]->id_parent) . ",\n" : '')
     554                . "\t];\n";
     555}
    506556
    507557
  • _plugins_/indexer/trunk/liste/sphinx_metas.html

    r82558 r82591  
    99        <td>
    1010        [(#CLE|=={keywords}|non) #VALEUR ]
    11         [(#CLE|=={keywords}|oui)
    12             <pre>[(#VALEUR*|print_r{1})]</pre>
    13         ]
     11        <B_keywords>
     12            <table class='spip'>
     13                <thead>
     14                    <tr>
     15                        <th>Mot</th>
     16                        <th>Documents</th>
     17                        <th>Nombre d'occurrences</th>
     18                    </tr>
     19                </thead>
     20                <tbody>
     21        <BOUCLE_keywords(DATA){source tableau, #VALEUR}{si #CLE|=={keywords}}>
     22                <tr>
     23                    <th>#KEYWORD</th>
     24                    <td>#DOCS</td>
     25                    <td>#HITS</td>
     26                </tr>
     27        </BOUCLE_keywords>
     28                </tbody>
     29            </table>
     30        </B_keywords>
    1431        </td>
    1532    </tr>
Note: See TracChangeset for help on using the changeset viewer.