Spring Data ElasticSearch
In this tutorial, we’ll look at the basics of Spring Data Elasticsearch with simple but practical CRUD operations.
We’ll look at how to index, search, and query Elasticsearch in a Spring application using Spring Data—a Spring module for interaction with a popular open-source, Lucene-based search engine called Elasticsearch.
While Elasticsearch is schemaless, it can use mappings in order to tell the type of a field. When a document is indexed, its fields are processed according to their types. It is a highly scalable open-source full-text search and analytics engine. It allows us to store, search, and analyze big volumes of data quickly and in near real time.
Though Spring Data Elasticsearch comes with its own Elasticsearch copy, feel free to read and explore the documentation.
Getting Started
Setting up elasticsearch is very simple and straightforward process. Let us get started quickly with a Maven dependency. Also, we will be setting up a Spring Boot project whose link is available at the end of this article.
Maven Dependency
To get started, add the required maven dependency as:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
As the project is Spring Boot based, it will take care of the latest dependency. For Spring Data Elasticsearch dependency without Spring Boot, look here.
Configuration via Java
Let’s now explore the Spring configuration of our persistence layer here:
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.node.NodeBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
@Configuration
@EnableElasticsearchRepositories(basePackages = "com.discoversdk.model")
@ComponentScan(basePackages = "com.discoversdk")
public class DataConfig {
@Value("{spring.data.elasticsearch.cluster-name}")
private String clusterName;
private static Logger logger = LoggerFactory.getLogger(DataConfig.class);
@Bean
public NodeBuilder nodeBuilder() {
return new NodeBuilder().clusterName(clusterName);
}
@Bean
public ElasticsearchOperations elasticsearchTemplate() {
final Settings.Builder elasticsearchSettings =
Settings.settingsBuilder().put("http.enabled", "true")
.put("index.number_of_shards", "1");
return new ElasticsearchTemplate(nodeBuilder()
.local(true)
.settings(elasticsearchSettings.build())
.node()
.client());
}
}
Notice that we’re using a standard Spring enable-style annotation, @EnableElasticsearchRepositories, to scan the provided package for Spring Data repositories.
We are also:
- Starting the Elasticsearch node without HTTP transport support
- Setting the location of the data files of each index allocated on the node
- Starting from Elasticsearch 2.x, we need to set “path.home” with Elasticsearch home directory
Finally, we’re also setting up an ElasticsearchOperations bean—elasticsearchTemplate—as our client to work against the Elasticsearch server.
Defining Entities
Next, let us define an entity which needs to be persisted to the elasticsearch cluster data.
Let’s now define our first entity—a document called Student with a String id:
@Document(indexName = "student", type = "person")
public class Student {
@Id
private String id;
private String name;
// getters and setters
}
Note the @Document annotation. It indicates that instances of this class should be stored in Elasticsearch in an index called “student”, and with a document type of “person”. Documents with many different types can be stored in the same index.
Defining Student Access Repository
Next we need to extend one of the provided repository interfaces, replacing the generic types with our actual document and primary key types.
Notice that ElasticsearchRepository extends PagingAndSortingRepository, which provides built-in support for pagination and sorting.
package com.discoversdk.elasticdemo.repository;
import com.discoversdk.model.Student;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface StudentRepository extends ElasticsearchRepository<Student, String> {
}
Indexing Documents
Spring Data Elasticsearch automatically generates all the indices based on the entities we made with the @Document annotation.
Still, if we need we can also create an index programmatically, via the client template:
elasticsearchTemplate.createIndex(Student.class);
After the index is available, we can add a document to the index.
Querying
Saving Data
In our project, we setup a simple Controller which will help us in saving the data and deleting it as well.
To start, let’s write a REST API to save the Student into the database:
@RequestMapping(
value = "/insert/student",
method = RequestMethod.POST)
public Student insertStudent(@RequestBody Student student){
return studentService.insertStudent(student);
}
Our service will do something like:
public Student insertStudent(Student student) {
return studentRepository.save(student);
}
It’s as simple as that. To save data, Spring Data Elasticsearch provides us with all of the general methods.
Deleting Data
To complete the Delete operation, we can build another service as:
@RequestMapping(value = "/delete/student/{id}", method = RequestMethod.GET)
public void deleteStudent(@PathVariable int id){
studentService.deleteStudent(id);
}
Our service layer will look like:
@Override
public void deleteStudent(int id) {
studentRepository.delete(String.valueOf(id));
}
Get All Data
Finally, once we have inserted enough data in it, we can write a simple service to get all of the data.
@RequestMapping(value = "/students", method = RequestMethod.GET)
public List<Student> getAllStudents(){
return studentService.getALlStudents();
}
Our service will look like:
@Override
public List<Student> getALlStudents() {
List<Student> students = new ArrayList<>();
studentRepository.findAll().forEach(students::add);
return students;
}
Not the part of Spring Data but finally we make a Spring Boot Application class:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Terminology
Some terminology will help in understand how Elasticsearch works.
- Cluster: A cluster is a collection of one or more nodes (servers) that together holds your entire data and provides federated indexing and search capabilities across all nodes.
- Node: A node is a single server that is part of your cluster, stores your data, and participates in the cluster’s indexing and search capabilities.
- Index: An index is a collection of documents that have somewhat similar characteristics.
- Type: Within an index, you can define one or more types. A type is a logical category/partition of your index whose semantics is completely up to you.
- A document is a basic unit of information that can be indexed. For example, you can have a document for a single customer, another document for a single product, and yet another for a single order.
Conclusion
This was a quick and practical discussion of the basic use of Spring Data Elasticsearch.
To read more about the impressive features of Elasticsearch, you can find its documentation on the official website.
The example used in this article is available as a sample project in GitHub. It is a simple maven based project so it should be easy to clone and run.
Recent Stories
Top DiscoverSDK Experts
Compare Products
Select up to three two products to compare by clicking on the compare icon () of each product.
{{compareToolModel.Error}}
{{CommentsModel.TotalCount}} Comments
Your Comment