Slide 1

Slide 1 text

BreizhCamp 2015 #BzhCmp BreizhCamp 2015 #BzhCmp Comment (ne pas réussir à) modéliser ses data dans Elasticsearch! Bruno Bonnin - @_bruno_b_

Slide 2

Slide 2 text

$ whoami Bruno Bonnin > Plus de 15 ans dans les télécoms (dev, archi, pompier) > Aujourd’hui @_bruno_b_ github.com/bbonnin

Slide 3

Slide 3 text

Il était une fois un assureur…

Slide 4

Slide 4 text

Le contexte Contrats Personnes TEL LDAP Copie entre systèmes Navigation entre clients

Slide 5

Slide 5 text

Le puits de données avec Elastic ! Contrats Personnes TEL LDAP Search-based Apps Consultation uniquement, les systèmes d’origine restent maîtres de la donnée

Slide 6

Slide 6 text

ELK : La triplette de la mort !

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

Quelques questions à se poser… • Les usages ? Partiellement connus… • Vue 360° du sociétaire • Recherche sur des référentiels • Ça arrive au fur et à mesure… • Quelles données ? Toutes (ou presque) ! • De multiple sources de données, complexes à croiser • Des contraintes techniques ? Système des mises à jour imposé ! • Messages générés à partir des updates issus des différents système, sans garanti d’ordre • Problème potentiel de mises à jour des documents dans ES (cas nested : conteneur de la donnée pas encore présente dans le puits)

Slide 9

Slide 9 text

Alimentation Du Puits de données Focus : mises à jour du puits Contrats Personnes TEL LDAP JMS Fil de l’eau Batch

Slide 10

Slide 10 text

Quel modèle pour elastic ? Sinistres TEL Contrats Personnes ?

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

« La brute » ? Un seul type de document ! { "nom" : "Haddock", "prenom" : "Archibald", "age" : 56, "contrats" : [ { "formule" : "assur_auto", "bien" : { "immatriculation" : "1-AAA-99", "modele" : "peugeot 504", } "garanties" : [ ... ], }, { … } ], "sinistres" : [ { … }, { … } ] } Doc Societaire

Slide 13

Slide 13 text

« La brute » ? Un seul type de document ! { "nom" : "Haddock", "prenom" : "Archibald", "age" : 56, "contrats" : [ { "formule" : "assur_auto", "bien" : { "immatriculation" : "1-AAA-99", "modele" : "peugeot 504", } "garanties" : [ ... ], }, { … } ], "sinistres" : [ { … }, { … } ] } Doc Societaire Personnes Contrats Sinistres

Slide 14

Slide 14 text

