Getting Started With Elasticsearch in Java Spring Boot
By: Brilian Firdaus
Tags: Programming, Java, Spring Boot, Spring, Software Development

Using Spring Data Elasticsearch

First, let’s learn how to use spring-data-elasticsearch in our Spring project. spring-data-elasticsearch is very easy to use and a high-level library we can use to access Elasticsearch.

Creating an entity and configuring our index

After you’re done connecting your apps with Elasticsearch, it’s time to create an entity! With Spring Data, we can add metadata to our entity, which will be read by the repository bean we created. This way, the code will be much cleaner and faster to develop since we won’t need to create any mapping logic in our service level.

Let’s create an entity called Product :

So let me explain what’s going on in the code block above. First, I won’t explain about @Data , @AllArgsConstructor , @NoArgsConstructor , and @Builder . They’re annotations from the Lombok library for constructor , getter , setter , builder , and other things.

Now, let’s talk about the first spring data annotation in the entity, @Document . The @Document annotation shows that the class is an entity containing metadata of the Elasticsearch index’s setup. To use the Spring Data repository, which we’ll learn later on, the @Document annotation is mandatory.

The only annotation that’s mandatory in @Document is the indexName . It should be pretty clear from the name — we should fill it with the index name we want to use for the entity. In this article, we’ll use the same name as the entity, product .

The second parameter of @Document to talk about is the createIndex parameter. If you set the createIndex as true , your apps will create an index automatically when you’re starting the apps if the index doesn’t yet exist.

The shards , replicas , and refreshInterval parameters determine the index settings when the index is created. If you change the value of those parameters after the index is already created, the settings won’t be applied. So the parameters will only be used when creating the index for the first time.

If you want to use a custom ID in Elasticsearch, you can use @Id annotations. If you use @Id annotations, Spring Data will tell Elasticsearch to store the ID in the document and the document source.

The @Field type will determine the field mapping of the field. Like shards , replicas , and refreshInterval , the @Field type will only affect Elasticsearch when first creating the index. If you add a new field or change types when the index is already created, it won’t do anything.

Now that we configured the entity, let’s try out the automatic index creation by Spring Data! When we configure the createIndex as true , Spring Data will check whether the index exists in Elasticsearch. If it doesn’t exist, Spring Data will create the index with the configuration we created in the entity.

Let’s start our app. After it’s running, let’s check the settings and see if it’s correct:

The result is:

Everything is as we configured! The refresh_interval is set to 5s , the number_of_shards is 1 , and number_of_replicas is 0 .

Now let’s check the mappings:

The result is:

The mappings are also as we expected. It’s the same as we configured in the entity class.

Basic CRUD with the Spring Data repository interface

After we’ve created the entity, we’ve everything we need to create a repository interface in Spring Boot. Let’s create a repository called ProductRepository .

When you’re creating an interface, make sure to extend ElasticsearchRepository<T, U> . In this case, the T object is your entity, and the U object type you want to use for the data ID. In our case, we’ll use the Product entity we created earlier as T and String as U .

Now that your repository interface is done, you don’t need to take care of the implementation because Spring is taking care of it. Now, you can call every function in the classes that your repository extends to.

For examples of CRUD, you can check the code below:

In the code blocks above, we created a service class called SpringDataProductServiceImpl , which is autowired to the ProductRepository we created before.

There are four basic CRUD function in it. The first one is createProduct , which, as its name implies, will create a new product in the product index. The second one, getProduct , gets the product we’ve indexed by its ID. The deleteProduct function can be used to delete the product in the index by ID.The insertBulk function will allow you to insert multiple products to Elasticsearch.

Everything’s done! I won’t write about the API testing in this article because I want to focus on how our apps can interact with Elasticsearch. But if you want to try the API, I left a GitHub link at the end of the article so you can clone and try this project.

Custom query methods in the Spring Data

In the previous section, we only took advantage of using the basic methods that are already defined in the other classes. But we can also create custom query methods to use.

What’s very convenient about Spring Data is you can make a method in the repository interface, and you don’t need to code any implementation. The Spring Data library will read the repository and automatically create the implementations for it.

Let’s try searching for products by the name field:

Yes, that’s all you need to do to create a function in the Spring Data repository interface.

You can also define a custom query with the @Query annotation and insert a JSON query in the parameters.

Both of the methods we’ve created do the same thing — use the match query with name as its parameter. If you try it, you’ll get the same results.

Using ElasticsearchRestTemplate

If you want to do a more advanced query, like aggregations, highlighting, or suggestions, you can use the ElasticsearchsearchRestTemplate provided by the Spring Data library. By using it, you can create your own query, making itas complex as you want.

For example, let’s create a function for doing a match query to the name field like before:

You should notice the code above is more complex than the one we defined in the ElasticserchRepository . It’s recommended to use the Spring Data repository if you can. But for a more advanced query like aggregation, highlighting, or suggestions, you must use the ElasticsearchRestTemplate .

For example, let’s write a bit of code that’ll aggregate a term: