Le Search à Mappy

  • Elisabeth Benoit
  • Jérôme Bernardes

Le Search à Mappy

  • 3 devs, 3 datas, 1 scrum master
  • 2 services: suggest, search

Avant Solr

uniquement des adresses

  • SQL Server

  • Serveur C++

Maintenant

des adresses et des pois

  • Solr

  • Serveur python

  • Correction d'erreurs en chantier

2013 Création du service de Suggestion

Solr 4.2.1

  • Tentative 1: utilisation du suggester de Solr
    • pas assez flexible
  • Tentative 2: propre suggester créé grâce au modèle http://www.cominvent.com/
    • poids dynamique
    • basé sur les ngrams

q=Rue de Lap

Suggester

Score est le produit du score textuel, de l'importance géographique et de l'importance éditoriale

 

Score = Text x Géo x Market

Bilan d'étape (fin 2013)

  • Familiarisation réussie avec Solr
    • Indexation, update
    • Analyzers, synonymes, ...
    • JVM, GC, caches
  • Un service mis en production
    • 19 ms (temps de réponse moyen)
    • 150 M req / semaine
    • pics de 250 à 300 req / sec / serveur
    • 10 M d'adresses, 4 M de Pois

2014 Création du service Search

Contrairement au suggest

  • Le search doit filtrer les résultats

Luxembourg

On veut

On ne veut pas (contrainte éditoriale)

  • Luxembourg (pays)
  • Luxembourg (région)
  • Luxembourg (département)

Boulogne

On ne veut pas

Rue de Charonne Paris

  • Rue de Charonne Paris

On veut

On ne veut pas (contrainte éditoriale)

  • Boulevard de Charonne Paris
  • Chemin du Parc de Charonne Paris

Search

Frontal Python (Tornado) interroge Solr et filtre les résultats

1er essai

  • Adresses et pois dans le même core Solr
  • Utilisation du geoboost
  • mm permissif
  • spellcheck silencieux

Constat

Nécessaire de trier par score textuel, contrairement au suggest

sort = Text, Geo x Market

q=Bd MacDonald 75019 Paris

Boulevard MacDonald 75019 Paris

T(1) x G(1) x M(1)

 Av. J. Jaurès 75019 Paris

T(0.1) x G(1) x M(100)

Constat

Nécessaire de favoriser la proximité entre les mots

Rue de Charenton Paris

Utilisation du pf2, pf3

Constat

Nécessité d'avoir un exact match boost

Trick pour le exact match

<charFilter class="solr.PatternReplaceCharFilterFactory" 
pattern="^(.*)$" replacement="starts_with_token $1 Ǣ"/>
<str name="pf">exactname^0.01</str>

Dans schema.xml

Dans solrconfig.xml

Constat

Nécessité d'avoir un starts_with boost

Versailles Yvelines

  • Versailles (ville) dans département Yvelines

On veut

On ne veut pas:

  • Tribunal de Versailles Yvelines

Possibilités (avec solr 4.2.1)

  • Utiliser le SurroundQueryParser, mais ne fait pas d'analyse
  • Utiliser un patch (https://issues.apache.org/jira/browse/LUCENE-5014)
  • Utiliser un trick, ie ajouter un token au début de la requête et utiliser pf2 pf3
    • index = starts_with_token versailles
    • query = starts_with_token versailles

Constat

Avec les règles de matching mises en place, certains pois ont des scores ⩾ aux adresses

Rome Italie

On veut

  • Rome (la ville) starts_with

On ne veut pas

  • Garage Rome Italie pf2
  • Passage à deux cores
    • Adresses / POIs
  • Implémentation python d'un code de décision

    • Utilisation du highlighting

    • En chantier : passer à explain

2e essai

q = aux bons crus paris

Adresses :

Rue du Petit <em>Paris</em> <em>Bons</em>-en-Chablais

POIs :

Aux <em>Bons</em> <em>Crus</em> <em>Paris</em>

recherche exacte ok mais problèmes de performance

  • L'utilisation silencieuse du spellchecker à chaque requête plombe les perfs
  • Utilisation du spellchecker uniquement si nécessaire

Mise en Production

Septembre 2014

  • 36 M req /semaine
  • pics de 50 req / sec / serveur
  • 60 ms temps de réponse moyen

En chantier

  • Développer la correction orthographique
  • Dans ce but, se débarrasser du mm permissif
    • Rue de Chraonne
  • Et donc traiter les mots fréquents différemment
    • Rue ~ Avenue ~ Boulevard

 

Avenue de Charonne Paris

On veut

Traitement des mots fréquents

  • 1er essai: mm permissif, avec idf dans score
    • mauvaise détection des fautes
    • starts_with trick a un poids variable
  • 2e essai: utilisation d'un plugin (hon-lucene-synonyms)
    • problèmes de performances
  • 3e essai: indexation des synonymes dans un champ qui a moins de poids

Bilan

  • Un outil puissant mais un sujet complexe
  • Tester, tester, tester
  • Adopté

Merci

boost=add(eps, product(eps2, min(abs(sub(lat,{lat_min})),abs(sub(lat,{lat_max})))...