19-01-07
banq
演示的目标
- 使用Spring Data ElasticSearch连接并查询嵌入式ElasticSearch节点
- 使用Spring Data ElasticSearch连接并查询外部ElasticSearch节点
- 所有在ElasticSearch API 5.5.0中运行的东西都嵌入在Spring Boot 2.0中
演示先决条件:
我们要将以下文档保存到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 和参数类型,可检查document.
为了测试目的,让我们创建以下两个REST控制器来调用Spring Data ElasticSearch CRUD存储库:
@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讨论。ES文档说明:
NodeBuilder已被删除。虽然直接在应用程序中使用Node不受官方支持, 但它仍然可以使用Node(Settings)构造函数构建。 |
下面是我所做的:
@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; } |
有关节点参数列表,请查看以下文档。要使Spring Data ElasticSearch存储库正常工作,我们需要ElasticsearchTemplate:
@Profile("localNode") @Bean(name="elasticsearchTemplate") public ElasticsearchTemplate elasticsearchTemplate2() throws Exception { return new ElasticsearchTemplate(createLocalNode().client()); } |
这将根据您的需要使用NodeClient启动ElasticsearchTemplate 。Definitelly要注意以下两件事:
测试本地ElasticSearch节点
首先,我们需要构建项目:
$ mvn clean install |
然后使用localNode spring profile运行Spring Boot 2.0应用程序:
$ java -jar -Dspring.profiles.active=localNode target/demo-0.0.1-SNAPSHOT.jar |
ES本地节点应该启动了。
现在让我们测试一下,首先调用REST控制器端点将数据加载到ElasticSearch中:
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>"} |
好的,本地嵌入式节点工作正常!
连接并查询外部ElasticSearch节点
在这种情况下,我们不需要嵌入任何本地ES节点,我们只需要启动ES客户端。以下配置互联网:
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
@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工作:
@Profile("!localNode") @Bean(name = "elasticsearchTemplate") public ElasticsearchOperations elasticsearchTemplate1() throws Exception { return new ElasticsearchTemplate(client()); } |
准备好代码,让我们测试整个场景:
打开终端并启动外部ES服务器
$ elasticsearch
验证外部elasticsearch服务器是否正在运行:
$ 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:
$ java -jar target/demo-0.0.1-SNAPSHOT.jar |
然后让我们重复调用REST端点,将数据加载到ES中并查询:
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也可以正常工作。
原文源码点击标题