« La brute » ? Un seul type de document ! { "query" : { "nested" : { "path" : "contrats", "query" : { "bool" : { "must" : [ { "match" : { "contrats.formule" : “assur_auto" }, "match" : { "contrats.bien.modele" : "peugeot 504" } ] } } } } } } { "societaire" : { "properties" : { "contrats" : { "type" : "nested ", "properties" : { "formule" : { "type" : "string“ }, "bien" : { … }, … } }, "sinistres" : { "type" : "nested" } } } } Mapping Query

Slide 15

Slide 15 text

« La brute » ? Un seul type de document ! Avantage(s) : • Avec une seule requête, on récupère l’ensemble des données d’un sociétaire • Requêtes complexes sur les sous-documents Désavantage(s) : • La mise à jour ! • Temps de ré-indexation • Complexité (quid des messages concernant un sous- partie sans le document conteneur ?) • Vue orientée « sociétaire » : quid des use cases orientés « contrat » ?

Slide 16

Slide 16 text

« La brute » ? Un seul type de document ! Avantage(s) : • Avec une seule requête, on récupère l’ensemble des données d’un sociétaire • Requêtes complexes sur les sous-documents Désavantage(s) : • La mise à jour ! • Temps de ré-indexation • Complexité (quid des messages concernant un sous- partie sans le document conteneur ?) • Vue orientée « sociétaire » : quid des use cases orientés « contrat » ?

Slide 17

Slide 17 text

« Le truand » ? Un doc par objet source { "num_soc" : "1234", "nom" : "Haddock", "prenom" : "Archibald", "age" : 56 } Sociétaire { "num_contrat" : "6789", "type" : "auto", "immatriculation" : "1-AAA-99", "modele" : "peugeot 504", "num_soc" : "1234" } Contrat { "num_contrat" : "6789", … } Garantie { "num_soc" : "1234", … } Sinistre

Slide 18

Slide 18 text

« Le truand » ? Un doc par objet source { "num_soc" : "1234", "nom" : "Haddock", "prenom" : "Archibald", "age" : 56 } Sociétaire { "num_contrat" : "6789", "type" : "auto", "immatriculation" : "1-AAA-99", "modele" : "peugeot 504", "num_soc" : "1234" } Contrat { "num_contrat" : "6789", … } Garantie Personne Contrats Contrats { "num_soc" : "1234", … } Sinistre Sinistres

Slide 19

Slide 19 text

« Le truand » ? Un doc par objet source GET /societaire,contrats/_search { "query" : { “term" : { “num_soc" : “1234" } } } Query … { "_index" : “assureur", "_type" : "contrats", "_id" : "2045", "_score" : 4.4011974, "_source“ : { "num_contrat" : "2045", "num_soc" : “1234", "type" : "assur_maison", "bien" : { "type" : "chateau", "adresse" : “moulinsart" } } } ] } "hits" : { "total" : 2, "max_score" : 4.417726, "hits" : [ { "_index" : “assureur", "_type" : "societaire", "_id" : "45", "_score" : 4.417726, "_source“ : { "num_soc" : “1234", "nom" : "haddock" } }, … Result Recherche sur 2 types de docs en utilisant le champ commun « num_soc »

Slide 20

Slide 20 text

« Le truand » ? Un doc par objet source Avantage(s) : • Facile à mettre à jour (1 type de doc correspond à 1 type de message) Désavantage(s) : • Requêtage : devient vite complexe pour avoir une information complète • Multiplication des requêtes côté client pour reconstituer le modèle

Slide 21

Slide 21 text

« Le truand » ? Un doc par objet source Avantage(s) : • Facile à mettre à jour (1 type de doc correspond à 1 type de message) Désavantage(s) : • Requêtage : devient vite complexe pour avoir une information complète • Multiplication des requêtes côté client pour reconstituer le modèle

Slide 22

Slide 22 text

« Le bon » ? Un mix nested et parent/child { "num_soc" : "1234", "nom" : "Haddock", "prenom" : "Archibald", "age" : 56 } Sociétaire { "num_contrat" : "6789", "type" : "maison", "bien" : { "type" : "chateau", "localisation" : "moulinsart" } "garanties" : [ {…}, {…} ] } Contrat

Slide 23

Slide 23 text

« Le bon » ? Un mix nested et parent/child { "num_soc" : "1234", "nom" : "Haddock", "prenom" : "Archibald", "age" : 56 } Sociétaire { "num_contrat" : "6789", "type" : "maison", "bien" : { "type" : "chateau", "localisation" : "moulinsart" } "garanties" : [ {…}, {…} ] } Contrat Personnes Contrats parent=1234 Relation parent/child entre des docs liés mais vivant indépendamment Contrat complet avec nested docs car forte dépendance

Slide 24

Slide 24 text

« Le bon » ? Un mix nested et parent/child { "societaire" : { … }, "contrat" : { “_parent” : { "type" : “societaire“ }, "properties" : { “bien" : { "type" : "nested" }, “garanties" : { "type" : "nested" } } Mapping PUT /contrat/6789?parent=1234 { "num_soc" : "1234", "type" : "assur_maison", "bien" : { "type" : "chateau", "adresse" : "moulinsart", }, "garanties" : [] } Indexation Déclaration du parent

Slide 25

Slide 25 text

« Le bon » ? Un mix nested et parent/child GET /societaire/_search { “query” : { “has_child" : { “type” : “contrat”, "query" : { "match" : { “bien.adresse" : “moulinsart" } } }, "inner_hits" : {} } } } Query … "inner_hits" : { "contrats" : { "hits" : { "total" : 1, "max_score" : 3.4336133, "hits" : [ { "_index" : “assureur", "_type" : "contrat", "_id" : “6789", "_score" : 3.4336133, "_source“ : { "num_contrat" : “6789", "num_soc" : “1234", "type" : "assur_maison", "bien" : { "type" : "chateau", "adresse" : "moulinsart" } } } ] { "_index" : “assureur", "_type" : "societaire", "_id" : “1234", "_score" : 1.0, "_source“ : { "num_soc" : “1234", "nom" : "haddock" }, … Result « inner_hits » (new 1.5) : permet d’avoir les contrats en plus des sociétaires dans le résultat

Slide 26

Slide 26 text

« Le bon » ? Un mix nested et parent/child Avantage(s) : • Modèle permettant de répondre à la plupart des usages (orienté sociétaire ou contrat) • Séparation de documents ayant des cycles de vie différents • Avec inner_hits, capacité à retrouver des documents liés entre eux facilement Désavantage(s) : • Requêtes plus lentes pour les docs liés par une lien parent/enfant • Elastic met en mémoire la table des liens

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

Cluster Elastic Architecture Nœud sans data Nœud data 1 Nœud data 2 Shield Marvel Alim puits de données 1 Alim puits de données 2 JMS … Taille des index (mesure PoC) : 400 Go

Slide 29

Slide 29 text

En résumé Penser « usages » est primordial ! Utiliser les nested documents pour des données ayant un lien fort, avec le même cycle de vie • Ne pas hésiter à dupliquer Utiliser les liens parents/enfants sur les documents pouvant vivre indépendamment les uns des autres • Requêtes avec « inner_hits » Tenir compte des contraintes techniques de votre env

Slide 30

Slide 30 text

MERCI ! Crédit photos : https://www.flickr.com/photos/hoyvinmayvin