<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Zenit Kovačević</title>
    <description>&lt;span&gt;Information Retrieval&lt;/span&gt;&lt;span&gt;Data Analysis, Music, Feature Discovery&lt;/span&gt;</description>
    <link>https://www.zenitk.com/</link>
    <atom:link href="https://www.zenitk.com/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Sun, 15 Mar 2026 21:18:29 +0000</pubDate>
    <lastBuildDate>Sun, 15 Mar 2026 21:18:29 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>Simple dev setup for elasticsearch and kibana</title>
        <description>&lt;p&gt;This is a mini script that contains all the needed config params. 
It’s a stripped down, no security, dev variant of the docker compose script provided by elastic (see link below) to run one ES node and Kibana on your machine.&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Set environment variables for Docker Compose&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;STACK_VERSION&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;8.12.0&quot;&lt;/span&gt;            &lt;span class=&quot;c&quot;&gt;# Example version for both ES and Kibana&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ES_PORT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;9200&quot;&lt;/span&gt;                   
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;KIBANA_PORT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;5601&quot;&lt;/span&gt;                
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CLUSTER_NAME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;dev-cluster&quot;&lt;/span&gt;        
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ES_MEM_LIMIT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;8g&quot;&lt;/span&gt;                 &lt;span class=&quot;c&quot;&gt;# Elasticsearch memory limit&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;KB_MEM_LIMIT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;4g&quot;&lt;/span&gt;                 &lt;span class=&quot;c&quot;&gt;# Kibana memory limit&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;down&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
  &lt;/span&gt;docker-compose down
&lt;span class=&quot;k&quot;&gt;else
  &lt;/span&gt;docker-compose up &lt;span class=&quot;nt&quot;&gt;--remove-orphans&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Docker compose&lt;/p&gt;

&lt;div class=&quot;language-yml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;3.8&quot;&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;es01&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;co.elastic.logs/module&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;elasticsearch&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;esdata01:/usr/share/elasticsearch/data&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;${ES_PORT}:9200&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;node.name=es01&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;cluster.name=${CLUSTER_NAME}&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;discovery.type=single-node&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;bootstrap.memory_lock=true&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;xpack.security.enabled=false&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;mem_limit&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;${ES_MEM_LIMIT}&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;ulimits&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;memlock&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;soft&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;-1&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;hard&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;-1&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;healthcheck&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;CMD-SHELL&quot;&lt;/span&gt;
        &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;curl&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;http://localhost:9200&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;grep&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;cluster_name&apos;&quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;10s&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;10s&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;retries&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;120&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;kibana&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;depends_on&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;es01&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;condition&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;service_healthy&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;docker.elastic.co/kibana/kibana:${STACK_VERSION}&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;co.elastic.logs/module&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;kibana&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;kibanadata:/usr/share/kibana/data&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;${KIBANA_PORT}:5601&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;SERVERNAME=kibana&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ELASTICSEARCH_HOSTS=http://es01:9200&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;mem_limit&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;${KB_MEM_LIMIT}&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;healthcheck&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;CMD-SHELL&quot;&lt;/span&gt;
        &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;curl&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-s&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-I&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;http://localhost:5601&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;grep&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-q&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;HTTP/1.1&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;302&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Found&apos;&quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;10s&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;10s&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;retries&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;120&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;esdata01&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;local&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;kibanadata&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;local&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Related articles:&lt;/p&gt;

&lt;p&gt;Original source: &lt;a href=&quot;https://www.elastic.co/blog/getting-started-with-the-elastic-stack-and-docker-compose&quot;&gt;Elastic&lt;/a&gt;.
Another stripped down version: &lt;a href=&quot;https://blog.devgenius.io/elasticsearch-and-kibana-installation-using-docker-compose-886c4823495e&quot;&gt;Devgenius&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Fri, 26 Jan 2024 00:00:00 +0000</pubDate>
        <link>https://www.zenitk.com/es-docker-compose-up</link>
        <guid isPermaLink="true">https://www.zenitk.com/es-docker-compose-up</guid>
        
        <category>elasticsearch</category>
        
        <category>elasticsearch8</category>
        
        <category>kibana</category>
        
        <category>docker</category>
        
        <category>docker-compose</category>
        
        
        <category>Search</category>
        
      </item>
    
      <item>
        <title>Stage Code Hunks In GIT CLI</title>
        <description>&lt;p&gt;Let’s say you’ve made way too many changes that you don’t want to place in the same commit, and these changes are mixed up in the same file. The GIT CLI supports adding of partial hunks interactively.&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git add &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# or&lt;/span&gt;
