spring-boot
Spring Boot + Spring Data Elasticsearch
Buscar..
Introducción
Spring Data Elasticsearch es una implementación de Spring Data para Elasticsearch que proporciona integración con el motor de búsqueda Elasticsearch .
Integración de Spring Boot y Spring Data Elasticsearch
En este ejemplo, vamos a implementar el proyecto spring-data-elasticsearch para almacenar POJO en elasticsearch. Veremos un proyecto de maven muestra que hace lo siguiente:
- Inserte un elemento de
Greeting(id, username, message)
en elasticsearch. - Obtener todos los elementos de saludo que se han insertado.
- Actualizar un elemento de saludo.
- Eliminar un elemento de saludo.
- Obtener un elemento de saludo por id.
- Obtener todos los artículos de saludo por nombre de usuario.
Integración elasticsearch de arranque y datos de primavera.
En este ejemplo, vamos a ver una aplicación de arranque de primavera basada en Maven que integra Spring-Data-elasticsearch. Aquí, haremos lo siguiente y veremos los segmentos de código respectivos.
- Inserte un elemento de
Greeting(id, username, message)
en elasticsearch. - Obtener todos los artículos de elasticsearch
- Actualizar un elemento específico.
- Eliminar un elemento específico.
- Obtener un elemento específico por id.
- Obtener un artículo específico por nombre de usuario.
Archivo de configuración del proyecto (pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springdataes</groupId>
<artifactId>springdataes</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Usaremos Spring Boot de la versión 1.5.6.RELEASE
y Spring Data Elasticsearch de esa versión respectiva. Para este proyecto, necesitamos ejecutar elasticsearch-2.4.5 para probar nuestros apis.
Archivo de propiedades
Pondremos el archivo de propiedades del proyecto (llamado applications.properties
) en resources
carpeta de resources
que contiene:
elasticsearch.clustername = elasticsearch
elasticsearch.host = localhost
elasticsearch.port = 9300
Usaremos el nombre de clúster, el host y el puerto predeterminados. De forma predeterminada, el puerto 9300
se utiliza como puerto de transporte y el puerto 9200
se conoce como puerto http. Para ver el nombre del clúster predeterminado, pulse http: // localhost: 9200 / .
Clase principal (Application.java)
package org.springdataes;
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);
}
}
@SpringBootApplication
es una combinación de @Configuration
, @EnableAutoConfiguration
, @EnableWebMvc
y @ComponentScan
anotaciones. El método main()
utiliza el método SpringApplication.run()
Spring Boot para iniciar una aplicación. No necesitamos ninguna configuración xml, esta aplicación es una aplicación java spring pura.
Clase de configuración de Elasticsearch (ElasticsearchConfig.java)
package org.springdataes.config;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
import java.net.InetAddress;
@Configuration
@PropertySource(value = "classpath:applications.properties")
@EnableElasticsearchRepositories(basePackages = "org.springdataes.dao")
public class ElasticsearchConfig {
@Value("${elasticsearch.host}")
private String EsHost;
@Value("${elasticsearch.port}")
private int EsPort;
@Value("${elasticsearch.clustername}")
private String EsClusterName;
@Bean
public Client client() throws Exception {
Settings esSettings = Settings.settingsBuilder()
.put("cluster.name", EsClusterName)
.build();
return TransportClient.builder()
.settings(esSettings)
.build()
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(EsHost), EsPort));
}
@Bean
public ElasticsearchOperations elasticsearchTemplate() throws Exception {
return new ElasticsearchTemplate(client());
}
}
ElasticsearchConfig
clase ElasticsearchConfig
configura elasticsearch para este proyecto y establece una conexión con elasticsearch. Aquí, se utiliza @PropertySource
para leer el archivo application.properties
donde almacenamos el nombre del clúster, el host de elasticsearch y el puerto. @EnableElasticsearchRepositories
se utiliza para habilitar los repositorios de Elasticsearch que escanearán los paquetes de la clase de configuración anotada para los repositorios de Spring Data de forma predeterminada. @Value
se usa aquí para leer las propiedades del archivo application.properties
.
El método Client()
crea una conexión de transporte con elasticsearch. La configuración anterior configura un servidor de Elasticsearch integrado que es utilizado por ElasticsearchTemplate
. El bean ElasticsearchTemplate
utiliza el Elasticsearch Client
y proporciona una capa personalizada para manipular datos en Elasticsearch.
Clase modelo (Greeting.java)
package org.springdataes.model;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import java.io.Serializable;
@Document(indexName = "index", type = "greetings")
public class Greeting implements Serializable{
@Id
private String id;
private String username;
private String message;
public Greeting() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
Aquí hemos anotado nuestros objetos de datos de Greeting
con una anotación @Document que también podemos utilizar para determinar la configuración del índice como el nombre, el número de fragmentos o el número de réplicas. Uno de los atributos de la clase debe ser un id
, ya sea @Id
con @Id
o usando uno de los nombres que se encuentran automáticamente como id
o documentId
. Aquí, el valor del campo id
generará automáticamente, si no configuramos ningún valor del campo id
.
Clase de repositorio de Elasticsearch (GreetingRepository.class)
package org.springdataes.dao;
import org.springdataes.model.Greeting;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import java.util.List;
public interface GreetingRepository extends ElasticsearchRepository<Greeting, String> {
List<Greeting> findByUsername(String username);
}
Aquí, hemos ampliado ElasticsearchRepository
que nos proporciona muchas de las API que no necesitamos definir externamente. Esta es la clase de repositorio base para las clases de dominio basadas en elasticsearch
. Dado que amplía las clases de repositorio basadas en Spring
, obtenemos el beneficio de evitar el código de repetición requerido para implementar capas de acceso a datos para varios almacenes de persistencia.
Aquí hemos declarado un método findByUsername(String username)
que se convertirá en una consulta de coincidencia que coincide con el nombre de usuario con el campo de username
de username
de Objetos de Greeting
y devuelve la lista de resultados.
Servicios (GreetingService.java)
package org.springdataes.service;
import org.springdataes.model.Greeting;
import java.util.List;
public interface GreetingService {
List<Greeting> getAll();
Greeting findOne(String id);
Greeting create(Greeting greeting);
Greeting update(Greeting greeting);
List<Greeting> getGreetingByUsername(String username);
void delete(String id);
}
Servicio Bean (GreetingServiceBean.java)
package org.springdataes.service;
import com.google.common.collect.Lists;
import org.springdataes.dao.GreetingRepository;
import org.springdataes.model.Greeting;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class GreetingServiceBean implements GreetingService {
@Autowired
private GreetingRepository repository;
@Override
public List<Greeting> getAll() {
return Lists.newArrayList(repository.findAll());
}
@Override
public Greeting findOne(String id) {
return repository.findOne(id);
}
@Override
public Greeting create(Greeting greeting) {
return repository.save(greeting);
}
@Override
public Greeting update(Greeting greeting) {
Greeting persitedGreeting = repository.findOne(greeting.getId());
if(persitedGreeting == null) {
return null;
}
return repository.save(greeting);
}
@Override
public List<Greeting> getGreetingByUsername(String username) {
return repository.findByUsername(username);
}
@Override
public void delete(String id) {
repository.delete(id);
}
}
En la clase anterior, hemos @Autowired
the GreetingRepository
. Simplemente podemos llamar a los métodos de CRUDRepository
y al método que hemos declarado en la clase de repositorio con el objeto GreetingRepository
.
En el método getAll()
, puede encontrar una línea Lists.newArrayList(repository.findAll())
. Hemos hecho esto para convertir repository.findAll()
en el elemento List<>
, ya que devuelve una lista Iterable
.
Clase de controlador (GreetingController.java)
package org.springdataes.controller;
import org.springdataes.model.Greeting;
import org.springdataes.service.GreetingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api")
public class GreetingController {
@Autowired
private GreetingService greetingService;
@ResponseBody
@RequestMapping(value = "/greetings", method = RequestMethod.GET)
public ResponseEntity<List<Greeting>> getAll() {
return new ResponseEntity<List<Greeting>>(greetingService.getAll(), HttpStatus.OK);
}
@ResponseBody
@RequestMapping(value = "/greetings", method = RequestMethod.POST)
public ResponseEntity<Greeting> insertGreeting(@RequestBody Greeting greeting) {
return new ResponseEntity<Greeting>(greetingService.create(greeting), HttpStatus.CREATED);
}
@ResponseBody
@RequestMapping(value = "/greetings", method = RequestMethod.PUT)
public ResponseEntity<Greeting> updateGreeting(@RequestBody Greeting greeting) {
return new ResponseEntity<Greeting>(greetingService.update(greeting), HttpStatus.MOVED_PERMANENTLY);
}
@ResponseBody
@RequestMapping(value = "/greetings/{id}", method = RequestMethod.DELETE)
public ResponseEntity<Greeting> deleteGreeting(@PathVariable("id") String idd) {
greetingService.delete(idd);
return new ResponseEntity<Greeting>(HttpStatus.NO_CONTENT);
}
@ResponseBody
@RequestMapping(value = "/greetings{id}", method = RequestMethod.POST)
public ResponseEntity<Greeting> getOne(@PathVariable("id") String idd) {
return new ResponseEntity<Greeting>(greetingService.findOne(idd), HttpStatus.OK);
}
@ResponseBody
@RequestMapping(value = "/greetings/{name}", method = RequestMethod.GET)
public ResponseEntity<List<Greeting>> getByUserName(@PathVariable("name") String name) {
return new ResponseEntity<List<Greeting>>(greetingService.getGreetingByUsername(name), HttpStatus.OK);
}
}
Construir
Para construir esta aplicación maven ejecutar
mvn clean install
El comando anterior primero elimina todos los archivos en la carpeta de target
y crea el proyecto. Después de construir el proyecto obtendremos el archivo ejecutable .jar que se llama springdataes-1.0-SNAPSHOT.jar
. Podemos ejecutar la clase principal ( Application.java
) para iniciar el proceso o simplemente ejecutando el tarro anterior escribiendo:
java -jar springdataes-1.0-SNAPSHOT.jar
Comprobando las APIs
Para insertar un elemento de saludo en elasticsearch, ejecute el siguiente comando
curl -H "Content-Type: application/json" -X POST -d '{"username":"sunkuet02","message": "this is a message"}' http://localhost:8080/api/greetings
Debería obtener el siguiente resultado como
{"id":"AV2ddRxBcuirs1TrVgHH","username":"sunkuet02","message":"this is a message"}
También puede verificar la API de obtención ejecutando:
curl -H "Content-Type: application/json" -X GET http://localhost:8080/api/greetings
Usted debe obtener
[{"id":"AV2ddRxBcuirs1TrVgHH","username":"sunkuet02","message":"this is a message"}]
Puedes consultar otras apis siguiendo los procesos anteriores.
Documentaciones oficiales: