• 15 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

Ce cours est en vidéo.

Vous pouvez obtenir un certificat de réussite à l'issue de ce cours.

J'ai tout compris !

Mis à jour le 05/01/2019

Interrogez des données textuelles

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Maintenant que nous avons un index "movies2" contenant les informations sur des films du 7ème art, nous pouvons nous intéresser à la manière d’effectuer des recherches via l’API REST d’Elasticsearch.

Une URL simplifiée

Pour cela, nous utiliserons le service “_search” qui sera appliqué à un index (ici movies2) et éventuellement un type (movie). Ensuite, la requête utilise le paramètre “?q=”.  Supposons que je cherche les films de “Star Wars”, cela nous donne l’URL suivante :

http://localhost:9200/movies2/_search?q=Star+Wars

Comme vous pouvez le constater, la requête est très simple, et le résultat est le suivant (pour plus de commodité, je n’affiche ici que les clés “title” et “plot”) :

{
  "took" : 87,
  "timed_out" : false, "_shards" : {"total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0},
  "hits" : {
    "total" : 77,
    "max_score" : 11.224471,
    "hits" : [
      {"_index" : "movies2", "_type" : "movie", "_id" : "371",
        "_score" : 11.224471,
        "_source" : {"fields" : {
            "title" : "Star Wars: Episode III - Revenge of the Sith",
            "plot" : "After three years of fighting in the Clone Wars, Anakin Skywalker falls prey to the Sith Lord's lies and makes an enemy of the Jedi and those he loves, concluding his journey to the Dark Side."}
      }},
      {"_index" : "movies2", "_type" : "movie", "_id" : "168",
        "_score" : 10.601671,
        "_source" : {"fields" : {
            "title" : "Star Wars: Episode VII",
            "plot" : "A continuation of the saga created by George Lucas."}
      }},
      {"_index" : "movies2", "_type" : "movie", "_id" : "782",
        "_score" : 8.290606,
        "_source" : {"fields" : {
            "title" : "Star Wars: Episode VI - Return of the Jedi",
            "plot" : "After rescuing Han Solo from the palace of Jabba the Hutt, the Rebels attempt to destroy the Second Death Star, while Luke Skywalker tries to bring his father back to the Light Side of the Force."}
        }},
      {"_index" : "movies2", "_type" : "movie", "_id" : "226",
        "_score" : 7.8367987,
        "_source" : {"fields" : {
            "title" : "Star Wars",
            "plot" : "Luke Skywalker joins forces with a Jedi Knight, a cocky pilot, a wookiee and two droids to save the universe from the Empire's world-destroying battle-station, while also attempting to rescue Princess Leia from the evil Darth Vader."}
        }},
      {"_index" : "movies2", "_type" : "movie", "_id" : "2088",
        "_score" : 7.8277807,
        "_source" : {"fields" : {
            "title" : "Fanboys",
            "plot" : "Star Wars fanatics take a cross-country trip to [link=nm0000184]' Skywalker Ranch so their dying friend can see a screening of [link=tt0120915] before its release."}
        }},
      {"_index" : "movies2", "_type" : "movie", "_id" : "469",
        "_score" : 6.8894043,
        "_source" : {"fields" : {
            "title" : "Star Wars: Episode I - The Phantom Menace",
            "plot" : "Two Jedi Knights escape a hostile blockade to find allies and come across a young boy who may bring balance to the Force, but the long dormant Sith resurface to reclaim their old glory."}
        }},
      {"_index" : "movies2", "_type" : "movie", "_id" : "651",
        "_score" : 6.8894043,
        "_source" : {"fields" : {
            "title" : "Star Wars: Episode V - The Empire Strikes Back",
            "plot" : "After the rebels have been brutally overpowered by the Empire on their newly established base, Luke Skywalker takes advanced Jedi training with Master Yoda, while his friends are pursued by Darth Vader as part of his plan to capture Luke."}
        }},
      {"_index" : "movies2", "_type" : "movie", "_id" : "922",
        "_score" : 6.8894043,
        "_source" : {"fields" : {
            "title" : "Star Wars: Episode II - Attack of the Clones",
            "plot" : "Ten years later, Anakin Skywalker shares a forbidden romance with Padmé, while Obi-Wan investigates an assassination attempt on the Princess and discovers a secret clone army crafted for the Jedi."}
        }},
      {"_index" : "movies2", "_type" : "movie", "_id" : "2885",
        "_score" : 5.736456,
        "_source" : {"fields" : {
            "title" : "Star Trek 3"}
        }},
      {"_index" : "movies2", "_type" : "movie", "_id" : "4781",
        "_score" : 5.5729313,
        "_source" : {"fields" : {
            "title" : "S1m0ne",
            "plot" : "A producer's film is endangered when his star walks off, so he decides to digitally create an actress to substitute for the star, becoming an overnight sensation that everyone thinks is a real person."}
        }}
     ]
  }
}

Sans surprise, nous retrouvons les différents épisodes de la mythique saga de la Guerre des étoiles, mais également le film Fanboys sur des fans de Star Wars. Par ailleurs, un score est fourni pour chaque document, il correspond au calcul que nous avons vu dans le chapitre suivant (avec une petite variante). Ce qui nous amène à regarder les deux derniers résultats : Star Trek 3 et S1m0ne. Le résultat est pour le moins inattendu. Si l’on regarde bien, le titre ou le résumé contiennent le mot “star” ou “wars”, donnant lieu à un score plus faible que les documents précédents.

De fait, il serait plus pertinent de filtrer sur le titre des films. Ce titre est présent dans la clé "fields.title" du document. La requête devient alors :

http://localhost:9200/movies2/_search?q=fields.title:Star Wars

Cette fois-ci, le résultat fait apparaître les documents Star Trek, Lone Star et Dark Star, mais avec un score plus faible.

Attaquons-nous maintenant aux requêtes sur des listes de valeurs telles que les acteurs. Nous voudrions les films dans lesquels a joué Harrison Ford :

http://localhost:9200/movies2/_search?q=fields.actors:Harrison Ford

Nous pouvons voir que l’on ne fait pas de différence entre une clé contenant du texte, ou une liste de texte (même au format raw). Nous pourrions également chercher plus de résultats en rajoutant le paramètre "size" :

http://localhost:9200/movies2/_search?q=fields.actors:Harrison Ford&size=20

Essayons maintenant les films films dont le titre contenant "Star Wars" ET dont le réalisateur est George Lucas. Il faut alors ajouter la condition "AND" entre les deux critères sur les clés ciblées. Ce qui nous donne :

http://localhost:9200/movies2/_search?q=fields.title:Star Wars AND fields.directors:George Lucas

{
  "took": 40,
  "timed_out": false,
  "_shards": {"total": 5, "successful": 5, "skipped": 0, "failed": 0},
  "hits": {
    "total": 4,
    "max_score": 19.122818,
    "hits": [
      {"_index": "movies2", "_type": "movie", "_id": "371",
        "_score": 19.122818,
        "_source": {"fields": {
            "directors": [ "George Lucas" ],
            "title": "Star Wars: Episode III - Revenge of the Sith"}
        }},
      {"_index": "movies2", "_type": "movie", "_id": "226",
        "_score": 17.52296,
        "_source": {"fields": {
            "directors": [ "George Lucas" ],
            "title": "Star Wars}
        }},
      {"_index": "movies2", "_type": "movie", "_id": "469",
        "_score": 15.000907,
        "_source": {"fields": {
            "directors": ["George Lucas" ],
            "title": "Star Wars: Episode I - The Phantom Menace"}
        }},
      {"_index": "movies2", "_type": "movie", "_id": "922",
        "_score": 14.387882,
        "_source": {"fields": {
            "directors": [ "George Lucas" ],
            "title": "Star Wars: Episode II - Attack of the Clones"}
        }}
    ]
  }
}

Revenons à Harrison Ford, et regardons ceux dont le résumé parle de "Jones" :

http://localhost:9200/movies2/_search?q=fields.actors:Harrison Ford AND fields.plot:Jones

Là, seulement 3 résultats sont produits. Le fait d’avoir créé une requête booléenne avec le "AND" filtre les résultats n’ayant pas de score dans chacune des clés demandées.

Et maintenant, je voudrais parmi ceux-ci, uniquement ceux qui ne parlent pas de "Nazis". Il faut alors rajouter la recherche avec la négation "-" avec la clé et le mot à rejeter :

http://localhost:9200/movies2/_search?q=actors=Harrison Ford AND fields.plot:Jones AND -fields.plot:Nazis

Cette fois-ci, nous trouvons le formidable Indiana Jones et le temple maudit qui se déroule en Inde.

Des requêtes subtiles

Les requêtes précédentes restent rudimentaires et correspondent à ce qu’un moteur de recherche traditionnel sait faire. Nous voudrions maintenant être capable d’effectuer des requêtes plus complexes avec des variantes sur la présence des mots ("devrait"/"doit"), ou des filtres sur des plages de valeurs.

Pour cela, nous allons utiliser le langage d’Elasticsearch, qui est écrit sous forme d’un document JSON. Pour ce faire, nous allons écrire chaque requête JSON dans un fichier, que nous allons passer en paramètre à l’API REST grâce à l’utilitaire curl que nous avons utilisé dans le chapitre précédent.

Requêtes classiques

Reprenons donc la requête sur les films de Star Wars. Celle-ci s’écrit sous la forme :

{
    "query":{
        "match":{
            "fields.title":"Star Wars"
        }
    }
}

C’est donc une requête d’interrogation (query) dont les documents doivent correspondre (match) à un titre (fields.title) contenant "Star Wars".

On enregistre le document dans un fichier "query1", que l’on va passer en paramètre "-d @query1" et exécuter avec la commande suivante :

curl -XGET -H "Content-Type: application/json" 'localhost:9200/movies2/movie/_search?pretty' -d @query1

Nous retrouvons bien le résultat obtenu avec la première requête en mode classique. Donc pour chacune des requêtes ci-dessous, il faudra enregistrer la requête dans un fichier, et le passer en paramètre.

Continuons avec la seconde requête que nous avions produite avec George Lucas comme réalisateur et qui peut être écrite de la manière suivante :

{"query":{
    "bool": {
        "should": [
            { "match": { "fields.title": "Star Wars" }},
            { "match": { "fields.directors": "George Lucas" }}
        ]
}}}

Nous avons donc une requête booléenne ("bool") pour laquelle le document devrait ("should") avoir le titre "Star Wars" et le réalisateur "George Lucas". La subtilité vient du filtre conditionnel produisant ainsi un score et triant le résultat sur celui-ci. Si vous souhaitez être plus restrictif et obliger le nom du réalisateur, il faut effectuer une requête de type "must" (doit) sur la clé fields.directors, comme ci-dessous :

{"query":{
    "bool": {
        "should": { "match": { "fields.title": "Star Wars" }},
        "must" :  { "match": { "fields.directors": "George Lucas" }}
}}}

Mais là encore, d’autres films vont apparaître (filtre sur le titre), avec un score beaucoup plus faible.

Il est également possible de rechercher des séquences de mots (ou phrases) dans un texte, pour forcer l’ordre de "Star" puis "Wars" avec la clé "match_phrase" :

{"query":{
    "bool": {
        "should": [
            { "match_phrase": { "fields.title": "Star Wars" }},
            { "match": { "fields.directors": "George Lucas" }}
        ]
}}}

On pourra également réécrire la requête avec Harrison Ford :

{  "query": {
    "match": 
        {"fields.actors":"Harrison Ford"}
}}

Ou celle où il a joué le rôle d’Indiana Jones :

{"query":{
    "bool": {
        "should": [
            { "match": { "fields.actors": "Harrison Ford" }},
            { "match": { "fields.plot": "Jones" }}
        ]
}}}

  Voire même interdire l’utilisation du mot "Nazis" avec la clé "must_not" :

{"query":{
    "bool": {
        "should": [
            { "match": { "fields.actors": "Harrison Ford" }},
            { "match": { "fields.plot": "Jones" }}
        ],
        "must_not" : { "match" : {"fields.plot":"Nazis"}}
}}}

Requêtes avec "range"

Intéressons-nous maintenant aux filtres sur des valeurs numériques. Nous souhaitons retrouver les films de James Cameron dont le rang (fields.rank) est inférieur à 1000. Pour cela, le filtre s’effectue avec la clé "range" avec un "plus petit que" ("lt", less than) :

{"query":{
    "bool": {
            "should": [
                { "match": { "fields.directors": "James Cameron" }},
                { "range": { "fields.rank": {"lt":1000 }}}
           ]
}}}

Nous obtenons le résultat suivant (projection sur les clés directors, title et rank) :

{
  "took":52,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0, "failed":0},
  "hits" : {
    "total" : 1039,
    "max_score" : 10.376579,
    "hits" : [
      {
        "_index" : "movies2", "_type" : "movie", "_id" : "420",
        "_score" : 10.376579,
        "_source" : {"fields" : {"directors" : [ "James Cameron" ],
            "title" : "Terminator 2: Judgment Day","rank" : 420}
        }
      },
      {
        "_index" : "movies2", "_type" : "movie", "_id" : "678",
        "_score" : 10.376579,
        "_source" : {"fields" : {"directors" : [ "James Cameron" ],
            "title" : "The Terminator","rank" : 678}
        }
      },
      {
        "_index" : "movies2", "_type" : "movie", "_id" : "111",
        "_score" : 9.760926,
        "_source" : {"fields" : {"directors" : [ "James Cameron" ],
            "title" : "Titanic","rank" : 111}
        }
      },
      {
        "_index" : "movies2", "_type" : "movie", "_id" : "909",
        "_score" : 9.760926,
        "_source" : {"fields" : {"directors" : [ "James Cameron" ],
            "title" : "Avatar 2","rank" : 909
        }
      },
      {
        "_index" : "movies2", "_type" : "movie", "_id" : "283",
        "_score" : 9.710734,
        "_source" : {"fields" : {"directors" : [ "James Cameron" ],
            "title" : "Avatar","rank" : 283}
        }
      },
      {
        "_index" : "movies2", "_type" : "movie", "_id" : "552",
        "_score" : 9.710734,
        "_source" : {"fields" : {"directors" : [ "James Cameron" ],
            "title" : "Aliens","rank" : 552}
        }
      },
      {
        "_index" : "movies2", "_type" : "movie", "_id" : "2067",
        "_score" : 9.614885,
        "_source" : {"fields" : {"directors" : [ "James Cameron" ],
            "title" : "True Lies","rank" : 2067}
        }
      },
      {
        "_index" : "movies2", "_type" : "movie", "_id" : "2470",
        "_score" : 9.376579,
        "_source" : {"fields" : {"directors" : [ "James Cameron" ],
            "title" : "The Abyss","rank" : 2470,}
        }
      },
      {
        "_index" : "movies2", "_type" : "movie", "_id" : "599",
        "_score" : 6.7030363,
        "_source" : {"fields" : {"directors" : [ "Cameron Crowe" ],
            "title" : "Almost Famous","rank" : 599}
        }
      },
      {
        "_index" : "movies2", "_type" : "movie", "_id" : "567",
        "_score" : 6.0453296,
        "_source" : {"fields" : {"directors" : [ "Cameron Crowe" ],
            "title" : "We Bought a Zoo","rank" : 567}
        }
      }
    ]
  }
}

Quel surprise de retrouver les films True  Lies et Abyss avec un score supérieur à 1000 (même si ce sont de bons films). De même, le réalisateur Cameron Crowe répond à la question. Il faut donc être plus filtrant et forcer la restriction avec la clé "must" :

{"query":{
    "bool": {
        "must": [
            { "match": { "fields.directors": "James Cameron" }},
            { "range": { "fields.rank": {"lt":1000 }}}
        ]
}}}

 Là encore, il reste les films de James Bobin ou Cody Cameron dans le résultat. Soyons précis et faisons un "match_phrase" sur le réalisateur :

{"query":{
    "bool": {
        "must": [
            { "match_phrase": { "fields.directors": "James Cameron" }},
            { "range": { "fields.rank": {"lt":1000 }}}
        ]
}}}

Cherchons maintenant les films de James Cameron dont la note (fields.rating) doit être supérieure à 5, mais sans être un film d'action ni dramatique (fields.genre). Il faut donc utiliser la clé "must_not", et une liste de "match" (un par genre).

{"query":{
    "bool": {
        "should": { "match": { "fields.directors": "James Cameron" }},
        "must":{ "range": { "fields.rating": {"gte":5 }}},
        "must_not":[
            {"match":{"fields.genres":"Action"}},
            {"match":{"fields.genres":"Drama"}}
        ]
}}}

 Le résultat ne contient aucun film de James Cameron, mais de nombreux autres films avec une note supérieure à 5, mais qui ne sont ni d’action ni dramatiques. Nous retrouvons naturellement les réalisateurs avec "James" ou "Cameron". C’est tout simplement dû au fait que James Cameron ne fait que des films d’action et/ou dramatique. Ce qui est intéressant c’est que, malgré tout, un résultat est renvoyé.

Effectuons maintenant une recherche sur les films de J.J. Abrams sortis entre 2010 et 2015 (fields.release_date). La clé "filter" sera alors appliquée avec un sous-document de type "range" avec une date de départ (from) et une date de fin (to). Nous pouvons remarquer que le format date est automatiquement reconnu dans la recherche :

{
    "query": {
        "bool":{
            "must": {"match": {"fields.directors": "J.J. Abrams"}},
            "filter": {"range": {"fields.release_date":
                { "from": "2010-01-01", "to": "2015-12-31"}}}
}}}

Comment agréger du texte

Maintenant que nous savons effectuer des filtres pour trouver les documents pertinents par rapport à nos besoins, nous pouvons aller une étape plus loin pour être capable de produire des agrégations sur ces résultats. Cela nous permettra de fournir des statistiques sur le contenu de la base de données, que nous utiliserons dans le chapitre 4 avec Kibana.

Agrégats simples

Pour commencer, nous voudrions produire pour chaque année, le nombre de films sortis. Pour cela, nous utiliserons la clé "aggs" qui va produire un document "nb_par_annee" avec pour chaque année (fields.year), le nombre de document (seule la clé "terms" est nécessaire) :

{"aggs" : {
    "nb_par_annee" : {
        "terms" : {"field" : "fields.year"}
}}}

Le résultat est décomposé en deux parties. La première donne un sous ensemble des documents utilisés en entrée de l’agrégat (ici tout l’index "movies2"). La seconde partie est le résultat attendu :

{
    … ,
  "aggregations" : {
    "nb_par_annee" : {
      "doc_count_error_upper_bound" : 54,
      "sum_other_doc_count" : 2192,
      "buckets" : [
        { "key" : 2013, "doc_count" : 448 },
        { "key" : 2012, "doc_count" : 404 },
        { "key" : 2011, "doc_count" : 308 },
        { "key" : 2009, "doc_count" : 253 },
        { "key" : 2010, "doc_count" : 249 },
        { "key" : 2008, "doc_count" : 207 },
        { "key" : 2006, "doc_count" : 204 },
        { "key" : 2007, "doc_count" : 200 },
        { "key" : 2005, "doc_count" : 170 },
        { "key" : 2014, "doc_count" : 152 }
      ]
    }
  }
}

Le document "nb_par_annee" est donc produit, avec pour chaque "key" l’année correspondante et le nombre de documents de l’index. Remarquez que les dates ne sont pas triées.

Calculons maintenant la note moyenne des films. Pour cela, nous utiliserons la fonction d’agrégation "avg" sur la clé "fields.rating" :

{"aggs" : {
    "note_moyenne" : {
        "avg" : {"field" : "fields.rating"}
}}}

Combinaison de fonctions d'agrégats

Si maintenant, nous souhaitons afficher la note moyenne et le rang moyen des films de George Lucas, il faut ajouter, avant la clé "aggs", notre requête avec la clé "query" :

{
    "query" :{
        "match" : {"fields.directors" : "George Lucas"}
    },
    "aggs" : {
            "note_moyenne" : {
                        "avg" : {"field" : "fields.rating"}
            },
            "rang_moyen" : {
                        "avg" : {"field" : "fields.rank"}
            }
}}

 Notez bien que dans le résultat, nous allons prendre en compte les films de George Miller… Un filtre de type "must" avec un "match_phrase" serait plus approprié dans ce cas.

Allons encore plus loin en calculant par année, la note moyenne des films. Il faut pour cela agréger par date, puis dans ce sous-groupe, agréger (2ème "aggs") avec la clé "avg" :

{"aggs" : {
    "group_year" : {
        "terms" : {"field" : "fields.year"},
        "aggs" : {
            "note_moyenne" : {"avg" : {"field" : "fields.rating"}}
        }
}}}

Il est également possible de combiner plusieurs fonctions d’agrégat en sortie, en spécifiant à chaque fois le nom de la clé (note_moyenne, note_min, note_max) :

{"aggs" : {
    "group_year" : {
        "terms" : { "field" : "fields.year" },
        "aggs" : {
            "note_moyenne" : {"avg" : {"field" : "fields.rating"}},
            "note_min" : {"min" : {"field" : "fields.rating"}},
            "note_max" : {"max" : {"field" : "fields.rating"}}
        }
}}}

Tri de résultats

Pour effectuer un tri sur la note moyenne des films, il faut d'abord calculer cette moyenne ("avg" sur "fields.rating"), et définir un ordre (clé "order") sur la clé produite pour la moyenne "note_moyenne". L’ordre des moyennes sera classé de manière descendante (desc) :

{"aggs" : {
    "group_year" : {
        "terms" : {
            "field" : "fields.year",
            "order" : { "note_moyenne" : "desc" }
        },
        "aggs" : {
            "note_moyenne" : {"avg" : {"field" : "fields.rating"}}
        }
}}}

Agrégats par plages de valeurs

Nous avons jusqu’ici effectué des agrégats sur des valeurs, à l’aide de la clé "terms" sur le champ souhaité. Il est également possible de faire des agrégats sur des plages de valeurs. Il faut pour cela créer un "group_range" avec les bornes de chaque plage ("from" / "to"). Nous allons donc calculer le nombre de notes par plage de taille 2 :

{"aggs" : {
    "group_range" : {
        "range" : {
            "field" : "fields.rating",
            "ranges" : [
                {"to" : 1.9},
                {"from" : 2, "to" : 3.9},
                {"from" : 4, "to" : 5.9},
                {"from" : 6, "to" : 7.9},
                {"from" : 8}
            ]
}}}}

Agrégats de type raw

On souhaite savoir maintenant les genres comportant le plus de films. Mais voilà, la clé "fields.genre" est une liste de valeurs, de base il n’est pas possible d’effectuer des groupements sur des listes. Sauf que rappelez-vous, nous avons effectué un mapping dans le chapitre précédent ! Et justement, nous avons précisé que "genres" devaient être gardés comme type "raw". De fait, il est possible d’effectuer un groupement sur le genre, mais en précisant ce "raw" :

{"aggs" : {
    "nb_per_genres" : {
        "terms" : {"field" : "fields.genres.raw"}
}}}

De même, nous pouvons utiliser le réalisateur comme clé de groupement puisque le mapping a été fait de type "raw" pour ses données qui peuvent nous servir lors de l’agrégation.

{"aggs" : {
    "nb_per_director" : {
        "terms" : {"field" : "fields.directors.raw"}
}}}

Idem avec les acteurs, mais nous aimerions cette fois-ci avoir la note moyenne, le rang min et max des films dans lesquels ils ont joués :

{"aggs" : {
    "group_actors" : {
        "terms" : {
            "field" : "fields.actors.raw"
        },
        "aggs" : {
            "note_moyenne" : {"avg" : {"field" : "fields.rating"}},
            "rang_min" : {"min" : {"field" : "fields.rank"}},
            "rang_max" : {"max" : {"field" : "fields.rank"}}
        }
}}}

Ne vous y trompez-pas, les acteurs sont triés automatiquement par le nombre de documents correspondant et non la note moyenne. Les 30 premiers acteurs (ayant joués dans le plus de films de l’index) sont affichés, nous pouvons voir qu’il y a 14 106 autres acteurs dans cette liste.

{  "aggregations" : {
    "group_actors" : {
      "doc_count_error_upper_bound" : 30,
      "sum_other_doc_count" : 14106,
      "buckets" : [
        {"key" : "Robert De Niro",
         "doc_count" : 43,
         "rang_max" : { "value" : 4795.0 },
         "rang_min" : { "value" : 15.0 },
         "note_moyenne" : { "value" : 7.040000009536743 }
        },
        {"key" : "Nicolas Cage",
         "doc_count" : 34,
         "rang_max" : { "value" : 4916.0 },
         "rang_min" : { "value" : 91.0 },
         "note_moyenne" : {"value" : 6.228124991059303}
        },
        {"key" : "Bruce Willis",
         "doc_count" : 31,
         "rang_max" : {"value" : 4350.0},
         "rang_min" : {"value" : 139.0},
         "note_moyenne" : {"value" : 6.6066666603088375}
        },
        {"key" : "Johnny Depp",
         "doc_count" : 31,
         "rang_max" : {"value" : 4913.0},
         "rang_min" : {"value" : 113.0},
         "note_moyenne" : {"value" : 6.90370367191456}
        },
        {"key" : "Morgan Freeman",
         "doc_count" : 26,
         "rang_max" : {"value" : 4949.0},
         "rang_min" : {"value" : 80.0},
         "note_moyenne" : {"value" : 6.870833337306976}
        },
        {"key" : "Adam Sandler",
         "doc_count" : 25,
         "rang_max" : {"value" : 4201.0},
         "rang_min" : {"value" : 98.0},
         "note_moyenne" : {"value" : 5.841666688521703}
        },
        {"key" : "Matt Damon",
         "doc_count" : 25,
         "rang_max" : {"value" : 3616.0},
         "rang_min" : {"value" : 28.0},
         "note_moyenne" : {"value" : 7.2434783396513565}
        },
        {"key" : "Tom Hanks",
         "doc_count" : 24,
         "rang_max" : {"value" : 4871.0},
         "rang_min" : {"value" : 101.0},
         "note_moyenne" : {"value" : 7.24545448476618}
        },
        {"key" : "Tom Cruise",
         "doc_count" : 23,
         "rang_max" : {"value" : 3944.0},
         "rang_min" : {"value" : 225.0},
         "note_moyenne" : {"value" : 6.933333306085496}
        },
        {"key" : "Denzel Washington",
         "doc_count" : 22,
         "rang_max" : {"value" : 4426.0},
         "rang_min" : {"value" : 176.0},
         "note_moyenne" : {"value" : 6.9333333514985585}
        }
      ]
    }
  }
}

Vous serez surpris par le résultat retourné si vous triez le résultat par note moyenne décroissante. Je vous invite à la tester, et surtout à comprendre le résultat ;)

Maintenant que vous avez compris les subtilités du langage de requête d’Elasticsearch, vous allez pouvoir interroger votre base de données. D’autres fonctionnalités sont disponibles ici (Elasticsearch évolue constamment). Mais avant toute chose, il faut regarder comment on va pouvoir passer à l’échelle en répartissant notre base de données sur plusieurs serveurs.

Exemple de certificat de réussite
Exemple de certificat de réussite