git add &lt;span class=&quot;nt&quot;&gt;--patch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For each hunk, you’ll be presented with a set of options:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;y&lt;/code&gt; - apply this hunk&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;n&lt;/code&gt; - do not apply this hunk&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a&lt;/code&gt; - apply this and all remaining hunks&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;d&lt;/code&gt; - do not apply this hunk or any of the remaining hunks&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;g&lt;/code&gt; - select a hunk to go to&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/&lt;/code&gt; - search for a hunk matching the given regex&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;j&lt;/code&gt; - leave this hunk undecided and see the next undecided hunk&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;J&lt;/code&gt; - leave this hunk undecided and see the next hunk&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;k&lt;/code&gt; - leave this hunk undecided and see the previous undecided hunk&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s&lt;/code&gt; - split the current hunk into smaller hunks&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e&lt;/code&gt; - manually edit the current hunk&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;?&lt;/code&gt; - print the help&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The GIT documentation can be found &lt;a href=&quot;https://git-scm.com/docs/git-add#Documentation/git-add.txt--p&quot;&gt;here&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Sun, 10 Sep 2023 00:00:00 +0000</pubDate>
        <link>https://www.zenitk.com/git-partial-stage</link>
        <guid isPermaLink="true">https://www.zenitk.com/git-partial-stage</guid>
        
        <category>GIT</category>
        
        
        <category>GIT</category>
        
      </item>
    
      <item>
        <title>Import from CSV to Elasticsearch using Logstash</title>
        <description>&lt;p&gt;Frequently when we want to test out a new feature in Elasticsearch we need some data to play with. Unfortunately, Kibana and Elasticsearch don’t provide an easy, out-of-the-box way to simply import a CSV.&lt;/p&gt;

&lt;p&gt;That’s why there is Logstash in the known E&lt;strong&gt;L&lt;/strong&gt;K stack. Its job is to &lt;em&gt;watch&lt;/em&gt; to a data source,
&lt;em&gt;process&lt;/em&gt; incoming data, and &lt;em&gt;output&lt;/em&gt; it into specified sources. Once started, it usually stays on and watches for any changes in the data source.&lt;/p&gt;

&lt;p&gt;Here, I’ll guide you step by step on how to import a sample CSV into Elasticsearch 7.x using Logstash 7.x. By the end, you should be able to tweak the provided example to fit your own needs. There will be plenty of links to the official documentation, but that’s just for convenience.&lt;/p&gt;

&lt;h2 id=&quot;sample-csv&quot;&gt;Sample CSV&lt;/h2&gt;

