Working in a distributed company like Elastic is great, but can sometimes be hard to grasp. Answering some seemingly simple questions can be surprisingly complicated, like:
- Show our team on a map, so I can explain our reach and structure.
- Let me find anyone in a certain area, so we know who is "local".
- Find someone with a specific skill close by.
- Show the team growth over time.
- Document region coverage, so anyone can look it up.
Luckily, Kibana can help here and the goal of this post is to create a map like this:
Mapping and Data in Elasticsearch
Before you can jump into the visualization, you need to create the correct mapping (or schemaΒ β this isn't directly related to a map yet ). Run the following request in Kibana's Console to create the mapping:
PUT team
{
"mappings": {
"dynamic": "strict",
"properties": {
"name": {
"type": "keyword"
},
"team": {
"type": "keyword"
},
"role": {
"type": "keyword"
},
"start_date": {
"type": "date"
},
"country_code": {
"type": "keyword"
},
"city": {
"type": "keyword"
},
"location": {
"type": "geo_point"
},
"technology": {
"type": "keyword"
},
"region": {
"type": "keyword"
},
"picture": {
"type": "keyword"
}
}
}
}
Most important in the mapping is:
-
geo_point
is the most important data type to use on a map. - The
date
field is necessary to show the development over time.
To keep it simple, the sample data set used only includes the Community team in Europe:
PUT team/_doc/david
{
"name": "David Pilato",
"team": "community",
"role": "Developer π₯",
"start_date": "2013-01-10",
"country_code": "fr",
"city": "Cergy",
"location": {
"lat": 49.05,
"lon": 2.04
},
"technology": ["java", "elasticsearch", "search"],
"picture": "https://avatars.githubusercontent.com/u/274222"
}
PUT team/_doc/philipp
{
"name": "Philipp Krenn",
"team": "community",
"role": "Developer π₯ | EMEA Lead",
"start_date": "2016-04-01",
"country_code": "at",
"city": "Vienna",
"location": {
"lat": 48.21,
"lon": 16.37
},
"technology": ["java", "automation", "observability"],
"picture": "https://avatars.githubusercontent.com/u/432211"
}
PUT team/_doc/adrienne
{
"name": "Adrienne de Vries",
"team": "community",
"role": "Community Programs",
"start_date": "2019-12-02",
"country_code": "nl",
"city": "Rotterdam",
"location": {
"lat": 51.92,
"lon": 4.48
},
"region": ["FR", "ES", "PT", "IT", "GR", "TR", "CY", "NL", "BE", "DK", "LU", "NO", "SE", "FI", "IS", "EE", "LV", "LT", "MA", "TN", "DZ"],
"picture": "https://ca.slack-edge.com/T0CUZ52US-UQQ55JABU-56457843fc81-512"
}
PUT team/_doc/naoise
{
"name": "Naoise Rush",
"team": "community",
"role": "Community Programs",
"start_date": "2022-02-28",
"country_code": "gb",
"city": "Belfast",
"location": {
"lat": 54.60,
"lon": -5.93
},
"region": ["GB", "IE", "DE", "AT", "CH", "PL", "CZ", "SK", "SI", "HU", "RO", "BG", "MD", "UA", "HR", "RS", "BA", "AL", "XK", "ME", "MK", "IL", "SA", "EG", "AE", "JO", "LB", "KW", "QA", "OM", "BH"],
"picture": "https://ca.slack-edge.com/T0CUZ52US-U033ZF1HPM3-3f8511dbc26f-512"
}
PUT team/_doc/carly
{
"name": "Carly Richmond",
"team": "community",
"role": "Developer π₯",
"start_date": "2022-04-25",
"country_code": "uk",
"city": "London",
"location": {
"lat": 51.55,
"lon": 0.16
},
"technology": ["javascript", "frontend", "observability"],
"picture": "https://avatars.githubusercontent.com/u/74931905"
}
Adding the Data in Kibana
Before you can use the data in Kibana, you need to add the indexed data to a Data View:
And to use the pictures, you need to customize the picture
field to a Url
of the type Image
and set the URL template to {{rawValue}}
:
Once set up, you can view the underlying documents in Discover and change the timeframe to 10 years (from the default of 15 minutes):
Adding the First Map β at Last
Maps in Kibana have a lot of features, but the example will keep it simple. Add a layer of the type Documents:
And in the team
index, pick the only available geo-point location
:
Add the most relevant tooltip fields:
And adjust the color of each document by the role
:
And that's all we need to get the team on the map. If you don't see anything, double-check that you have picked the past 10 years and not just 15 minutes again. Hovering over one of them reveals their profile and based on the color you can tell their role:
Mapping Time
Based on the start_date
field for each team member, you can show how it developed over time or even autoplay it year by year:
Putting Search on the Map
Search is core to what we do. So if you want to figure out who on our team could help you out with all things "frontend", you could also find that on the map:
Mapping Regions
Our team also has the concept of owning certain regions. Time to add another layer to the map β this time it's the Choropleth. The region
array of the Elasticsearch documents maps to the ISO 3166-1 alpha-2 code of countries. And we can limit it to the role of "Community Programs", since only they own regions:
Sprinkling a bit of color on top by name:
And we have neatly mapped out the ownership of the entire region:
Helping Santa Find the Team
To add something more Christmas related, let's help Santa find the team. This information should go in a new index with the simple mapping for source
and destination
geo-points in one document:
PUT santa
{
"mappings": {
"dynamic": "strict",
"properties": {
"@timestamp": {
"type": "date"
},
"source": {
"type": "geo_point"
},
"destination": {
"type": "geo_point"
}
}
}
}
And these are the documents for the actual travel route:
POST santa/_doc
{
"@timestamp": "2022-12-24T19:30Z",
"source": {
"lat": 48.21,
"lon": 100
},
"destination": {
"lat": 48.21,
"lon": 16.37
}
}
POST santa/_doc
{
"@timestamp": "2022-12-24T19:40Z",
"source": {
"lat": 48.21,
"lon": 16.37
},
"destination": {
"lat": 49.05,
"lon": 2.04
}
}
POST santa/_doc
{
"@timestamp": "2022-12-24T19:50Z",
"source": {
"lat": 49.05,
"lon": 2.04
},
"destination": {
"lat": 51.92,
"lon": 4.48
}
}
POST santa/_doc
{
"@timestamp": "2022-12-24T20:00Z",
"source": {
"lat": 51.92,
"lon": 4.48
},
"destination": {
"lat": 51.55,
"lon": 0.16
}
}
POST santa/_doc
{
"@timestamp": "2022-12-24T20:10Z",
"source": {
"lat": 51.55,
"lon": 0.16
},
"destination": {
"lat": 54.60,
"lon": -5.93
}
}
POST santa/_doc
{
"@timestamp": "2022-12-24T20:20Z",
"source": {
"lat": 54.60,
"lon": -5.93
},
"destination": {
"lat": 54.60,
"lon": -20.00
}
}
Add one more layer, this time with Point to point. In which you map source
and destination
:
And with some minor customization, you can show Santa the way to everyone on the team. Picking the right timeframe, you could even follow along as the reindeers are traversing every segment on the route:
Conclusion
We hope that this gave you some ideas on how to put distributed teams on the map. Kibana can still do a lot more β the documentation for maps is a great starting point there.