Spring Boot ElasticSearch – initial loader, indexing test data

S

Hi, and welcome to the 6th article devoted to the theme:  “How to work with ElasticSearch using Java Spring Boot”. Previous article (Part 5: Spring Boot ElasticSearch – model data layer) is located here. At that article we are going to create initial loader which would be used for creating elasticsearch mapping and indexing some initial test data to ElasticSearch index. The loader is represented by SpringBootEsInitLoader class:

SpringBootEsInitLoader

Here is the code of the loader:

package com.udemy_sergii_java.spring_boot_es;

import com.udemy_sergii_java.spring_boot_es.model.elasticsearch.Comment;
import com.udemy_sergii_java.spring_boot_es.model.elasticsearch.HotelBookingDocument;
import com.udemy_sergii_java.spring_boot_es.repository.HotelBookingRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
import org.springframework.data.elasticsearch.core.join.JoinField;
import org.springframework.stereotype.Component;
import java.time.Instant;
import java.util.Arrays;

@Component
@Order(1)
class SpringBootEsInitLoader implements CommandLineRunner {

    @Autowired
    HotelBookingRepository hotelBookingRepository;

    @Value("${load.init.data}")
    private Boolean loadInitData;

    private static final Logger logger = LoggerFactory.getLogger(
            SpringBootEsInitLoader.class
    );

    @Override
    public void run(String... args) throws Exception {
        logger.info("CommandLineRunner#run(String[])");

        try {
            if (loadInitData) {
                HotelBookingDocument goldenHotel = new HotelBookingDocument();
                goldenHotel.setId("1");
                goldenHotel.setHotelID(1);
                goldenHotel.setName("Golden star hotel");
                goldenHotel.setCityNameEn("Warsaw");
                goldenHotel.setLocation(new GeoPoint(52.21, 21.01));
                goldenHotel.setAge(7);
                goldenHotel.setStarts(5);
                goldenHotel.setFreePlacesAtNow(true);
                goldenHotel.setRating(4.85);
                goldenHotel.setRelation(new JoinField<>("hotel"));

                Comment comment = new Comment();
                comment.setContent("Some content");
                comment.setCreatedDate(Instant.now());
                comment.setHotelID(1);
                comment.setStarts(5);
                goldenHotel.setComments(Arrays.asList(comment));

                hotelBookingRepository.save(goldenHotel);

                HotelBookingDocument booking = new HotelBookingDocument();
                booking.setId("2");
                booking.setPrice(100.00);
                booking.setCreatedDate(Instant.now());
                booking.setRelation(new JoinField<>("booking", goldenHotel.getId()));
                hotelBookingRepository.save(booking);

                HotelBookingDocument silverHotel = new HotelBookingDocument();
                silverHotel.setId("3");
                silverHotel.setHotelID(3);
                silverHotel.setName("Silver star hotel");
                silverHotel.setCityNameEn("Warsaw");
                silverHotel.setLocation(new GeoPoint(52.13, 21.01));
                silverHotel.setAge(7);
                silverHotel.setStarts(4);
                silverHotel.setFreePlacesAtNow(true);
                silverHotel.setRating(4.6);
                silverHotel.setRelation(new JoinField<>("hotel"));
                hotelBookingRepository.save(silverHotel);
            }
        } catch (Throwable t) {
            logger.error(t.toString());
        }

        if (args.length > 0) {
            logger.info("first command line parameter: '{}'", args[0]);
        }
    }
}

Current loader is run at every start of spring boot application. loadInitData property defines whether to index test data or not. Current parameter is bind from spring boot application properties. Please pay attention at hotelBookingRepository. Current class extends ElasticsearchRepository from spring data elasticsearch package and has some additional logic inside. All that allows to get base CRUD operation realizations out of the box. Saving document models also creates according index with correct mapping (if it is still does not exist). If you would like to know more how exactly it works, I propose you to view my online course,. You also can try to get according information from official spring data elasticsearch java package.

ElasticsearchRepository

Of course, current initial loader – that is only simplified example. But here you already have the code that covers all possible scenarios e.g parent child relationship, and nested object. In real life you will have to create some commands for initial indexing and reindexing with much more complicated logic (e.g like separate spring boot console application). At real practice you will probably have to connect to some RDB, external microservices to get according data. Moreover, you will have to create some worker that will track all changes provided by customers and administrators at elasticsearch data. That is a little bit out of the horizonts of that article. But the principles I am using here would not be changed. So that command loader is a good point you would be able to start from. 

At the next lecture (Part 7: Symfony ElasticSearch – search service and query builder) we will finish to create our search microservice. Together, we will create search service, query builder and realize filter design pattern. If you would like to pass all material more fast, then I propose you to view my on-line course at udemy where you will also find full project skeleton. Below is the link to the course. As the reader of that blog you are also getting possibility to use coupon for the best possible low price. Otherwise, please wait at next articles. Thank you for you attention.


architecture cluster docker elasticsearch flask geo high availability java php programming languages python recommendation systems search systems spring boot symfony