Changeset 82551 in spip-zone


Ignore:
Timestamp:
May 17, 2014, 6:34:05 PM (5 years ago)
Author:
rastapopoulos@…
Message:

Diverses améliorations de l'API tableau :

  • on change de stragégie pour les multivalués : le premier niveau du tableau "values" génère des AND et le second niveau, si c'est un tableau génère des OR : cela permet de générer des AND plus dynamiquement (par ex tags[]=tag1&tags[]=tag2) alors qu'avant pour les AND il fallait appeler plusieurs fois le même critère : pas assez dynamique
  • on ajoute un "select" explicite possible, en plus des select calculés suivant les critères
  • on ajoute le score lorsqu'il y a une recherche fulltext
  • on ajoute le snippet lorsqu'il y a une recherche fulltext ET/OU lorsqu'on a défini des mots en plus explicitement : cela permet par exemple d'ajouter aussi les tags si on veut (même quand pas de fulltext)
  • on ajoute des espaces après les virgules dans la requête générée, c'est plus lisible
Location:
_plugins_/indexer/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • _plugins_/indexer/trunk/lib/Sphinx/SphinxQLQuery.php

    r82479 r82551  
    6565        }
    6666
     67        public function generate_snippet($field, $words='', $limit=200){
     68                if ($words){
     69                        $limit = intval($limit);
     70                        $this->select('snippet(' . $field . ', ' . $this->quote($words) . ", 'limit=$limit') as snippet");
     71                }
     72        }
     73       
    6774        public function array2query($query_description){
    6875                if (is_array($query_description)){
     
    7784                        }
    7885
     86                        // Explicit select definition
     87                        if (isset($query_description['select'])){
     88                                // Always work with an array of values
     89                                if (!is_array($query_description['select'])){
     90                                        $query_description['select'] = array($query_description['select']);
     91                                }
     92                                foreach ($query_description['select'] as $select){
     93                                        $this->select($select);
     94                                }
     95                        }
     96                       
    7997                        // Fulltext search string (optional)
    8098                        if (isset($query_description['fulltext']) and is_string($query_description['fulltext'])){
    8199                                $this->where('match(' . $this->quote($query_description['fulltext']) . ')');
    82                         }
    83 
     100                                // add the score
     101                                $this->select('weight() as score');
     102                                // add to snippet
     103                                $snippet_words = $query_description['fulltext'];
     104                        }
     105
     106                        // If there is fulltext and/or an other words declaration, generate a snippet
     107                        if (isset($query_description['snippet']['words']) and is_string($query_description['snippet']['words'])){
     108                                $snippet_words .= ' ' . $query_description['snippet']['words'];
     109                                $snippet_words = trim($snippet_words);
     110                        }
     111                        if ($snippet_words){
     112                                $field = isset($query_description['snippet']['field']) ? $query_description['snippet']['field'] : 'content';
     113                                $limit = isset($query_description['snippet']['limit']) ? $query_description['snippet']['limit'] : 200;
     114                                $this->generate_snippet($field, $snippet_words, $limit);
     115                        }
     116                       
    84117                        // All filters
    85118                        $as_count = 0;
     
    92125                                                and isset($filter['values']) // mandatory
    93126                                        ){
    94                                                 // Default comparision : =
     127                                                // Default comparison : =
    95128                                                if (!isset($filter['comparison'])){
    96129                                                        $filter['comparison'] = '=';
     
    102135                                                }
    103136
    104                                                 // For each values, we build a comparision
     137                                                // For each values, we build a comparison
    105138                                                $comparisons = array();
    106139                                                foreach ($filter['values'] as $value){
    107                                                         $comparisons[] = ($filter['not'] ? '!':'') . '(' . $filter['field'] . $filter['comparison'] . $this->quote($value) . ')';
     140                                                        $comparison = $filter['field'] . $filter['comparison'] . $this->quote($value);
     141                                                        if ($filter['not']){
     142                                                                $comparison = "!($comparison)";
     143                                                        }
     144                                                        $comparisons[] = $comparison;
    108145                                                }
    109146                                                if ($comparisons){
     
    121158                                                // Always work with an array of values
    122159                                                if (!is_array($filter['values'])){
    123                                                         $filter['values'] = array($filter['values']);
    124                                                 }
    125 
    126                                                 // For each values, we build an "in" select
    127                                                 $this->select(
    128                                                         'IN(' . $filter['field'] . ', ' . join(', ', array_map(array($this, 'quote'), $filter['values'])) . ') as multi_json_'.$as_count
    129                                                 );
    130                                                 $this->where('multi_json_'.$as_count . '=' . ($filter['not'] ? '0' : '1'));
     160                                                        $filter['values'] = array(array($filter['values']));
     161                                                }
     162
     163                                                // At depth 1, generate AND
     164                                                $ins = array();
     165                                                foreach ($filter['values'] as $values_in){
     166                                                        // Always work with an array of values
     167                                                        if (!is_array($values_in)){
     168                                                                $values_in = array($values_in);
     169                                                        }
     170                                                        $ins[] = 'IN(' . $filter['field'] . ', ' . join(', ', array_map(array($this, 'quote'), array_filter($values_in))) . ')';
     171                                                }
     172                                                if ($ins){
     173                                                        $this->select('(' . join(' AND ', $ins) . ') as select_'.$as_count);
     174                                                        $this->where('select_'.$as_count . '=' . ($filter['not'] ? '0' : '1'));
     175                                                        $as_count++;
     176                                                }
    131177                                        }
    132178                                }
     
    138184                array(
    139185                        'index' => 'visites',
     186                        'select' => array('date', 'properties', '*', 'etc'),
    140187                        'fulltext' => 'ma recherche',
    141188                        'filters' => array(
     
    202249    public function get() {
    203250        $query = [];
    204         $this->removeEmpty();
    205         if ($this->select)   $query[] = 'SELECT '   . implode(',', $this->select);
    206         if ($this->from)     $query[] = 'FROM '     . implode(',', $this->from);
     251        if ($this->select)   $query[] = 'SELECT '   . implode(', ', $this->select);
     252        if ($this->from)     $query[] = 'FROM '     . implode(', ', $this->from);
    207253        if ($this->where)    $query[] = 'WHERE ('   . implode(') AND (', $this->where) . ')';
    208254        if ($this->groupby)  $query[] = 'GROUP BY ' . implode(',', $this->groupby);
    209         if ($this->orderby)  $query[] = 'ORDER BY ' . implode(',', $this->orderby);
     255        if ($this->orderby)  $query[] = 'ORDER BY ' . implode(', ', $this->orderby);
    210256        if ($this->limit)    $query[] = 'LIMIT '    . $this->limit;
    211257        if ($this->facet)    $query[] = 'FACET '    . implode(' FACET ', $this->facet);
  • _plugins_/indexer/trunk/prive/squelettes/contenu/sphinx.html

    r82466 r82551  
    7272#SET{query, #ARRAY{
    7373        index,#ENV{source,spip},
     74        select, #LISTE{id,title,date,uri,properties},
    7475        fulltext, #ENV*{recherche},
     76        snippet,#ARRAY{
     77                words,#ENV*{datation},
     78                limit,300,
     79        },
    7580        filters, #LISTE{
    7681                #ARRAY{
    7782                        type,multi_json,
    78                         field,properties.tags,
    79                         values,#LISTE{#ENV*{tag}, truc, bidule},
    80                         not,true,
    81                 },
    82                 #ARRAY{
    83                         type,mono,
    84                         field,properties.date,
    85                         values,2014-04,
    86                         comparison,">=",
    87                         not,true,
     83                        field,properties.titres_hierarchie_datation,
     84                        values,#ENV*{datation},
    8885                },
    8986        },
    90 }|sphinx_get_array2query}
    91 
     87}|sphinx_get_array2query{5}}
     88
     89<pre>[(#GET{sql}|htmlspecialchars)]</pre>
    9290<pre>[(#GET{query}|htmlspecialchars)]</pre>
    9391
    9492
    95 <BOUCLE_recherche(DATA) {source SphinxQL, #GET{sql}} {si #ENV{recherche}}>
     93<BOUCLE_recherche(DATA) {source SphinxQL, #GET{query}} {si #ENV{recherche}}>
    9694
    9795        <B_documents>
     
    169167
    170168]
    171 [(#SET{sqlf,"SELECT COUNT(*) AS c, "GROUPBY() AS facette FROM [(#ENV{source,spip})] WHERE MATCH([(#ENV*{recherche}|_q)]) GROUP BY properties.tags ORDER BY c DESC LIMIT 30})]
     169[(#SET{sqlf,"SELECT COUNT(*) AS c, "GROUPBY() AS facette FROM [(#ENV{source,spip})] WHERE MATCH([(#ENV*{recherche}|_q)]) GROUP BY properties.titres_hierarchie_datation ORDER BY c DESC LIMIT 30})]
    172170
    173171
     
    189187            <h2>Liste des facettes</h2>
    190188        <BOUCLE_facette(DATA){source tableau, #VALEUR}{si #CLE|=={docs}}>
    191                 <a href="[(#SELF|parametre_url{tag,[(#VALEUR{facette}|sinon{-})]})]">[(#VALEUR{facette}|sinon{<i>sans tag</i>})]</a> (#VALEUR{c} documents)<br />
     189                <a href="[(#SELF|parametre_url{datation,[(#VALEUR{facette}|sinon{-})]})]">[(#VALEUR{facette}|sinon{<i>sans tag</i>})]</a> (#VALEUR{c} documents)<br />
    192190        </BOUCLE_facette>
    193191        </B_facette>
Note: See TracChangeset for help on using the changeset viewer.