Browse Source

Elasticsearcch 7.X

elasticsearch-rest-high-level-client 基本CURD 操作demo 完成
pull/1/head
fxbin Yangkai.Shen 5 years ago
parent
commit
ea00d4ce20
24 changed files with 995 additions and 165 deletions
  1. +25
    -0
      spring-boot-demo-elasticsearch-rest-high-level-client/.gitignore
  2. +473
    -0
      spring-boot-demo-elasticsearch-rest-high-level-client/README.md
  3. +18
    -4
      spring-boot-demo-elasticsearch-rest-high-level-client/pom.xml
  4. +1
    -1
      spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/ElasticsearchApplication.java
  5. +14
    -1
      spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/autoconfigure/ElasticsearchAutoConfiguration.java
  6. +25
    -9
      spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/autoconfigure/ElasticsearchProperties.java
  7. +1
    -1
      spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/contants/DataTypeTransfer.java
  8. +1
    -1
      spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/contants/ElasticsearchConstant.java
  9. +2
    -2
      spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/exception/ElasticsearchException.java
  10. +1
    -1
      spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/model/Person.java
  11. +1
    -1
      spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/model/Result.java
  12. +1
    -1
      spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/model/ResultCode.java
  13. +170
    -0
      spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/service/BaseElasticsearchService.java
  14. +68
    -0
      spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/service/PersonService.java
  15. +91
    -0
      spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/service/impl/PersonServiceImpl.java
  16. +29
    -12
      spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/util/BeanUtils.java
  17. +1
    -1
      spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/util/MapUtils.java
  18. +0
    -88
      spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xlcoding/elasticsearch/service/BaseElasticsearchService.java
  19. +0
    -11
      spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xlcoding/elasticsearch/service/PersonService.java
  20. +0
    -14
      spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xlcoding/elasticsearch/service/impl/PersonServiceImpl.java
  21. +3
    -0
      spring-boot-demo-elasticsearch-rest-high-level-client/src/main/resources/META-INF/spring.factories
  22. +6
    -0
      spring-boot-demo-elasticsearch-rest-high-level-client/src/main/resources/application.yml
  23. +0
    -17
      spring-boot-demo-elasticsearch-rest-high-level-client/src/test/java/com/xdcoding/elasticsearch/ElasticsearchApplicationTests.java
  24. +64
    -0
      spring-boot-demo-elasticsearch-rest-high-level-client/src/test/java/com/xkcoding/elasticsearch/ElasticsearchApplicationTests.java

+ 25
- 0
spring-boot-demo-elasticsearch-rest-high-level-client/.gitignore View File

@@ -0,0 +1,25 @@
/target/
!.mvn/wrapper/maven-wrapper.jar

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr

### NetBeans ###
/nbproject/private/
/build/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

+ 473
- 0
spring-boot-demo-elasticsearch-rest-high-level-client/README.md View File

@@ -0,0 +1,473 @@
# spring-boot-demo-elasticsearch-rest-high-level-client

> 此 demo 主要演示了 Spring Boot 如何集成 `elasticsearch-rest-high-level-client` 完成对 ElasticSearch 的基本CURD 操作

## elasticsearch 升级

先升级到 6.8,索引创建,设置 mapping 等操作加参数:include_type_name=true,然后滚动升级到 7,旧索引可以用 type 访问。具体可以参考:

https://www.elastic.co/cn/blog/moving-from-types-to-typeless-apis-in-elasticsearch-7-0

https://www.elastic.co/guide/en/elasticsearch/reference/7.0/removal-of-types.html

## 注意

作者编写本demo时,ElasticSearch版本为 `7.3.0`,使用 docker 运行,下面是所有步骤:

1. 下载镜像:`docker pull elasticsearch:7.3.0`

2. 下载安装 `docker-compose`
```
sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
参考文档: https://docs.docker.com/compose/install/
```

2. 编写docker-compose 文件
```yaml
version: "3"

services:
es7:
hostname: es7
container_name: es7
image: elasticsearch:7.3.0
volumes:
- "/data/es7/logs:/usr/share/es7/logs:rw"
- "/data/es7/data:/usr/share/es7/data:rw"
restart: on-failure
ports:
- "9200:9200"
- "9300:9300"
environment:
cluster.name: elasticsearch
discovery.type: single-node
logging:
driver: "json-file"
options:
max-size: "50m"

```
3. 启动: `docker-compose -f elasticsearch.yaml up -d`


## pom.xml

```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>
<parent>
<artifactId>spring-boot-demo</artifactId>
<groupId>com.xkcoding</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>

<artifactId>spring-boot-demo-elasticsearch-rest-high-level-client</artifactId>
<name>spring-boot-demo-elasticsearch-rest-high-level-client</name>
<description>Demo project for Spring Boot</description>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<!-- test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<!-- validator -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<scope>compile</scope>
</dependency>

<!--
You can easily generate your own configuration metadata file from items annotated with
@ConfigurationProperties by using the spring-boot-configuration-processor jar.
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>

<!-- 工具类 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.6.6</version>
</dependency>

<!-- elasticsearch -->
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.3.0</version>
</dependency>

<!-- elasticsearch-rest-client -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.3.0</version>
</dependency>

<!-- elasticsearch-rest-high-level-client -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.3.0</version>
<exclusions>
<exclusion>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
</exclusion>
<exclusion>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
</exclusion>
</exclusions>
</dependency>

<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>

</dependencies>

</project>

```

## Person.java

> 实体类
>

```java
package com.xkcoding.elasticsearch.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.Date;

/**
* Person
*
* @author fxbin
* @version v1.0
* @since 2019/9/15 23:04
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Person implements Serializable {

private static final long serialVersionUID = 8510634155374943623L;

/**
* 主键
*/
private Long id;

/**
* 名字
*/
private String name;

/**
* 国家
*/
private String country;

/**
* 年龄
*/
private Integer age;

/**
* 生日
*/
private Date birthday;

/**
* 介绍
*/
private String remark;

}

```

## PersonService.java

```java
package com.xkcoding.elasticsearch.service;

import com.xkcoding.elasticsearch.model.Person;
import org.springframework.lang.Nullable;

import java.util.List;

/**
* PersonService
*
* @author fxbin
* @version v1.0
* @since 2019/9/15 23:07
*/
public interface PersonService {

/**
* create Index
*
* @author fxbin
* @param index elasticsearch index name
*/
void createIndex(String index);

/**
* delete Index
*
* @author fxbin
* @param index elasticsearch index name
*/
void deleteIndex(String index);

/**
* insert document source
*
* @author fxbin
* @param index elasticsearch index name
* @param list data source
*/
void insert(String index, List<Person> list);

/**
* update document source
*
* @author fxbin
* @param index elasticsearch index name
* @param list data source
*/
void update(String index, List<Person> list);

/**
* delete document source
*
* @author fxbin
* @param person delete data source and allow null object
*/
void delete(String index, @Nullable Person person);

/**
* search all doc records
*
* @author fxbin
* @param index elasticsearch index name
* @return person list
*/
List<Person> searchList(String index);

}

```

## PersonServiceImpl.java

> service 实现类型,基本CURD操作

```java
package com.xkcoding.elasticsearch.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.xkcoding.elasticsearch.model.Person;
import com.xkcoding.elasticsearch.service.BaseElasticsearchService;
import com.xkcoding.elasticsearch.service.PersonService;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.SearchHit;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
* PersonServiceImpl
*
* @author fxbin
* @version v1.0
* @since 2019/9/15 23:08
*/
@Service
public class PersonServiceImpl extends BaseElasticsearchService implements PersonService {


@Override
public void createIndex(String index) {
createIndexRequest(index);
}

@Override
public void deleteIndex(String index) {
deleteIndexRequest(index);
}

@Override
public void insert(String index, List<Person> list) {

try {
list.forEach(person -> {
IndexRequest request = buildIndexRequest(index, String.valueOf(person.getId()), person);
try {
client.index(request, COMMON_OPTIONS);
} catch (IOException e) {
e.printStackTrace();
}
});
} finally {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

@Override
public void update(String index, List<Person> list) {
list.forEach(person -> {
updateRequest(index, String.valueOf(person.getId()), person);
});
}

@Override
public void delete(String index, Person person) {
if (ObjectUtils.isEmpty(person)) {
// 如果person 对象为空,则删除全量
searchList(index).forEach(p -> {
deleteRequest(index, String.valueOf(p.getId()));
});
}
deleteRequest(index, String.valueOf(person.getId()));
}

@Override
public List<Person> searchList(String index) {
SearchResponse searchResponse = search(index);
SearchHit[] hits = searchResponse.getHits().getHits();
List<Person> personList = new ArrayList<>();
Arrays.stream(hits).forEach(hit -> {
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
Person person = BeanUtil.mapToBean(sourceAsMap, Person.class, true);
personList.add(person);
});
return personList;
}
}

```


