Mappings ElasticSearch

De EjnTricks
Révision de 22 mai 2018 à 13:18 par Etienne (discussion | contributions)

(diff) ← Version précédente | Voir la version courante (diff) | Version suivante → (diff)

Les mappings permettent de configurer le type des propriétés dans les indexes. Ceci permet par exemple de spécifier les champs de type géolocalisation lors de la lecture des fichiers trace par Logstash.

Cet article présente l'utilisation de ces mappings.


Hand-icon.png Votre avis

Nobody voted on this yet

 You need to enable JavaScript to vote


Icon-database-search.png Recherche

Il existe deux moyens de récupérer un mapping associés à un index.

Le premier consiste à utiliser l'API _template en spécifiant le nom de l'index. L'exemple suivant présente la récupération du mapping pour l'indexe logstash.

#curl -X GET "localhost:9200/_template/logstash?pretty"
{
  "logstash" : {
    "order" : 0,
    "version" : 60001,
    "index_patterns" : [
      "logstash-*"
    ],
    "settings" : {
      "index" : {
        "refresh_interval" : "5s"
      }
    },
    "mappings" : {
      "_default_" : {
        "dynamic_templates" : [
          {
            "message_field" : {
              "path_match" : "message",
              "match_mapping_type" : "string",
              "mapping" : {
                "type" : "text",
                "norms" : false
              }
            }
          },
          {
            "string_fields" : {
              "match" : "*",
              "match_mapping_type" : "string",
              "mapping" : {
                "type" : "text",
                "norms" : false,
                "fields" : {
                  "keyword" : {
                    "type" : "keyword",
                    "ignore_above" : 256
                  }
                }
              }
            }
          }
        ],
        "properties" : {
          "@timestamp" : {
            "type" : "date"
          },
          "@version" : {
            "type" : "keyword"
          },
          "geoip" : {
            "dynamic" : true,
            "properties" : {
              "ip" : {
                "type" : "ip"
              },
              "location" : {
                "type" : "geo_point"
              },
              "latitude" : {
                "type" : "half_float"
              },
              "longitude" : {
                "type" : "half_float"
              }
            }
          }
        }
      }
    },
    "aliases" : { }
  }
}

La définition du mapping est disponible dans le noeud mappings.

Pour optenir un affichage plus compact, il suffit de supprimer l'argument pretty dans la requête.

#curl -X GET "localhost:9200/_template/logstash" {"logstash":{"order":0,"version":60001,"index_patterns":["logstash-*"],"settings":{"index":{"refresh_interval":"5s"}},"mappings":{"_default_":{"dynamic_templates":[{"message_field":{"path_match":"message","match_mapping_type":"string","mapping":{"type":"text","norms":false}}},{"string_fields":{"match":"*","match_mapping_type":"string","mapping":{"type":"text","norms":false,"fields":{"keyword":{"type":"keyword","ignore_above":256}}}}}],"properties":{"@timestamp":{"type":"date"},"@version":{"type":"keyword"},"geoip":{"dynamic":true,"properties":{"ip":{"type":"ip"},"location":{"type":"geo_point"},"latitude":{"type":"half_float"},"longitude":{"type":"half_float"}}}}}},"aliases":{}}}


Le second moyen est de rechercher le mapping pour un indexe existant. Dans l'exemple suivant, le mapping pour l'indexe .kibana est demandé.

#curl -X GET "localhost:9200/.kibana/_mapping"
{".kibana":{"mappings":{"doc":{"dynamic":"strict","properties":{"config":{"dynamic":"true","properties":{"buildNum":{"type":"keyword"},"dashboard:defaultDarkTheme":{"type":"boolean"},"defaultIndex":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}}},"dashboard":{"properties":{"description":{"type":"text"},"hits":{"type":"integer"},"kibanaSavedObjectMeta":{"properties":{"searchSourceJSON":{"type":"text"}}},"optionsJSON":{"type":"text"},"panelsJSON":{"type":"text"},"refreshInterval":{"properties":{"display":{"type":"keyword"},"pause":{"type":"boolean"},"section":{"type":"integer"},"value":{"type":"integer"}}},"timeFrom":{"type":"keyword"},"timeRestore":{"type":"boolean"},"timeTo":{"type":"keyword"},"title":{"type":"text"},"uiStateJSON":{"type":"text"},"version":{"type":"integer"}}},"index-pattern":{"properties":{"fieldFormatMap":{"type":"text"},"fields":{"type":"text"},"intervalName":{"type":"keyword"},"notExpandable":{"type":"boolean"},"sourceFilters":{"type":"text"},"timeFieldName":{"type":"keyword"},"title":{"type":"text"}}},"search":{"properties":{"columns":{"type":"keyword"},"description":{"type":"text"},"hits":{"type":"integer"},"kibanaSavedObjectMeta":{"properties":{"searchSourceJSON":{"type":"text"}}},"sort":{"type":"keyword"},"title":{"type":"text"},"version":{"type":"integer"}}},"server":{"properties":{"uuid":{"type":"keyword"}}},"timelion-sheet":{"properties":{"description":{"type":"text"},"hits":{"type":"integer"},"kibanaSavedObjectMeta":{"properties":{"searchSourceJSON":{"type":"text"}}},"timelion_chart_height":{"type":"integer"},"timelion_columns":{"type":"integer"},"timelion_interval":{"type":"keyword"},"timelion_other_interval":{"type":"keyword"},"timelion_rows":{"type":"integer"},"timelion_sheet":{"type":"text"},"title":{"type":"text"},"version":{"type":"integer"}}},"type":{"type":"keyword"},"updated_at":{"type":"date"},"url":{"properties":{"accessCount":{"type":"long"},"accessDate":{"type":"date"},"createDate":{"type":"date"},"url":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":2048}}}}},"visualization":{"properties":{"description":{"type":"text"},"kibanaSavedObjectMeta":{"properties":{"searchSourceJSON":{"type":"text"}}},"savedSearchId":{"type":"keyword"},"title":{"type":"text"},"uiStateJSON":{"type":"text"},"version":{"type":"integer"},"visState":{"type":"text"}}}}}}}}

L'argument pretty peut être ajouté pour avoir un affichage plus lisible.

#curl -X GET "localhost:9200/.kibana/_mapping?pretty"

Enfin, lorsque l'on ne connait nil'indexe ni le nom du maping, il est possible de demander l'ensemble des déclarations en utilisant le mot clé _all.

#curl -X GET "localhost:9200/_all/_mapping"


Icon-database-init.png Création

Il peut être nécessaire de créer une définition spécifique de mapping, comme dans le cas d'une intégration de fichier trace avec Logstash. Il est souvent plus simple de s'inspirer de configuration déjà existante. Dans le cas de l'utilisation de Logstash, une configuration par défaut est créé lors du démarrage de l'instance. Il est observé le message suivant dans la trace de démarrage.

Attempting to install template {:manage_template=>{"template"=>"logstash-*", "version"=>60001, "settings"=>{"index.refresh_interval"=>"5s"}, "mappings"=>{"_default_"=>{"dynamic_templates"=>[{"message_field"=>{"path_match"=>"message", "match_mapping_type"=>"string", "mapping"=>{"type"=>"text", "norms"=>false}}}, {"string_fields"=>{"match"=>"*", "match_mapping_type"=>"string", "mapping"=>{"type"=>"text", "norms"=>false, "fields"=>{"keyword"=>{"type"=>"keyword", "ignore_above"=>256}}}}}], "properties"=>{"@timestamp"=>{"type"=>"date"}, "@version"=>{"type"=>"keyword"}, "geoip"=>{"dynamic"=>true, "properties"=>{"ip"=>{"type"=>"ip"}, "location"=>{"type"=>"geo_point"}, "latitude"=>{"type"=>"half_float"}, "longitude"=>{"type"=>"half_float"}}}}}}}}

Le modèle logstash est donc disponible par défaut et il suffit de s'en inspirer.

#curl -X GET "localhost:9200/_template/logstash?pretty"
{
  "logstash" : {
    "order" : 0,
    "version" : 60001,
    "index_patterns" : [
      "logstash-*"
    ],
    "settings" : {
      "index" : {
        "refresh_interval" : "5s"
      }
    },
    "mappings" : {
      "_default_" : {
        "dynamic_templates" : [
          {
            "message_field" : {
              "path_match" : "message",
              "match_mapping_type" : "string",
              "mapping" : {
                "type" : "text",
                "norms" : false
              }
            }
          },
          {
            "string_fields" : {
              "match" : "*",
              "match_mapping_type" : "string",
              "mapping" : {
                "type" : "text",
                "norms" : false,
                "fields" : {
                  "keyword" : {
                    "type" : "keyword",
                    "ignore_above" : 256
                  }
                }
              }
            }
          }
        ],
        "properties" : {
          "@timestamp" : {
            "type" : "date"
          },
          "@version" : {
            "type" : "keyword"
          },
          "geoip" : {
            "dynamic" : true,
            "properties" : {
              "ip" : {
                "type" : "ip"
              },
              "location" : {
                "type" : "geo_point"
              },
              "latitude" : {
                "type" : "half_float"
              },
              "longitude" : {
                "type" : "half_float"
              }
            }
          }
        }
      }
    },
    "aliases" : { }
  }
}

Pour cet exemple, un modèle fail2ban est créé, argument fail2ban dans l'URL, qui va s'appliquer à tous les indexes dont le nom commencent par f2b-.

#curl -X PUT "localhost:9200/_template/fail2ban" -H 'Content-Type: application/json' -d'
{
  "order" : 0,
  "version" : 1,
  "index_patterns" : [
    "f2b-*"
  ],
  "settings" : {
    "index" : {
      "refresh_interval" : "5s"
    }
  },
  "mappings" : {
    "_default_" : {
      "dynamic_templates" : [
        {
          "message_field" : {
            "path_match" : "message",
            "match_mapping_type" : "string",
            "mapping" : {
              "type" : "text",
              "norms" : false
            }
          }
        },
        {
          "string_fields" : {
            "match" : "*",
            "match_mapping_type" : "string",
            "mapping" : {
              "type" : "text",
              "norms" : false,
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            }
          }
        }
      ],
      "properties" : {
        "@timestamp" : {
          "type" : "date"
        },
        "@version" : {
          "type" : "keyword"
        },
        "geoip" : {
          "dynamic" : true,
          "properties" : {
            "ip" : {
              "type" : "ip"
            },
            "location" : {
              "type" : "geo_point"
            },
            "latitude" : {
              "type" : "half_float"
            },
            "longitude" : {
              "type" : "half_float"
            }
          }
        }
      }
    }
  },
  "aliases" : { }
}
'
{"acknowledged":true}

A noter les configurations spécifiques des propriétés. location sera utilisée pour référencer les données de géolocalisation et ip est déclaré en type ip

La réponse {"acknowledged":true} indique que le modèle a été correctement installé, ainsi que le mapping associé.