&lt;p&gt;For this blog, I’ve imported the usual &lt;a href=&quot;https://news.ycombinator.com/&quot;&gt;Hackernews stories&lt;/a&gt; from &lt;a href=&quot;https://cloud.google.com/bigquery/public-data&quot;&gt;BigQuery Public Data Sets&lt;/a&gt;. 
The CSV is available &lt;a href=&quot;/assets/posts/2020/import-from-csv-to-elasticsearch-with-logstash/hackernews.csv&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The schema looks like this:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Field name&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
      &lt;th&gt;Description&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;id&lt;/td&gt;
      &lt;td&gt;INTEGER&lt;/td&gt;
      &lt;td&gt;Unique story ID&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;by&lt;/td&gt;
      &lt;td&gt;STRING&lt;/td&gt;
      &lt;td&gt;Username of submitter&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;score&lt;/td&gt;
      &lt;td&gt;INTEGER&lt;/td&gt;
      &lt;td&gt;Story score&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;time&lt;/td&gt;
      &lt;td&gt;INTEGER&lt;/td&gt;
      &lt;td&gt;Unix time&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;time_ts&lt;/td&gt;
      &lt;td&gt;TIMESTAMP&lt;/td&gt;
      &lt;td&gt;Human readable time in UTC (format: YYYY-MM-DD hh:mm:ss)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;title&lt;/td&gt;
      &lt;td&gt;STRING&lt;/td&gt;
      &lt;td&gt;Story title&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;url&lt;/td&gt;
      &lt;td&gt;STRING&lt;/td&gt;
      &lt;td&gt;Story url&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;text&lt;/td&gt;
      &lt;td&gt;STRING&lt;/td&gt;
      &lt;td&gt;Story text&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;deleted&lt;/td&gt;
      &lt;td&gt;BOOLEAN&lt;/td&gt;
      &lt;td&gt;Is deleted?&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;dead&lt;/td&gt;
      &lt;td&gt;BOOLEAN&lt;/td&gt;
      &lt;td&gt;Is dead?&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;descendants&lt;/td&gt;
      &lt;td&gt;INTEGER&lt;/td&gt;
      &lt;td&gt;Number of story descendants&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;author&lt;/td&gt;
      &lt;td&gt;STRING&lt;/td&gt;
      &lt;td&gt;Username of author&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Here are some sample rows (for readability purposes not all columns are selected):&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;id&lt;/th&gt;
      &lt;th&gt;by&lt;/th&gt;
      &lt;th&gt;time_ts&lt;/th&gt;
      &lt;th&gt;title&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;7405411&lt;/td&gt;
      &lt;td&gt;ferhack&lt;/td&gt;
      &lt;td&gt;2014-03-15 17:55:02 UTC&lt;/td&gt;
      &lt;td&gt;Hacker&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;7541990&lt;/td&gt;
      &lt;td&gt;jeassonlens&lt;/td&gt;
      &lt;td&gt;2014-04-06 18:29:21 UTC&lt;/td&gt;
      &lt;td&gt;Marc Cormier, Real Estate Marketing Specialist&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;7163174&lt;/td&gt;
      &lt;td&gt;aryekellman01&lt;/td&gt;
      &lt;td&gt;2014-02-01 20:10:58 UTC&lt;/td&gt;
      &lt;td&gt;Accents from Around The World&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;6807522&lt;/td&gt;
      &lt;td&gt;wearefivek&lt;/td&gt;
      &lt;td&gt;2013-11-27 11:14:52 UTC&lt;/td&gt;
      &lt;td&gt;Developer For Small, Creative Digital Design Studio&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;6950020&lt;/td&gt;
      &lt;td&gt;zeiny&lt;/td&gt;
      &lt;td&gt;2013-12-22 11:23:41 UTC&lt;/td&gt;
      &lt;td&gt;Psychotropic drug use among people with dementia – a six-month follow-up study&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;prepare-logstash-configuration&quot;&gt;Prepare Logstash Configuration&lt;/h2&gt;

&lt;p&gt;First, follow the &lt;a href=&quot;https://www.elastic.co/guide/en/logstash/current/installing-logstash.html&quot;&gt;instructions on installing Logstash&lt;/a&gt;.
Then, take a brief look at this full logstash configuration script. I’ll explain the details further down. The script can be downloaded &lt;a href=&quot;/assets/posts/2020/import-from-csv-to-elasticsearch-with-logstash/import-hackernews.conf&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-conf highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; {
  &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt; {
    &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;/home/zenitk/hackernews.csv&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;start_position&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;beginning&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sincedb_path&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;/dev/null&quot;&lt;/span&gt;
  }
}

&lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt; {

    &lt;span class=&quot;n&quot;&gt;csv&lt;/span&gt; {
        &lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt; =&amp;gt; [
            &lt;span class=&quot;s2&quot;&gt;&quot;id&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;by&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;score&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;time&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;time_ts&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;title&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;url&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;text&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;deleted&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;dead&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;descendants&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;author&quot;&lt;/span&gt;
        ]
        &lt;span class=&quot;n&quot;&gt;separator&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;,&quot;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;skip_header&lt;/span&gt; =&amp;gt; &lt;span class=&quot;n&quot;&gt;true&lt;/span&gt;
    }

    &lt;span class=&quot;n&quot;&gt;date&lt;/span&gt; {
        &lt;span class=&quot;n&quot;&gt;match&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;s2&quot;&gt;&quot;time_ts&quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&quot;yyyy-MM-dd HH:mm:ss z&quot;&lt;/span&gt;]
        &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;post_date&quot;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;remove_field&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;time_ts&quot;&lt;/span&gt;
    }

    &lt;span class=&quot;n&quot;&gt;mutate&lt;/span&gt; {        
        &lt;span class=&quot;n&quot;&gt;rename&lt;/span&gt; =&amp;gt; { 
            &lt;span class=&quot;s2&quot;&gt;&quot;dead&quot;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;is_dead&quot;&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&quot;id&quot;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;[@metadata][id]&quot;&lt;/span&gt;            
        }
        
        &lt;span class=&quot;n&quot;&gt;convert&lt;/span&gt; =&amp;gt; {
            &lt;span class=&quot;s2&quot;&gt;&quot;is_dead&quot;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;boolean&quot;&lt;/span&gt;
        }
       
        &lt;span class=&quot;n&quot;&gt;remove_field&lt;/span&gt; =&amp;gt; [
            &lt;span class=&quot;s2&quot;&gt;&quot;@timestamp&quot;&lt;/span&gt;, 
            &lt;span class=&quot;s2&quot;&gt;&quot;host&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;message&quot;&lt;/span&gt;, 
            &lt;span class=&quot;s2&quot;&gt;&quot;@version&quot;&lt;/span&gt;, 
            &lt;span class=&quot;s2&quot;&gt;&quot;path&quot;&lt;/span&gt;, 
            &lt;span class=&quot;s2&quot;&gt;&quot;descendants&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;time&quot;&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&quot;id&quot;&lt;/span&gt;
        ]
    }
}

&lt;span class=&quot;n&quot;&gt;output&lt;/span&gt; {

  &lt;span class=&quot;n&quot;&gt;elasticsearch&lt;/span&gt; { 
      &lt;span class=&quot;n&quot;&gt;hosts&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;s2&quot;&gt;&quot;localhost:9200&quot;&lt;/span&gt;]
      &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;hackernews_import&quot;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;document_id&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;%{[@metadata][id]}&quot;&lt;/span&gt;
  }

  &lt;span class=&quot;n&quot;&gt;stdout&lt;/span&gt; {}
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As expected, each logstash configuration file is defined with the three main elements: &lt;strong&gt;input&lt;/strong&gt;, &lt;strong&gt;filter&lt;/strong&gt;, and &lt;strong&gt;output&lt;/strong&gt;. 
More information can be found here in the &lt;a href=&quot;https://www.elastic.co/guide/en/logstash/current/configuration-file-structure.html&quot;&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;input&quot;&gt;Input&lt;/h3&gt;