## ElasticsearchApplicationTests.java

> 主要功能测试,参见service 注释说明

```java
package com.xkcoding.elasticsearch;

import com.xkcoding.elasticsearch.contants.ElasticsearchConstant;
import com.xkcoding.elasticsearch.model.Person;
import com.xkcoding.elasticsearch.service.PersonService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ElasticsearchApplicationTests {

@Resource
private PersonService personService;

@Test
public void deleteIndexTest() {
personService.deleteIndex(ElasticsearchConstant.INDEX_NAME);
}

@Test
public void createIndexTest() {
personService.createIndex(ElasticsearchConstant.INDEX_NAME);
}

@Test
public void insertTest() {

List<Person> list = new ArrayList<>();
list.add(Person.builder().age(11).birthday(new Date()).country("CN").id(1L).name("哈哈").remark("test1").build());
list.add(Person.builder().age(22).birthday(new Date()).country("US").id(2L).name("hiahia").remark("test2").build());
list.add(Person.builder().age(33).birthday(new Date()).country("ID").id(3L).name("呵呵").remark("test3").build());

personService.insert(ElasticsearchConstant.INDEX_NAME, list);
}

@Test
public void updateTest() {
Person person = Person.builder().age(33).birthday(new Date()).country("ID_update").id(3L).name("呵呵update").remark("test3_update").build();
List<Person> list = new ArrayList<>();
list.add(person);
personService.update(ElasticsearchConstant.INDEX_NAME, list);
}

@Test
public void deleteTest() {
personService.delete(ElasticsearchConstant.INDEX_NAME, Person.builder().id(1L).build());
}

@Test
public void searchListTest() {
List<Person> personList = personService.searchList(ElasticsearchConstant.INDEX_NAME);
System.out.println(personList);
}


}

```

## 参考

1. ElasticSearch 官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
2. Java High Level REST Client:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.3/java-rest-high.html


+ 18
- 4
spring-boot-demo-elasticsearch-rest-high-level-client/pom.xml View File

@@ -49,6 +49,13 @@
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>

<!-- 工具类 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.6.6</version>
</dependency>

<!-- elasticsearch -->
<dependency>
<groupId>org.elasticsearch</groupId>
@@ -56,16 +63,23 @@
<version>7.3.0</version>
</dependency>

<!-- elasticsearch-rest-client -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.3.0</version>
</dependency>

<!-- elasticsearch-rest-high-level-client -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.3.0</version>
<exclusions>
<!-- <exclusion>-->
<!-- <groupId>org.elasticsearch.client</groupId>-->
<!-- <artifactId>elasticsearch-rest-client</artifactId>-->
<!-- </exclusion>-->
<exclusion>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
</exclusion>
<exclusion>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>


spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xlcoding/elasticsearch/ElasticsearchApplication.java → spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/ElasticsearchApplication.java View File

@@ -1,4 +1,4 @@
package com.xlcoding.elasticsearch;
package com.xkcoding.elasticsearch;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xlcoding/elasticsearch/autoconfigure/ElasticsearchAutoConfiguration.java → spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/autoconfigure/ElasticsearchAutoConfiguration.java View File

@@ -1,6 +1,10 @@
package com.xlcoding.elasticsearch.autoconfigure;
package com.xkcoding.elasticsearch.autoconfigure;

import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
@@ -78,6 +82,15 @@ public class ElasticsearchAutoConfiguration {
httpClientBuilder.setMaxConnPerRoute(elasticsearchProperties.getMaxConnectPerRoute());
return httpClientBuilder;
});

// Callback used the basic credential auth
ElasticsearchProperties.Account account = elasticsearchProperties.getAccount();
if (!StringUtils.isEmpty(account.getUsername()) && !StringUtils.isEmpty(account.getUsername())) {
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();

credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(account.getUsername(), account.getPassword()));
}
return new RestHighLevelClient(builder);
}


spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xlcoding/elasticsearch/autoconfigure/ElasticsearchProperties.java → spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/autoconfigure/ElasticsearchProperties.java View File

