演示的目标
1、使用Spring Data ElasticSearch连接并查询嵌入式ElasticSearch节点 https://spring.io/projects/spring-data-elasticsearch 2、使用Spring Data ElasticSearch连接并查询外部ElasticSearch节点 3、所有在ElasticSearch API 5.5.0中运行的东西都嵌入在Spring Boot 2.0中
演示先决条件
代码语言:javascript复制我们要将以下文档保存到ElasticSearch中
@Document(indexName = "dataexchangecode", type = "dataTransferCode")
public class DataTransfer {
@Id
private String id;
private String dataExchangeCode;
private String data;
public DataTransfer() {
}
/**
* @param id
* @param dataExchangeCode
* @param data
*/
public DataTransfer(final String id, final String dataExchangeCode, final String data) {
this.id = id;
this.dataExchangeCode = dataExchangeCode;
this.data = data;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getDataExchangeCode() {
return dataExchangeCode;
}
public void setDataExchangeCode(String dataExchangeCode) {
this.dataExchangeCode = dataExchangeCode;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
@Override
public String toString() {
return this.id
this.dataExchangeCode
this.id;
}
}
要了解indexName和参数类型,可查看如下文章
https://www.elastic.co/guide/en/elasticsearch/guide/current/index-doc.html
为了测试目的,让我们创建以下两个REST控制器来调用Spring Data ElasticSearch CRUD存储库:
代码语言:javascript复制@Component
@RestController
public class HomeController {
@Autowired
private DataTransferRepository dataTransferRepository;
@GetMapping(value = "/prepareData")
public String prepareESData() {
final DataTransfer data = new DataTransfer("1", "AW_INPUT", "<XML>");
dataTransferRepository.save(data);
final DataTransfer data2 = new DataTransfer("2", "BSL_INPUT", "<XML>");
dataTransferRepository.save(data2);
return "Data saved into elastic search!";
}
@GetMapping(value = "/get/{id}")
public DataTransfer getDataTransfer(@PathVariable("id") String id) {
return dataTransferRepository.findById(id).get();
}
}
连接并查询嵌入式ElasticSearch节点
构建本地节点时请记住,ElasticSearch API 5.x已针对指定用于构建本地ES节点的NodeBuilder类进行了更改。例如,查看如下stackoverflow的讨论。
https://stackoverflow.com/questions/35342083/nodebuilder-not-found-in-the-elasticsearch-api-application
ES文档说明:
NodeBuilder已被删除。虽然直接在应用程序中使用Node不受官方支持, 但它仍然可以使用Node(Settings)构造函数构建。
下面是我所做的:
代码语言:javascript复制@Profile("localNode")
@Bean
public Node createLocalNode() throws NodeValidationException {
final String tmpDir = System.getProperty("java.io.tmpdir");
Settings.Builder elasticsearchSettings =
Settings.builder()
.put("cluster.name", EsClusterName)
.put("path.data", new File(tmpDir, "data").getAbsolutePath())
.put("path.logs", new File(tmpDir, "logs").getAbsolutePath())
.put("transport.type","local")
.put("http.enabled","false")
.put("path.home", tmpDir);
final Node node = new Node(elasticsearchSettings.build());
node.start();
return node;
}
有关节点参数列表,请查看以下文档
https://www.elastic.co/guide/en/elasticsearch/reference/2.1/modules-http.html
要使Spring Data ElasticSearch存储库正常工作,我们需要ElasticsearchTemplate:
代码语言:javascript复制@Profile("localNode")
@Bean(name="elasticsearchTemplate")
public ElasticsearchTemplate elasticsearchTemplate2() throws Exception {
return new ElasticsearchTemplate(createLocalNode().client());
}
这将根据您的需要使用NodeClient启动ElasticsearchTemplate 。Definitelly要注意以下两件事:
1、NodeClient和TransportClient之间的区别 https://www.elastic.co/guide/en/elasticsearch/guide/current/transportclientversusnode_client.html 2、最重要的是,不推荐使用TransportClient https://www.elastic.co/guide/en/elasticsearch/client/java-api/master/transport-client.html
测试本地ElasticSearch节点
首先,我们需要构建项目:
代码语言:javascript复制$ mvn clean install
然后使用localNode spring profile运行Spring Boot 2.0应用程序:
代码语言:javascript复制$ java -jar -Dspring.profiles.active=localNode target/demo-0.0.1-SNAPSHOT.jar
ES本地节点应该启动了。
现在让我们测试一下,首先调用REST控制器端点将数据加载到ElasticSearch中:
代码语言:javascript复制curl http://localhost:8080/prepareData
Data saved into elastic search!
然后我们可以查询数据:
代码语言:javascript复制$ curl http://localhost:8080/get/1 {"id":"1","dataExchangeCode":"AW_INPUT","data":"<XML>"}
代码语言:javascript复制$ curl http://localhost:8080/get/2 {"id":"2","dataExchangeCode":"BSL_INPUT","data":"<XML>"}
好的,本地嵌入式节点工作正常!
连接并查询外部ElasticSearch节点
在这种情况下,我们不需要嵌入任何本地ES节点,我们只需要启动ES客户端。以下配置互联网:
代码语言:javascript复制Settings settings = Settings.builder()
.put("cluster.name", EsClusterName).build();
TransportClient client = new PreBuiltTransportClient(settings);
client.addTransportAddress(
new InetSocketTransportAddress(
InetAddress.getByName(EsHost), EsPort));
好吧,嵌入在Spring Boot 2.0中的ES API不能与PreBuiltTransportClient一起使用,因为它需要Netty3Plugin,这个无法放到maven依赖项中。如果您仍然不希望 highlevel REST API ,可以还是使用TransportClientFactoryBean 委托给SpringDataTransportClient
代码语言:javascript复制@Profile("!localNode")
@Bean
public Client client() throws Exception {
/**
* PreBuiltTransportClient works fine, but requires Netty3Plugin
* and Spring Boot offers only Netty4Plugin. Needs extra dependencies.
Settings settings = Settings.builder()
.put("cluster.name", EsClusterName).build();
TransportClient client = new PreBuiltTransportClient(settings);
client.addTransportAddress(
new InetSocketTransportAddress(
InetAddress.getByName(EsHost), EsPort));
return client;
*/
TransportClientFactoryBean client = new TransportClientFactoryBean();
client.setClusterName(EsClusterName);
client.afterPropertiesSet();
return client.getObject();
}
当然,我们需要再次使用ElasticsearchTemplate来使Spring Data ES工作:
代码语言:javascript复制@Profile("!localNode")
@Bean(name = "elasticsearchTemplate")
public ElasticsearchOperations elasticsearchTemplate1() throws Exception {
return new ElasticsearchTemplate(client());
}
准备好代码,让我们测试整个场景:
打开终端并启动外部ES服务器
代码语言:javascript复制$ elasticsearch
验证外部elasticsearch服务器是否正在运行:
代码语言:javascript复制$ curl http://localhost:9200
{
"name" : "NmF778a",
"cluster_name" : "elasticsearch_tomask79",
"cluster_uuid" : "Z0CfKNMxSNGqfkUONZ6bRg",
"version" : {
"number" : "6.4.2",
"build_flavor" : "oss",
"build_type" : "tar",
"build_hash" : "04711c2",
"build_date" : "2018-09-26T13:34:09.098244Z",
"build_snapshot" : false,
"lucene_version" : "7.4.0",
"minimum_wire_compatibility_version" : "5.6.0",
"minimum_index_compatibility_version" : "5.0.0"
},
"tagline" : "You Know, for Search"
}
现在让我们使用默认的spring配置文件启动applicationn:
代码语言:javascript复制$ java -jar target/demo-0.0.1-SNAPSHOT.jar
然后让我们重复调用REST端点,将数据加载到ES中并查询:
代码语言:javascript复制curl http://localhost:8080/prepareData
Data saved into elastic search!
$ curl http://localhost:8080/get/1
{"id":"1","dataExchangeCode":"AW_INPUT","data":"<XML>"}
$ curl http://localhost:8080/get/2
{"id":"2","dataExchangeCode":"BSL_INPUT","data":"<XML>"}
连接到外部ES也可以正常工作。
demo地址
https://bitbucket.org/tomask79/elastic-search-boot