solr overview presentation
DESCRIPTION
Présentation générale de Solr : concept de base, indexation, requêtes simples, conception d'index, exemples de requêtes plus complexes.TRANSCRIPT
0
Développeur chez , Marseille
Armand Abric
Virtual-Expo
/ @ / forgebinaire.net spyseth github.com/spy-seth
Introduction
Solr ?Moteur de recherche fulltext utilisant l'algorithme Lucene
= Base de données non relationnelle spécialisée dans la recherchetextuelle
Développé par la Fondation Apache
Actuellement en version 4.6.1
Interface d'administration
CommunicationsAPI REST en JSON/XML
De nombreuses librairies dans de nombreux languages : Java, C, Ruby, Python...
...et en PHP :
Une extention PECL...
...et même des bundles Symfony 2
/ / / PECL Solarium NelmioSolariumBundle SolrBundle
Structure interne Solr
schema.xml<?xml version="1.0" encoding="UTF-8" ?><schema name="store" version="1.5"> <types> <fieldtype name="string" class="solr.StrField" /> <fieldType name="int" class="solr.IntField" /> <fieldType name="double" class="solr.DoubleField" /> <fieldType name="latLon" class="solr.LatLonType" [...] /> </types>
<fields> <field name="id" type="int" indexed="true" stored="true" required="true" /> <field name="name" type="string" indexed="true" stored="false" required="true" /> <field name="owner_id" type="int" indexed="true" stored="true" multiValued="true" required="true" /> <field name="coordinates" type="latLon" indexed="true" stored="false" required="true" />
[...] </fields>
<uniqueKey>id</uniqueKey> <solrQueryParser defaultOperator="OR" /></schema>
Solr vs SGBD relationnelsPrincipales différences à l'usage :
Pas de jointure complexe, mais des jointures simplesPas de sous-requêtesTransactionnel aux coeurs du logiciel : toutes modifications dedonnées se fait dans une transaction (commit/rollback obligatoire)La notion "d'égalité" varie en fonction du core et du champs surlequel on travailleUn changement dans le fichier schema.xml entraine une ré-indexationcomplète des données
Solr dans le SIUn moteur de recherche vient en supplément de BDD existantes
(relationnelle, NoSQL, fichier...)
Il ne peut pas et ne doit pas remplacer une BDD "long terme"
Indexation
IndexationL'indexation consiste à stocker des données au sein de Solr
C'est durant cette phase que Solr construit ses index internes qui luipemettent d'être très performant
Pour indexer des données il suffit de faire une requête HTTP sur unrequestHandler d'update du core
Les données doivent être envoyé en XML ou JSON<add> <doc> <field name="id">SP2514N</field> <field name="name">Samsung SpinPoint P120 SP2514N - hard drive - 250 GB</field> <field name="cat">electronics</field> <field name="cat">hard drive</field> <field name="features">7200RPM, 8MB cache, IDE Ultra ATA-133</field> <field name="features">NoiseGuard, SilentSeek technology</field> <field name="price">92</field> <field name="popularity">6</field> <field name="inStock">true</field> </doc> <doc> [...] </doc></add>
Le processus d'indexationIl existe trois méthodes pour gérer l'indexation :
Full indexation : un bach d'indexation ré-indexe toutes les données àinterval régulierIndexation incrémentale : un bach d'indexation indexe leschangements depuis la dernière indexationIndexation en live : lors de la sauvegarde d'une entité dans le reste duSI, on déclanche la mise à jour des données de l'entité au sein de Solr
Aucune n'est parfaite. Il faut choisir en fonction de ses besoins.
Plusieurs de ces techniques peuvent (doivent) être utiliser en paralelle: il est toujours utile de pouvoir ré-indexer tout un core à partir de zéro.
Text analysis
Un vrai fieldType<?xml version="1.0" encoding="UTF-8" ?><!-- [...] --><fieldType name="text_en" class="solr.TextField"> <analyzer type="index"> <tokenizer class="solr.WhitespaceTokenizerFactory" /> <filter class="solr.SynonymFilterFactory" synonyms="synonyms_en.txt" ignoreCase="true" expand="true" /> <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords_en.txt" enablePositionIncrements="true" /> <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1" /> <filter class="solr.LowerCaseFilterFactory" /> <filter class="solr.ASCIIFoldingFilterFactory"/> <filter class="solr.SnowballPorterFilterFactory" language="English" /> </analyzer> <analyzer type="query"> <tokenizer class="solr.WhitespaceTokenizerFactory" /> <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords_en.txt" enablePositionIncrements="true" /> <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1" /> <filter class="solr.LowerCaseFilterFactory" /> <filter class="solr.ASCIIFoldingFilterFactory"/> <filter class="solr.SnowballPorterFilterFactory" language="English" /> </analyzer></fieldType><!-- [...] -->
fieldType bisUne partie du travail de recherche se prépare au moment de l'indexation
Il faut préparer les données pour simplifier le travail de requête :
nettoyer les caractères spéciauxgérer des synonymesretirer les balises HTMLgérer les accents en fonction de la langue...
Va chercher !
Présentation de la synthaxehttp://localhost:8983/solr/[core]/[requestHandler]?[params]
Paramètres de baseq : coeur de la requête de recherchefq : clause "where" de filtre des résultats (plusieurs autorisés)fl : liste des champs du document a retournerrows : limitstart : offsetsort : ordonancement des résulats
Requêtes simples
http://localhost:8983/solr/articles/select?q=*:*
http://localhost:8983/solr/articles/select?q=content:battlefield
&fl=id,content
http://localhost:8983/solr/articles/select
?q=content:(battlefield DICE)
&fl=id,content
http://localhost:8983/solr/articles/select
?q=content:"battlefield DICE"
&fl=id,content
http://localhost:8983/solr/articles/select
?q=content:"battlefield DICE"~10
&fl=id,content
http://localhost:8983/solr/articles/select
?q=content:battlefield AND author_id:2
&fl=id,content,author_id
Recherchesavancées
Search revelancy
Scoring : Personaliser l'importance des clauses de match de la requête(uniquement le paramètre "q")
http://localhost:8983/solr/articles/select
?q=content:battlefield AND (author_id:2 OR author_id:3 OR author_id:4)
&fl=id,content,author_id
Favorisons l'auteur #2 : "author_id:2̂100"
http://localhost:8983/solr/articles/select
?q=content:battlefield AND (author_id:2̂100 OR author_id:3 OR author_id:4)
&fl=id,content,author_id
Debugging et aspirineRelançons la requête précédente en affichant les informations de débug
"&debugQuery=true"
http://localhost:8983/solr/articles/select
?q=content:battlefield AND (author_id:2̂100 OR author_id:3 OR author_id:4)
&fl=id,content,author_id
&debugQuery=true
&indent=true
GroupingLe groupement Solr est équivalant au groupement SQL
Au détail près que l'on ne peut pas grouper sur le plusieurs champs. Parcontre on peut faire plusieurs groupement différent en une requête.
http://localhost:8983/solr/articles/select
?q=content:battlefield
&group=true
&group.field=game_id
&group.limit=3
&fl=id,content
Faceting
Facetinghttp://localhost:8983/solr/articles/select
?q=*:*
&rows=0
&facet=true
&facet.field=author_id
http://localhost:8983/solr/articles/select
?q=*:*
&rows=0
&facet=true
&facet.field=author_id
&facet.limit=3
HighlightMise en avant des termes recherchés au sein du contenus d'un champs
texte.
http://localhost:8983/solr/articles/select
?q=content:battlefield
&fl=content
http://localhost:8983/solr/articles/select
?q=content:battlefield
&fl=content
&hl=true
&hl.q=content:battlefield
&hl.fl=content
Exemples d'autre modulesSpellCheckSuggester (aka Autocomplete)Recherche spaciale
Fin