@@ -1,9 +1,6 @@
package com.xlcoding.elasticsearch.autoconfigure;
package com.xkcoding.elasticsearch.autoconfigure;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.*;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@@ -70,21 +67,40 @@ public class ElasticsearchProperties {
/**
* 索引配置信息
*/
private Index index;
private Index index = new Index();

/**
* 认证账户
*/
private Account account = new Account();

@Data
@Builder
public static class Index {

/**
* 分片数量
*/
protected Integer numberOfShards = 3;
private Integer numberOfShards = 3;

/**
* 副本数量
*/
protected Integer numberOfReplicas = 2;
private Integer numberOfReplicas = 2;

}

@Data
public static class Account {

/**
* 认证用户
*/
private String username;

/**
* 认证密码
*/
private String password;

}


spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xlcoding/elasticsearch/contants/DataTypeTransfer.java → spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/contants/DataTypeTransfer.java View File

@@ -1,4 +1,4 @@
package com.xlcoding.elasticsearch.contants;
package com.xkcoding.elasticsearch.contants;

/**
* DataTypeTransfer

spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xlcoding/elasticsearch/contants/ElasticsearchConstant.java → spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/contants/ElasticsearchConstant.java View File

@@ -1,4 +1,4 @@
package com.xlcoding.elasticsearch.contants;
package com.xkcoding.elasticsearch.contants;

/**
* ElasticsearchConstant

spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xlcoding/elasticsearch/exception/ElasticsearchException.java → spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/exception/ElasticsearchException.java View File

@@ -1,6 +1,6 @@
package com.xlcoding.elasticsearch.exception;
package com.xkcoding.elasticsearch.exception;

import com.xlcoding.elasticsearch.model.ResultCode;
import com.xkcoding.elasticsearch.model.ResultCode;
import lombok.Getter;

/**

spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xlcoding/elasticsearch/model/Person.java → spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/model/Person.java View File

@@ -1,4 +1,4 @@
package com.xlcoding.elasticsearch.model;
package com.xkcoding.elasticsearch.model;

import lombok.AllArgsConstructor;
import lombok.Builder;

spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xlcoding/elasticsearch/model/Result.java → spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/model/Result.java View File

@@ -1,4 +1,4 @@
package com.xlcoding.elasticsearch.model;
package com.xkcoding.elasticsearch.model;

import lombok.Data;
import org.springframework.lang.Nullable;

spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xlcoding/elasticsearch/model/ResultCode.java → spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/model/ResultCode.java View File

@@ -1,4 +1,4 @@
package com.xlcoding.elasticsearch.model;
package com.xkcoding.elasticsearch.model;

import lombok.AllArgsConstructor;
import lombok.Getter;

+ 170
- 0
spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/service/BaseElasticsearchService.java View File

@@ -0,0 +1,170 @@
package com.xkcoding.elasticsearch.service;

import com.xkcoding.elasticsearch.exception.ElasticsearchException;
import com.xkcoding.elasticsearch.autoconfigure.ElasticsearchProperties;
import com.xkcoding.elasticsearch.util.BeanUtils;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.HttpAsyncResponseConsumerFactory;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.engine.Engine;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;

import javax.annotation.Resource;
import java.io.IOException;

/**
* BaseElasticsearchService
*
* @author fxbin
* @version 1.0v
* @since 2019/9/16 15:44
*/
@Slf4j
public abstract class BaseElasticsearchService {

@Resource
protected RestHighLevelClient client;

@Resource
private ElasticsearchProperties elasticsearchProperties;

protected static final RequestOptions COMMON_OPTIONS;

static {
RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();

// 默认缓冲限制为100MB,此处修改为30MB。
builder.setHttpAsyncResponseConsumerFactory(
new HttpAsyncResponseConsumerFactory
.HeapBufferedResponseConsumerFactory(30 * 1024 * 1024));
COMMON_OPTIONS = builder.build();
}

/**
* create elasticsearch index (asyc)
*
* @author fxbin
* @param index elasticsearch index
*/
protected void createIndexRequest(String index) {
try {
CreateIndexRequest request = new CreateIndexRequest(index);
// Settings for this index
request.settings(Settings.builder()
.put("index.number_of_shards", elasticsearchProperties.getIndex().getNumberOfShards())
.put("index.number_of_replicas", elasticsearchProperties.getIndex().getNumberOfReplicas()));

CreateIndexResponse createIndexResponse = client.indices().create(request, COMMON_OPTIONS);

log.info(" whether all of the nodes have acknowledged the request : {}", createIndexResponse.isAcknowledged());
log.info(" Indicates whether the requisite number of shard copies were started for each shard in the index before timing out :{}",
createIndexResponse.isShardsAcknowledged());
} catch (IOException e) {
throw new ElasticsearchException("创建索引 {" + index + "} 失败");
}
}

/**
* delete elasticsearch index
*
* @author fxbin
* @param index elasticsearch index name
*/
protected void deleteIndexRequest(String index) {
DeleteIndexRequest deleteIndexRequest = buildDeleteIndexRequest(index);
try {
client.indices().delete(deleteIndexRequest, COMMON_OPTIONS);
} catch (IOException e) {
throw new ElasticsearchException("删除索引 {" + index + "} 失败");
}
}

/**
* build DeleteIndexRequest
*
* @author fxbin
* @param index elasticsearch index name
*/
private static DeleteIndexRequest buildDeleteIndexRequest (String index) {
return new DeleteIndexRequest(index);
}

/**
* build IndexRequest
*
* @author fxbin
* @param index elasticsearch index name
* @param id request object id
* @param object request object
* @return {@link org.elasticsearch.action.index.IndexRequest}
*/
protected static IndexRequest buildIndexRequest(String index, String id, Object object) {
return new IndexRequest(index).id(id).source(BeanUtils.toMap(object), XContentType.JSON);
}

/**
* exec updateRequest
*
* @author fxbin
* @param index elasticsearch index name
* @param id Document id
* @param object request object
*/
protected void updateRequest(String index, String id, Object object) {
try {
UpdateRequest updateRequest = new UpdateRequest(index, id).doc(BeanUtils.toMap(object), XContentType.JSON);
client.update(updateRequest, COMMON_OPTIONS);
} catch (IOException e) {
throw new ElasticsearchException("更新索引 {" + index + "} 数据 {" + object + "} 失败");
}
}

/**
* exec deleteRequest
*
* @author fxbin
* @param index elasticsearch index name
* @param id Document id
*/
protected void deleteRequest(String index, String id) {
try {
DeleteRequest deleteRequest = new DeleteRequest(index, id);
client.delete(deleteRequest, COMMON_OPTIONS);
} catch (IOException e) {
throw new ElasticsearchException("删除索引 {" + index + "} 数据id {" + id + "} 失败");
}
}

/**
* search all
* @param index elasticsearch index name
* @return {@link SearchResponse}
*/
protected SearchResponse search(String index) {
SearchRequest searchRequest = new SearchRequest(index);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = null;
try {
searchResponse = client.search(searchRequest, COMMON_OPTIONS);
} catch (IOException e) {
e.printStackTrace();
}
return searchResponse;
}
}

+ 68
- 0
spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/service/PersonService.java View File

@@ -0,0 +1,68 @@
package com.xkcoding.elasticsearch.service;

import com.xkcoding.elasticsearch.model.Person;
import org.springframework.lang.Nullable;

import java.util.List;

/**
* PersonService
*
* @author fxbin
* @version v1.0
* @since 2019/9/15 23:07
*/
public interface PersonService {

/**
* create Index
*
* @author fxbin
* @param index elasticsearch index name
*/
void createIndex(String index);

/**
* delete Index
*
* @author fxbin
* @param index elasticsearch index name
*/
void deleteIndex(String index);

/**
* insert document source
*
* @author fxbin
* @param index elasticsearch index name
* @param list data source
*/
void insert(String index, List<Person> list);

/**
* update document source
*
* @author fxbin
* @param index elasticsearch index name
* @param list data source
*/
void update(String index, List<Person> list);

/**
* delete document source
*
* @author fxbin
* @param person delete data source and allow null object
*/
void delete(String index, @Nullable Person person);

/**
* search all doc records
*
* @author fxbin
* @param index elasticsearch index name
* @return person list
*/
List<Person> searchList(String index);

}

+ 91
- 0
spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/service/impl/PersonServiceImpl.java View File

@@ -0,0 +1,91 @@
package com.xkcoding.elasticsearch.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.xkcoding.elasticsearch.model.Person;
import com.xkcoding.elasticsearch.service.BaseElasticsearchService;
import com.xkcoding.elasticsearch.service.PersonService;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.SearchHit;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
* PersonServiceImpl
*
* @author fxbin
* @version v1.0
* @since 2019/9/15 23:08
*/
@Service
public class PersonServiceImpl extends BaseElasticsearchService implements PersonService {


@Override
public void createIndex(String index) {
createIndexRequest(index);
}

@Override
public void deleteIndex(String index) {
deleteIndexRequest(index);
}

@Override
public void insert(String index, List<Person> list) {

try {
list.forEach(person -> {
IndexRequest request = buildIndexRequest(index, String.valueOf(person.getId()), person);
try {
client.index(request, COMMON_OPTIONS);
} catch (IOException e) {
e.printStackTrace();
}
});
} finally {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

@Override
public void update(String index, List<Person> list) {
list.forEach(person -> {
updateRequest(index, String.valueOf(person.getId()), person);
});
}

@Override
public void delete(String index, Person person) {
if (ObjectUtils.isEmpty(person)) {
// 如果person 对象为空,则删除全量
searchList(index).forEach(p -> {
deleteRequest(index, String.valueOf(p.getId()));
});
}
deleteRequest(index, String.valueOf(person.getId()));
}

@Override
public List<Person> searchList(String index) {
SearchResponse searchResponse = search(index);
SearchHit[] hits = searchResponse.getHits().getHits();
List<Person> personList = new ArrayList<>();
Arrays.stream(hits).forEach(hit -> {
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
Person person = BeanUtil.mapToBean(sourceAsMap, Person.class, true);
personList.add(person);
});
return personList;
}
}

spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xlcoding/elasticsearch/util/BeanUtils.java → spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/util/BeanUtils.java View File

@@ -1,12 +1,10 @@
package com.xlcoding.elasticsearch.util;
package com.xkcoding.elasticsearch.util;

import com.xlcoding.elasticsearch.model.Person;
import com.xkcoding.elasticsearch.model.Person;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

@@ -50,15 +48,34 @@ public class BeanUtils {
return map;
}

/**
* Java Bean to Map
*
* @author fxbin
* @param object Object
* @return Map
*/
public static Map<String,Object> toMap(Object object){
Map<String, Object> map = MapUtils.newHashMap();
try {
// 获取javaBean的BeanInfo对象
BeanInfo beanInfo = Introspector.getBeanInfo(object.getClass(),Object.class);

public static void main(String[] args) {

Person person = new Person();

Map<String, Object> stringObjectMap = toFieldNameAndFieldTypeMap(person);

System.out.println(stringObjectMap);

// 获取属性描述器
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
// 获取属性名
String key = propertyDescriptor.getName();
// 获取该属性的值
Method readMethod = propertyDescriptor.getReadMethod();
// 通过反射来调用javaBean定义的getName()方法
Object value = readMethod.invoke(object);
map.put(key, value);
}
} catch (Exception e) {
e.printStackTrace();
}
return map;
}

}

spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xlcoding/elasticsearch/util/MapUtils.java → spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/util/MapUtils.java View File

@@ -1,4 +1,4 @@
package com.xlcoding.elasticsearch.util;
package com.xkcoding.elasticsearch.util;

import java.util.HashMap;
import java.util.LinkedHashMap;

+ 0
- 88
spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xlcoding/elasticsearch/service/BaseElasticsearchService.java View File

@@ -1,88 +0,0 @@
package com.xlcoding.elasticsearch.service;

import com.xlcoding.elasticsearch.autoconfigure.ElasticsearchProperties;
import com.xlcoding.elasticsearch.exception.ElasticsearchException;
import com.xlcoding.elasticsearch.model.Person;
import com.xlcoding.elasticsearch.util.BeanUtils;
import com.xlcoding.elasticsearch.util.MapUtils;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Map;

/**
* BaseElasticsearchService
*
* @author fxbin
* @version 1.0v
* @since 2019/9/16 15:44
*/
public abstract class BaseElasticsearchService {

@Resource
private ElasticsearchProperties elasticsearchProperties;

/**
* create elasticsearch index
*
* @author fxbin
* @param index elasticsearch index
*/
public void createIndex(String index, Person person) {

try {
CreateIndexRequest request = new CreateIndexRequest(index);
// Settings for this index
request.settings(Settings.builder()
.put("index.number_of_shards", elasticsearchProperties.getIndex().getNumberOfShards())
.put("index.number_of_replicas", elasticsearchProperties.getIndex().getNumberOfReplicas()));
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
{
builder.startObject("properties");
{
builder.startObject("message");
{
Map<String, Object> map =
BeanUtils.toMap(person);

map.keySet().forEach(key -> {

try {
builder.field(key, "text");
} catch (IOException e) {
e.printStackTrace();
}
});

}
builder.endObject();
}
builder.endObject();
}
builder.endObject();
request.mapping(builder);

} catch (IOException e) {
throw new ElasticsearchException("创建Elasticsearch索引 {" + index + "} 失败");
}

}

/**
* build IndexRequest
*
* @author fxbin
* @param index elasticsearch index name
* @return {@link org.elasticsearch.action.index.IndexRequest}
*/
public IndexRequest buildIndexRequest(String index) {
return new IndexRequest(index);
}

}

+ 0
- 11
spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xlcoding/elasticsearch/service/PersonService.java View File

@@ -1,11 +0,0 @@
package com.xlcoding.elasticsearch.service;

/**
* PersonService
*
* @author fxbin
* @version v1.0
* @since 2019/9/15 23:07
*/
public interface PersonService {
}

+ 0
- 14
spring-boot-demo-elasticsearch-rest-high-level-client/src/main/java/com/xlcoding/elasticsearch/service/impl/PersonServiceImpl.java View File

@@ -1,14 +0,0 @@
package com.xlcoding.elasticsearch.service.impl;

import com.xlcoding.elasticsearch.service.BaseElasticsearchService;
import com.xlcoding.elasticsearch.service.PersonService;

/**
* PersonServiceImpl
*
* @author fxbin
* @version v1.0
* @since 2019/9/15 23:08
*/
public class PersonServiceImpl extends BaseElasticsearchService implements PersonService {
}

+ 3
- 0
spring-boot-demo-elasticsearch-rest-high-level-client/src/main/resources/META-INF/spring.factories View File

@@ -0,0 +1,3 @@
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.xkcoding.elasticsearch.autoconfigure.ElasticsearchAutoConfiguration

+ 6
- 0
spring-boot-demo-elasticsearch-rest-high-level-client/src/main/resources/application.yml View File

@@ -3,3 +3,9 @@ demo:
elasticsearch:
cluster-name: elasticsearch
cluster-nodes: 20.20.0.27:9201
index:
number-of-replicas: 0
number-of-shards: 3
account:
username:
password:

+ 0
- 17
spring-boot-demo-elasticsearch-rest-high-level-client/src/test/java/com/xdcoding/elasticsearch/ElasticsearchApplicationTests.java View File

@@ -1,17 +0,0 @@
package com.xdcoding.elasticsearch;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ElasticsearchApplicationTests {

@Test
public void contextLoads() {
}


}

+ 64
- 0
spring-boot-demo-elasticsearch-rest-high-level-client/src/test/java/com/xkcoding/elasticsearch/ElasticsearchApplicationTests.java View File

@@ -0,0 +1,64 @@
package com.xkcoding.elasticsearch;

import com.xkcoding.elasticsearch.contants.ElasticsearchConstant;
import com.xkcoding.elasticsearch.model.Person;
import com.xkcoding.elasticsearch.service.PersonService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ElasticsearchApplicationTests {

@Resource
private PersonService personService;

@Test
public void deleteIndexTest() {
personService.deleteIndex(ElasticsearchConstant.INDEX_NAME);
}

@Test
public void createIndexTest() {
personService.createIndex(ElasticsearchConstant.INDEX_NAME);
}

@Test
public void insertTest() {

List<Person> list = new ArrayList<>();
list.add(Person.builder().age(11).birthday(new Date()).country("CN").id(1L).name("哈哈").remark("test1").build());
list.add(Person.builder().age(22).birthday(new Date()).country("US").id(2L).name("hiahia").remark("test2").build());
list.add(Person.builder().age(33).birthday(new Date()).country("ID").id(3L).name("呵呵").remark("test3").build());

personService.insert(ElasticsearchConstant.INDEX_NAME, list);
}

@Test
public void updateTest() {
Person person = Person.builder().age(33).birthday(new Date()).country("ID_update").id(3L).name("呵呵update").remark("test3_update").build();
List<Person> list = new ArrayList<>();
list.add(person);
personService.update(ElasticsearchConstant.INDEX_NAME, list);
}

@Test
public void deleteTest() {
personService.delete(ElasticsearchConstant.INDEX_NAME, Person.builder().id(1L).build());
}

@Test
public void searchListTest() {
List<Person> personList = personService.searchList(ElasticsearchConstant.INDEX_NAME);
System.out.println(personList);
}


}

Loading…
Cancel
Save