Blog
L'analyse BigData avec ElasticSearch

Partager

Elasticsearch Logo ElasticSearch a acquis une grande popularité ces dernières années. Sa grande flexibilité en terme de requêtes en fait un allié de choix pour la recherche et l'analyse de données. L'index d'Elasticsearch utilise une technologie NoSQL basée sur Apache LUCENE. Il propose une API RESTful au format JSON avec une architecture distribuée. C'est donc une technologie particulièrement adaptée aux projets BigData.

Le BigData s'intègre à beaucoup de projets aujourd'hui. On entend régulièrement ce terme utilisé comme gage de qualité ou encore comme argument marketing. C'est bien d'avoir une grosse base de données, d'accord, mais encore faut-il savoir quoi en faire !

L'intérêt du BigData réside dans l'information que l'on peut en tirer. Sans des outils adaptés, la visibilité sur les gros volumes de données est presque nulle. C'est là qu'intervient Elasticsearch : en plus de fournir des outils de recherche textuelle basés sur Apache Lucene, Elasticsearch nous propose un autre moyen puissant d'analyser nos données : les agrégations.

La puissance des agrégations

Les agrégations permettent d'agréger un ensemble de documents et d'en extraire des métriques. Elasticsearch nous propose un grand nombre d'agrégations, des plus simples (moyenne, maximum etc.) aux plus complexes (pourcentiles, histogrammes...) et on peut aller encore plus loin grâce à l'intégration de scripts dynamiques directement dans les requêtes !

À l'attaque des données

Imaginons que nous avons un grand nombre d'utilisateurs — ici plus d'un million — enregistrés dans l'index d'Elasticsearch, avec leur position et leur nombre de connexions sous la forme :

{
  "fullname": "Jerry Belly",
  "mail": "jerry.belly@gmail.com",
  "connections": 361,
  "position": {
    "lat": 48.29724731,
    "lon": 4.0786674
  }
}

Nous voudrions déterminer à quel point ces utilisateurs sont éloignés de chez nous. Elasticsearch nous permet d'extraire des informations pertinentes en quelques lignes :

POST: http://elasticsearch.domain.com/index/user/_search 
{
  "aggregations": {
    "geo_distance_percentiles": {
      "percentiles": {
        "script": "doc['position'].distanceInKm(lat, lon)",   // Script (Groovy)
        "params": {                                           // Notre position (latitude, longitude)
          "lat": 48.693378, 
          "lon": 6.178671
        }
      }
    }
  }
}

Un script nous permet de calculer la distance d'un utilisateur, puis cette valeur est traitée par l'agrégation "percentiles". Ici le script est en Groovy mais le langage est au choix entre Groovy, JS, MVEL, Python et Java.

Elasticsearch nous répond :

{
  "aggregations": {
    "geo_distance_percentiles": {
      "values": {
        "1.0": 8.236264535244456,
        "5.0": 105.52412024232123,
        "25.0": 407.20162245888768,
        "50.0": 978.23564877798798,
        "75.0": 2261.13766452675159,
        "95.0": 13329.16873216843576,
        "99.0": 15567.13542168421625
      }
    }
  }
}

Maintenant nous savons par exemple que 75% des utilisateurs habitent à moins de 2261 Km de chez nous.

Les agrégations imbriquées

La puissance des agrégations ne s'arrête pas là : Nous pouvons appliquer une agrégation au résultat d'une première agrégation grâce aux agrégations imbriquées.

Ici nous voulons avoir une idée du nombre de connexions des utilisateurs en fonction de leur distance par rapport à nous. Nous allons utiliser pour cela une première agrégation "range" qui permet de créer des "buckets" (comprenez groupe d'utilisateur) en fonction de leur distance. Ensuite on traitera ces différents buckets grâce à l'agrégation imbriquée "stats" qui nous indiquera des statistiques sur ces groupes.

POST: http://elasticsearch.bigint.fr/index/user/_search 
{
  "aggregations": {
    "geo_distance_ranges": {
      "range": {
        "field": "position",
        "script": "_value.distanceInKm(lat, lon)",   // Script (Groovy)
        "params": {                                  // Notre position (latitude, longitude)
          "lat": 48.693378, 
          "lon": 6.178671
        },
        "ranges": [
          { "to": 100 },
          { "from": 100, "to": 1000 },
          { "from": 1000 }
        ],
        "aggregations": {
          "connections_stats": {
            "stats": {
              "field": "connections"
            }
          }
        }
      }
    }
  }
}

Elasticsearch nous répond :

{
  "aggregations": {
    "geo_distance_ranges": {
      "buckets": [{              // Utilisateurs habitant à moins de 100 Km
        "to": 100,
        "doc_count": 59446,
        "connections_stats": {
          "count": 59446,
          "min": 2,
          "max": 854,
          "avg": 452.3,
          "sum": 26887426
        }
      }, {                       // Utilisateurs habitant de 100 à 1000 Km
        "from": 100,
        "to": 1000,
        "doc_count": 583887,
        "connections_stats": {
          "count": 583887,
          "min": 1,
          "max": 1326,
          "avg": 149.7,
          "sum": 87407884
        }
      }, {                       // Utilisateurs habitant à plus de 1000 Km
        "from": 1000,
        "doc_count": 643333,
        "connections_stats": {
          "count": 643333,
          "min": 1,
          "max": 1112,
          "avg": 124.1,
          "sum": 79837626
        }
      }]
    }
  }
}

Ces statistiques nous permettent, en considérant la valeur "avg" (moyenne du nombre de connexions d'un groupe d'utilisateur), de voir que plus les utilisateurs sont proches de chez nous, plus ils se connectent souvent.

Aller plus loin

Screenshot Kibana Afin de visualiser les données extraites de l'index, il serait utile de les présenter sous une forme un peu plus lisible. Ça tombe bien, Elasticsearch met à notre disposition un outil de visualisation des données directement connecté à l'index elastic : Kibana.

Certaines des agrégations proposées sont à un état expérimental et les développeurs continuent de les faire évoluer. Si vous voulez aller plus loin avec les agrégations, je vous invite à faire un tour sur la doc officielle qui est riche en exemples.

comments powered by Disqus