Spring boot   elasticsearch的最簡單實踐

之所以說是最簡單,是因為這樣能搭建出一個能跑出來結果的框架,而更高階的功能往往就是在最簡單的框架的基礎上建設的,對吧。

客戶端環境:spring boot 1.4.1

ElasticSearch環境:Elasticsearch2.4.0 on Windows 2008R2 100.2.92.100:9300

POM:

<?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>miku.ltd</groupId>
<artifactId>esl</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.RELEASE</version>
</parent>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>2.0.4.RELEASE</version>
</dependency>
</dependencies>
</project>

為了更簡單的在spring boot中使用es,直接依賴spring-boot-starter-data-elasticsearch就可以了。

application.properties

server.port=12001
logging.level.org.springframework=INFO
spring.data.elasticsearch.cluster-name=elasticsearch
spring.data.elasticsearch.cluster-nodes=100.2.92.100:9300
spring.data.elasticsearch.local=false
spring.data.elasticsearch.repositories.enabled=true

AppMain.java

package ltd.miku.esl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
@SpringBootApplication
//@EnableElasticsearchRepositories(basePackages = {"ltd.miku.esl.dao"})
public class AppMain implements CommandLineRunner
{
public static ConfigurableApplicationContext ctx;
private static final Logger LOG = LoggerFactory.getLogger(AppMain.class);
@Override
public void run(String... strings) throws Exception
{
}
public static void main(String[] args)
{
ctx = SpringApplication.run(AppMain.class, args);
LOG.info(" application running...");
}
}

EslController.java

package ltd.miku.esl.controller;
import ltd.miku.esl.service.EslService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value = "/esl/")
public class EslController
{
@Autowired
private EslService esl;
private static final Logger LOG = LoggerFactory.getLogger(EslController.class);
@RequestMapping(value = "test", method = RequestMethod.POST)
public Object test(@RequestBody String id)
{
return esl.findCliente(id);
}
}

ClienteRepository.java

package ltd.miku.esl.dao;
import ltd.miku.esl.model.Cliente;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
public interface ClienteRepository extends ElasticsearchRepository<Cliente, String>
{
}

跟JPA或者mongo的DAO差不多是一樣的。

Cliente.java

package ltd.miku.esl.model;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
/**
* the bean of customer
*/
@Document(indexName = "customer", type = "external", shards = 1, replicas = 0, refreshInterval = "-1")
public class Cliente
{
@Id
private String id;
private long account_number;
private long balance;
private String firstname;
private String lastname;
private int age;
private String gender;
private String address;
private String employer;
private String email;
private String city;
private String state;
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public long getAccount_number()
{
return account_number;
}
public void setAccount_number(long account_number)
{
this.account_number = account_number;
}
public long getBalance()
{
return balance;
}
public void setBalance(long balance)
{
this.balance = balance;
}
public String getFirstname()
{
return firstname;
}
public void setFirstname(String firstname)
{
this.firstname = firstname;
}
public String getLastname()
{
return lastname;
}
public void setLastname(String lastname)
{
this.lastname = lastname;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
public String getGender()
{
return gender;
}
public void setGender(String gender)
{
this.gender = gender;
}
public String getAddress()
{
return address;
}
public void setAddress(String address)
{
this.address = address;
}
public String getEmployer()
{
return employer;
}
public void setEmployer(String employer)
{
this.employer = employer;
}
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email = email;
}
public String getCity()
{
return city;
}
public void setCity(String city)
{
this.city = city;
}
public String getState()
{
return state;
}
public void setState(String state)
{
this.state = state;
}
@Override
public String toString()
{
return "Cliente{"   "id='"   id   '\''   ", account_number="   account_number   ", balance="   balance   ", firstname='"   firstname   '\''   ", lastname='"   lastname   '\''   ", age="   age   ", gender='"   gender   '\''   ", address='"   address   '\''   ", employer='"   employer   '\''   ", email='"   email   '\''   ", city='"   city   '\''   ", state='"   state   '\''   '}';
}
}

EslService.java

package ltd.miku.esl.service;
import ltd.miku.esl.model.Cliente;
public interface EslService
{
Cliente findCliente(String id);
}

EslServiceImpl.java

package ltd.miku.esl.service.impl;
import ltd.miku.esl.dao.ClienteRepository;
import ltd.miku.esl.model.Cliente;
import ltd.miku.esl.service.EslService;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class EslServiceImpl implements EslService
{
@Autowired
private ClienteRepository clienteDao;
private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(EslServiceImpl.class);
@Override
public Cliente findCliente(String id)
{
Cliente cliente = clienteDao.findOne(id);
LOG.info(" get cliente by id {} is {}", id, cliente);
return cliente;
}
}

執行結果:

記錄問題:

1,在開發環境搭建的過程中,總是報錯:

Field clienteDao in ltd.miku.esl.service.impl.EslServiceImpl required a bean named ‘elasticsearchTemplate’ that could not be found

然後看看程式碼和POM,貌似配置也沒問題,後來發現了maven依賴有問題:

spring-data-elasticsearch-2.0.4.RELEASE.jar裡點名的依賴是2.2.0,但是idea的依賴中說缺少2.4.0

鄙視雖然不知道為啥但是在私服中加上2.4.0版本的就好用了。

2,早起開發的時候一直遇到連線不到ES節點的異常,但是用ES伺服器的9200埠進行http訪問就能正常連線,異常資訊如下:

16:33:54.196 [elasticsearch[Shuma-Gorath][generic][T#2]] INFO  org.elasticsearch.client.transport.internalInfo:124 - [Shuma-Gorath] failed to get node info for [#transport#-1][clauspc][inet[/100.2.92.100:9300]], disconnecting...
org.elasticsearch.transport.NodeDisconnectedException: [][inet[/100.2.92.100:9300]][cluster:monitor/nodes/info] disconnected
16:33:59.221 [elasticsearch[Shuma-Gorath][generic][T#2]] INFO  org.elasticsearch.client.transport.internalInfo:124 - [Shuma-Gorath] failed to get node info for [#transport#-1][clauspc][inet[/100.2.92.100:9300]], disconnecting...
org.elasticsearch.transport.NodeDisconnectedException: [][inet[/100.2.92.100:9300]][cluster:monitor/nodes/info] disconnected
16:34:04.245 [elasticsearch[Shuma-Gorath][generic][T#2]] INFO  org.elasticsearch.client.transport.internalInfo:124 - [Shuma-Gorath] failed to get node info for [#transport#-1][clauspc][inet[/100.2.92.100:9300]], disconnecting...
org.elasticsearch.transport.NodeDisconnectedException: [][inet[/100.2.92.100:9300]][cluster:monitor/nodes/info] disconnected

原因是Spring boot elasticsearch的版本跟100.2.92.100上的es版本相差太多導致的,升級spring的es版本為2.4.1就可以了。