Apache Solr sur Drupal : Ajouter un champ (field) dans l’index

Publié le 30 mai 2011

Apache SolrApache Solr avec le module de Apache Solr Search Integration sous Drupal permet à votre site d’avoir un moteur de recherche ultra-performant (le moteur de recherche par défaut de Drupal utilise massivement la base de données, ce qui nuit à la performance du site).

Vous pouvez accéder à Solr avec vos modules customs afin d’affiner vos recherches ou intégrer des filtres provenant de données externe à Drupal (exemple : une table extérieure au schéma de Drupal).

Cas pratique : sur chaque node indexées, vous voulez rajouter les champs xxx et yyy

Il faut d’abord indiquer à Solr que de nouveau champs sont ajoutés.

Pour cela nous allons les ajouter lorsque Drupal met à jour l’index (via le cron).
Voilà les champs que j’ai voulu ajouter : le champ xxx qui ne peut contenir une seule valeur boolean : True ou False
et yyy qui a plusieurs valeurs (de type string : « un », « deux »….).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function exemple_apachesolr_update_index(&$documentoSolr, $node) {
//Ajout du champs xxx
//code pour determiner la valeur de xxx
$valeur_xxx='true'; //ou false
//...
$documentoSolr->setField('bs_xxx', 'true');
 
//Ajout du champ yyy
//code pour determiner les valeur de yyy
$valeurs_yyy=array("un","deux","trois");
//...
//pour lire le tableau rajouter un for ou while
$documentoSolr->addField('sm_yyy',  $valeurs_yyy[0]);
$documentoSolr->addField('sm_yyy',  $valeurs_yyy[1]);
$documentoSolr->addField('sm_yyy',  $valeurs_yyy[2]);
}

N’oubliez pas de re-indexer votre contenu via l’interface d’Apache Solr Search Integration

Vous remarquerez qu’on ne peut pas écrire les noms des champ librement : xxx devient bs_xxx et yyy devient sm_yyy

Les champs doivent obéir à la définition que l’on trouve dans le fichier schema.xml :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<dynamicField name="is_*" type="integer" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="im_*" type="integer" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="sis_*" type="sint" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="sim_*" type="sint" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="sm_*" type="string" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="tm_*" type="text" indexed="true" stored="true" multiValued="true" termVectors="true"/>
<dynamicField name="ss_*" type="string" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="ts_*" type="text" indexed="true" stored="true" multiValued="false" termVectors="true"/>
<dynamicField name="tsen2k_*" type="edge_n2_kw_text" indexed="true" stored="true" multiValued="false" omitNorms="true" omitTermFreqAndPositions="true"/>
<dynamicField name="ds_*" type="date" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="dm_*" type="date" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="tds_*" type="tdate" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="tdm_*" type="tdate" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="bm_*" type="boolean" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="bs_*" type="boolean" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="fs_*" type="sfloat" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="fm_*" type="sfloat" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="ps_*" type="sdouble" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="pm_*" type="sdouble" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="tis_*" type="tint" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="tim_*" type="tint" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="tls_*" type="tlong" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="tlm_*" type="tlong" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="tfs_*" type="tfloat" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="tfm_*" type="tfloat" indexed="true" stored="true" multiValued="true"/>
<dynamicField name="tps_*" type="tdouble" indexed="true" stored="true" multiValued="false"/>
<dynamicField name="tpm_*" type="tdouble" indexed="true" stored="true" multiValued="true"/> 
<dynamicField name="sort_ss_*" type="sortString" indexed="true" stored="false"/><copyField source="ss_*" dest="sort_ss_*"/> 
<dynamicField name="random_*" type="rand" indexed="true" stored="true"/> 
<dynamicField name="nodeaccess*" type="integer" indexed="true" stored="false" multiValued="true"/>

Pas très pratique….
Heureusement la fonction apachesolr_index_key est là pour vous aider à trouver le bon nom des variables :

1
2
3
4
5
6
7
8
9
10
11
$var_xxx = apachesolr_index_key (array(
'name' =>'xxx',
'multiple' => FALSE,
'index_type' => 'boolean',
));  //retourne 'bs_xxx
 
$var_yyy = apachesolr_index_key (array(
'name' => 'yyy',
'multiple' => TRUE,
'index_type' =>'string',
)); //retourne sm_yyy

La fonction devient :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function exemple_apachesolr_update_index(&$documentoSolr, $node) {
//Ajout du champs xxx
//code pour determiner la valeur de xxx
$valeur_xxx='true'; //ou false
//Détermine le nom de la variable a donner 
//Bonne pratique :  ces lignes doivent être sortie de la fonction 
$var_xxx = apachesolr_index_key (array(
'name' => 'xxx',
'multiple' => FALSE,
'index_type' => 'boolean',
));  //retourne 'bs_xxx
 
$documentoSolr->setField($var_xxx, 'true');
 
//Ajout du champ yyy
//code pour determiner les valeur de yyy
$valeurs_yyy=array("un","deux","trois");
//Détermine le nom de la variable a donner 
//Bonne pratique :  ces lignes doivent être sortie de la fonction 
//...
$var_yyy = apachesolr_index_key (array(
'name' => 'yyy',
'multiple' => TRUE,
'index_type' => 'string',
)); //retourne sm_yyy
//pour lire le tableau rajouter un for ou while
$documentoSolr->addField($var_yyy,  $valeurs_yyy[0]);
$documentoSolr->addField($var_yyy,  $valeurs_yyy[1]);
$documentoSolr->addField($var_yyy,  $valeurs_yyy[2]);
}

Voilà les 2 champs bs_xxx et sm_yyy viennent d’être ajouté dans l’index de Solr.

Maintenant il y a des plusieurs de façons d’exploiter ces champs dans le resultat de recherche :

Exemple 1 :

Vous ne voulez afficher que les résulats dont bs_xxx est à True (autrement dit : jamais afficher les bs_xxx dont la valeur est False).

Pour cela on va ajouter modifier la requete envoyé a apache :

1
2
3
 function exemple_apachesolr_modify_query(&$query, &$params, $caller) {
   $query->add_filter('bs_xxx','true');
}

Exemple 2 :
Vous voulez que sur l’interface de recherche les gens puissse trier les résultats par bs_xxxx.

1
2
3
4
5
6
7
function exemple_apachesolr_prepare_query(&$query, &$params) {
  $query->set_available_sort('bs_xxx', array(
    'title' => t('Le nom que vous voulez'),
    'default' => 'asc',  
  ));
 
}

Dans un prochain billet j’expliquerais comment faire un bloc de filtre (facet) avec le champ yyy.


Les commentaires sont fermés sur cet article.