&lt;div class=&quot;language-conf highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; {
  &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt; {
    &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;/home/zenitk/hackernews.csv&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;start_position&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;beginning&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sincedb_path&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;/dev/null&quot;&lt;/span&gt;
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here we define that we want to have a &lt;em&gt;file&lt;/em&gt; on the local machine as the source. At this point, this could be any text file, logstash doesn’t care.
In the example above, we basically say that when it runs it should read from the &lt;em&gt;beginning&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/logstash/7.x/plugins-inputs-file.html#plugins-inputs-file-path&quot;&gt;path&lt;/a&gt; - the &lt;strong&gt;absolute&lt;/strong&gt; path on your machine&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/logstash/7.x/plugins-inputs-file.html#_tracking_of_current_position_in_watched_files&quot;&gt;start_position&lt;/a&gt; - either &lt;em&gt;beggining&lt;/em&gt; or &lt;em&gt;end&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/logstash/7.x/plugins-inputs-file.html#_tracking_of_current_position_in_watched_files&quot;&gt;sincedb_path&lt;/a&gt; - basically the location where logstash stores how far it read, 
so that when it’s started next time it can simply start where it stopped the last time&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;: if you’re on Windows the path separator in &lt;em&gt;path&lt;/em&gt; has to be &lt;strong&gt;/&lt;/strong&gt;, but &lt;em&gt;sincedb_path&lt;/em&gt; &lt;strong&gt;\&lt;/strong&gt;. 
 If you know why let me know!&lt;/p&gt;

&lt;p&gt;More information on the file plugin &lt;a href=&quot;https://www.elastic.co/guide/en/logstash/current/plugins-inputs-file.html&quot;&gt;here in the official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;filter&quot;&gt;Filter&lt;/h3&gt;

&lt;div class=&quot;language-conf highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt; {

    &lt;span class=&quot;n&quot;&gt;csv&lt;/span&gt; {
        &lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt; =&amp;gt; [
            &lt;span class=&quot;s2&quot;&gt;&quot;id&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;by&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;score&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;time&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;time_ts&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;title&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;url&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;text&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;deleted&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;dead&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;descendants&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;author&quot;&lt;/span&gt;
            ]
        &lt;span class=&quot;n&quot;&gt;separator&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;,&quot;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;skip_header&lt;/span&gt; =&amp;gt; &lt;span class=&quot;n&quot;&gt;true&lt;/span&gt;
    }

    &lt;span class=&quot;n&quot;&gt;date&lt;/span&gt; {
        &lt;span class=&quot;n&quot;&gt;match&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;s2&quot;&gt;&quot;time_ts&quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&quot;yyyy-MM-dd HH:mm:ss z&quot;&lt;/span&gt;]
        &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;post_date&quot;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;remove_field&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;time_ts&quot;&lt;/span&gt;
    }

    &lt;span class=&quot;n&quot;&gt;mutate&lt;/span&gt; {        
        &lt;span class=&quot;n&quot;&gt;rename&lt;/span&gt; =&amp;gt; { 
            &lt;span class=&quot;s2&quot;&gt;&quot;dead&quot;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;is_dead&quot;&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&quot;id&quot;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;[@metadata][id]&quot;&lt;/span&gt;            
        }
        
        &lt;span class=&quot;n&quot;&gt;convert&lt;/span&gt; =&amp;gt; {
            &lt;span class=&quot;s2&quot;&gt;&quot;is_dead&quot;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;boolean&quot;&lt;/span&gt;
        }
       
        &lt;span class=&quot;n&quot;&gt;remove_field&lt;/span&gt; =&amp;gt; [
            &lt;span class=&quot;s2&quot;&gt;&quot;@timestamp&quot;&lt;/span&gt;, 
            &lt;span class=&quot;s2&quot;&gt;&quot;host&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;message&quot;&lt;/span&gt;, 
            &lt;span class=&quot;s2&quot;&gt;&quot;@version&quot;&lt;/span&gt;, 
            &lt;span class=&quot;s2&quot;&gt;&quot;path&quot;&lt;/span&gt;, 
            &lt;span class=&quot;s2&quot;&gt;&quot;descendants&quot;&lt;/span&gt;,
            &lt;span class=&quot;s2&quot;&gt;&quot;time&quot;&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;&quot;id&quot;&lt;/span&gt;
        ]
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This section is optional if you want to just import the file and you don’t care how it shows up in elastic. But you should know here is the &lt;strong&gt;all the fun&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;With the &lt;a href=&quot;https://www.elastic.co/guide/en/logstash/current/plugins-filters-csv.html&quot;&gt;CSV plugin&lt;/a&gt; we tell logstash how our data is structured. We explicitly write all the column names and skip the header. Note that the filter itself supports &lt;a href=&quot;https://www.elastic.co/guide/en/logstash/current/plugins-filters-csv.html#plugins-filters-csv-autodetect_column_names&quot;&gt;auto detection of the column names&lt;/a&gt; based on the header. However, this requires some fiddling with the internal logstash configuration, specifically the the pipeline.workers has to be set to 1.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;time_ts&lt;/em&gt; field is basically just a string, so in the &lt;a href=&quot;https://www.elastic.co/guide/en/logstash/current/plugins-filters-date.html#plugins-filters-date-remove_field&quot;&gt;date plugin&lt;/a&gt; we tell logstash that it’s actually a &lt;strong&gt;date&lt;/strong&gt; with the specified format. Then, we tell it to save it to the new &lt;strong&gt;target&lt;/strong&gt; field, and to remove the old one. This way Elasticsearch recognizes it as an actual date.&lt;/p&gt;

&lt;h4 id=&quot;mutate&quot;&gt;Mutate&lt;/h4&gt;

&lt;p&gt;Now, the &lt;a href=&quot;https://www.elastic.co/guide/en/logstash/current/plugins-filters-mutate.html&quot;&gt;mutate&lt;/a&gt; plugin is where it gets juicy! :watermelon:&lt;/p&gt;

&lt;p&gt;Here, we’re renaming &lt;strong&gt;dead&lt;/strong&gt; to &lt;strong&gt;is_dead&lt;/strong&gt;, because it’s common courtesy to name your booleans clearly.&lt;/p&gt;

&lt;p&gt;Then, we rename &lt;strong&gt;id&lt;/strong&gt; to &lt;strong&gt;[@metadata][id]&lt;/strong&gt; because we don’t want the id to be saved like a normal field in Elasticsearch, since we would like to use it as an actual document id. What we actually do here is store the id into a temporary variable that is not being passed on in the end output. We use this variable later in the &lt;a href=&quot;#metadata-document-id&quot;&gt;Output&lt;/a&gt; section. See the &lt;a href=&quot;https://www.elastic.co/blog/logstash-metadata&quot;&gt;Metadata&lt;/a&gt; blog at Elastic for more information.&lt;/p&gt;

&lt;p&gt;Similar to the date field, in &lt;a href=&quot;https://www.elastic.co/guide/en/logstash/current/plugins-filters-mutate.html#plugins-filters-mutate-convert&quot;&gt;convert&lt;/a&gt; we need to tell logstash that the string “true” is actually a boolean. No magic happens on its own.&lt;/p&gt;

&lt;p&gt;Since Logstash was primarily designed, well, for logging, it stores a bunch of fields to Elasticsearch like “@timestamp”, “host”, “message”, “@version”, “path” that we don’t care about so with the &lt;a href=&quot;https://www.elastic.co/guide/en/logstash/current/plugins-filters-mutate.html#plugins-filters-mutate-remove_field&quot;&gt;remove_field&lt;/a&gt; configuration option. Additionaly, we get rid of fields from our CSV that are just taking space.&lt;/p&gt;

&lt;h3 id=&quot;output&quot;&gt;Output&lt;/h3&gt;
&lt;div class=&quot;language-conf highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;output&lt;/span&gt; {

  &lt;span class=&quot;n&quot;&gt;elasticsearch&lt;/span&gt; { 
      &lt;span class=&quot;n&quot;&gt;hosts&lt;/span&gt; =&amp;gt; [&lt;span class=&quot;s2&quot;&gt;&quot;localhost:9200&quot;&lt;/span&gt;]
      &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;hackernews_import&quot;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;document_id&lt;/span&gt; =&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;%{[@metadata][id]}&quot;&lt;/span&gt;
      &lt;span class=&quot;c&quot;&gt;#cacert =&amp;gt; &quot;/home/hackerman/elastic.cer&quot;
&lt;/span&gt;      &lt;span class=&quot;c&quot;&gt;#user =&amp;gt; &quot;hackerman&quot;
&lt;/span&gt;      &lt;span class=&quot;c&quot;&gt;#password =&amp;gt; &quot;блинчикиandpancakesandcrepes&quot;
&lt;/span&gt;  }

  &lt;span class=&quot;n&quot;&gt;stdout&lt;/span&gt; {}
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;We output the data both into the standard output (for debugging purposes) and Elasticsearch.&lt;/p&gt;

&lt;p&gt;Now in the &lt;strong&gt;elasticsearch&lt;/strong&gt; section we say with &lt;strong&gt;&lt;span id=&quot;metadata-document-id&quot;&gt;document_id&lt;/span&gt;&lt;/strong&gt; that we want to use our metadata field. With the &lt;mark&gt;%{ ... }&lt;/mark&gt; syntax we just reference a variable.&lt;/p&gt;

&lt;p&gt;If you have a custom certificate on your cluster and/or need credentials the commented section has the keywords you’ll need to access your cluster.&lt;/p&gt;

&lt;h2 id=&quot;run-logstash&quot;&gt;Run Logstash&lt;/h2&gt;

&lt;p&gt;Now that we finally have our logstash configuration file we can finally run it.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./logstash &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; /home/zenitk/import-hackernews.conf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If everything runs smoothly (disclaimer: usually it doesn’t) you should see something like this:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;post_date&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2015&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;58&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;21.000&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
       &lt;span class=&quot;s2&quot;&gt;&quot;author&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Datafloq&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;score&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
           &lt;span class=&quot;s2&quot;&gt;&quot;by&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Datafloq&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
         &lt;span class=&quot;s2&quot;&gt;&quot;text&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;is_dead&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;deleted&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
         &lt;span class=&quot;s2&quot;&gt;&quot;time&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;1439305101&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;title&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;5 Reasons Why Small Businesses Need Not Be Shy of Big Data&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s2&quot;&gt;&quot;url&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;https://datafloq.com/read/5-reasons-small-businesses-need-not-shy-big-data/1390&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we can do a check in Kibana:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# check the data types
GET hackernews_import/_mapping

# check if all the rows are imported
GET hackernews_import/_count
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note that I didn’t create the index first, but rather let Elasticsearch dynamically define the fields. This is fine for testing purposes or when just trying out the logstash script, but for production, you should strongly consider creating the index first with a dynamic mapping set to strict. This is however a topic on its own.&lt;/p&gt;

&lt;p&gt;Often with CSVs that contain a lot of text, there will be trouble with parsing. If you had a &lt;strong&gt;stdout&lt;/strong&gt; output it will usually show you when and where it failed (although cryptically sometimes). These rows can be corrected and simply placed at the end of the file while running Logstash.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;Now we went through the whole process of importing CSV data into Elasticsearch.&lt;/p&gt;

&lt;p&gt;Logstash can feel fiddly in the beginning, but once you get familiar with its quirks it can be a potent and easy tool for quick imports. I hope that after going through this blog you feel well armed to tackle some imports on your own. For instance, how about importing a JSON document? Or from a DB? I’m assured you’ll know where to start.&lt;/p&gt;

&lt;p&gt;Please hit the comment section if you have some questions or feedback!&lt;/p&gt;

&lt;h2 id=&quot;other-sources&quot;&gt;Other sources&lt;/h2&gt;

&lt;p&gt;If you’re more of a video person, here is a similar (but a bit older) tutorial:&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/rKy4sFbIZ3U&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
</description>
        <pubDate>Thu, 28 May 2020 00:00:00 +0000</pubDate>
        <link>https://www.zenitk.com/import-from-csv-to-elasticsearch-with-logstash</link>
        <guid isPermaLink="true">https://www.zenitk.com/import-from-csv-to-elasticsearch-with-logstash</guid>
        
        <category>Logstash</category>
        
        <category>Elasticsearch</category>
        
        
        <category>Search</category>
        
      </item>
    
      <item>
        <title>Hello World!</title>
        <description>&lt;p&gt;This is the very first blog post! Well, not really, but I do feel the need to write this down.&lt;/p&gt;

&lt;p&gt;First of all, I hope you find here what you’re looking for. 
Right now there isn’t much content on the website, but hopefully, soon there will be plenty of good content about &lt;strong&gt;search&lt;/strong&gt;, software engineering, &lt;strong&gt;clean code&lt;/strong&gt;, 
reviews about online services, libraries, courses, and maybe some NLP goodness.&lt;/p&gt;

&lt;p&gt;I’ve been writing for a while now for myself, keeping somewhat structured notes that never get shared and get lost over time.
I hope that with this blog these notes will get more life and that they might be of some use to you.&lt;/p&gt;

&lt;p&gt;For me, blogging is is a way to learn and share what I’ve learned. Just remembering ideas and concepts is hard, 
but writing them down in your own words and putting them into practice goes a long way in terms of learning.&lt;/p&gt;

&lt;p&gt;There is a full backlog about topics, so please stay tuned! 
Here’s the link to the &lt;a href=&quot;https://www.zenitk.com/feed.xml&quot;&gt;RSS Feed&lt;/a&gt;, but regardless, stop by and say hello anytime.&lt;/p&gt;

&lt;p&gt;If you’ve been looking to write your &lt;strong&gt;own blog&lt;/strong&gt; check out this talk by &lt;a href=&quot;https://khalidabuhakmeh.com/&quot;&gt;Khalid Abuhakmeh&lt;/a&gt;. 
Right now he’s helping out new bloggers (as myself) to set up their blog and get going, so go and ask him about some tips!&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/qjTJI6jbc4s&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

</description>
        <pubDate>Thu, 28 May 2020 00:00:00 +0000</pubDate>
        <link>https://www.zenitk.com/hello-world</link>
        <guid isPermaLink="true">https://www.zenitk.com/hello-world</guid>
        
        <category>Meta</category>
        
        
      </item>
    
  </channel>
</rss>
