示例代码:
- GitHub:GitHub - Max-Qiu/demo-SpringBoot2: SpringBoot2.x整合各种第三方组件的示例代码
- Gitee:demo-SpringBoot2: SpringBoot2.x整合各种第三方组件的示例代码
PS:本文只是一篇极其简单的整合教程,不涉及复杂搜索示例,建议认真阅读官方文档
版本对应关系
Spring Boot | Spring Data Elasticsearch | Elasticsearch |
---|---|---|
2.1.18.RELEASE | 3.1.21.RELEASE | 6.4.3 |
2.2.11.RELEASE | 3.2.11.RELEASE | 6.8.13 |
2.3.6.RELEASE | 4.0.5.RELEASE | 7.6.2 |
2.4.12 | 4.1.1 | 7.9.3 |
2.5.7 | 4.2.7 | 7.12.1 |
2.6.1 | 4.3.0 | 7.15.2 |
- 本文以
Spring Boot 2.6.1
为例 - 本文不介绍
Reactive
模式的相关代码
准备
pom.xml
<!--核心依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<!--配置客户端需要的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--若不需要Tomcat,则只需要依赖spring-web-->
<!--<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>-->
客户端配置
官方文档: 5. Elasticsearch Clients
官网未介绍yml方式配置,但是也是可以使用的,不做复杂的设置的话,
yml
即可
application.yml
# yml配置elasticsearch客户端地址(可配置项有限)
spring:
elasticsearch:
uris: http://127.0.0.1:9200 # elasticsearch 连接地址
#username: elastic # 用户名
#password: 123456 # 密码
connection-timeout: 10s # 连接超时时间(默认1s)
socket-timeout: 30s # 数据读取超时时间(默认30s)
Bean
import java.time.Duration;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.RestClients;
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
/**
* Java高级别REST客户端是Elasticsearch的默认客户端
*
* Bean方式配置
*
* @author Max_Qiu
*/
@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {
@Bean
@Override
public RestHighLevelClient elasticsearchClient() {
// 使用构建器来提供集群地址,设置默认值HttpHeaders或启用SSL。
ClientConfiguration clientConfiguration = ClientConfiguration.builder()
// 设置连接地址
.connectedTo("127.0.0.1:9200")
// 可以设置多个地址
// .connectedTo("127.0.0.1:9200", "127.0.0.1:9201")
// 是否启用ssl
// .usingSsl()
// 设置连接超时时间
.withConnectTimeout(Duration.ofSeconds(10))
// 设置
.withSocketTimeout(Duration.ofSeconds(30))
// 设置用户名密码
// .withBasicAuth("elastic", "123456")
// 创建连接信息
.build();
// 创建RestHighLevelClient。
return RestClients.create(clientConfiguration).rest();
}
}
日志输出
方便查询发送的
http请求
详细内容
在 application.yml
内添加如下内容
logging:
file:
name: ./log/log.log
level:
root: info
org.springframework.data.elasticsearch.client.WIRE: trace
实体映射
官方文档: 6. Elasticsearch Object Mapping
示例如下:
@Document(indexName = "user", shards = 3, replicas = 0)
public class User {
@Id
private Integer id;
@Field(type = FieldType.Keyword)
private String name;
@Field(type = FieldType.Integer)
private Integer age;
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String address;
@Field(type = FieldType.Date, format = DateFormat.custom, pattern = "uuuu-MM-dd'T'HH:mm:ss.SSSX")
private LocalDateTime createTime;
}
注解说明:
在MappingElasticsearchConverter使用元数据驱动的对象的映射文件。元数据取自可以注释的实体属性。
提供以下注释:
@Document:在类级别应用,以指示该类是映射到数据库的候选对象。最重要的属性是:
indexName:用于存储此实体的索引的名称。它可以包含SpEL模板表达式,例如 "log-#{T(java.time.LocalDate).now().toString()}"
createIndex:标记是否在存储库引导中创建索引。默认值为true。请参见使用相应的映射自动创建索引
versionType:版本管理的配置。默认值为EXTERNAL。
@Id:在字段级别应用,以标记用于标识目的的字段。
@Transient:默认情况下,存储或检索文档时,所有字段都映射到文档,此注释不包括该字段。
@PersistenceConstructor:标记从数据库实例化对象时要使用的给定构造函数,甚至是受保护的程序包。构造函数参数按名称映射到检索到的Document中的键值。
@Field:在字段级别应用并定义字段的属性,大多数属性映射到各自的Elasticsearch映射定义(以下列表不完整,请查看注释Javadoc以获得完整参考):
name:字段名称,它将在Elasticsearch文档中表示,如果未设置,则使用Java字段名称。
type:字段类型,可以是Text, Keyword, Long, Integer, Short, Byte, Double, Float, Half_Float, Scaled_Float, Date, Date_Nanos, Boolean, Binary, Integer_Range, Float_Range, Long_Range, Double_Range, Date_Range, Ip_Range, Object, Nested, Ip, TokenCount, Percolator, Flattened, Search_As_You_Type。请参阅Elasticsearch映射类型
format和日期类型的pattern定义。必须为日期类型定义format
store:标记是否将原始字段值存储在Elasticsearch中,默认值为false。
analyzer,searchAnalyzer,normalizer用于指定自定义分析和正规化。
@GeoPoint:将字段标记为geo_point数据类型。如果字段是GeoPoint类的实例,则可以省略。
@ValueConverter:定义用于转换给定属性的类。与注册的 Spring 不同,Converter这仅转换带注释的属性,而不是给定类型的每个属性。
@Setting:注释定义不同的索引设置。以下参数可用:
useServerConfiguration 不发送任何设置参数,因此 Elasticsearch 服务器配置确定它们。
settingPath 是指定义必须在类路径中解析的设置的 JSON 文件
shards要使用的分片数,默认为1
replicas副本数,默认为1
refreshIntervall, 默认为“1s”
indexStoreType, 默认为"fs"
CRUD
Elasticsearch Operations
官方文档: 7. Elasticsearch Operations
主要有以下4个类
IndexOperations
在索引级别定义操作,例如创建或删除索引。DocumentOperations
定义根据其ID存储,更新和检索实体的操作。SearchOperations
定义使用查询搜索多个实体的动作ElasticsearchOperations
结合DocumentOperations
和SearchOperations
的接口ElasticsearchRestTemplate
是ElasticsearchOperations
的实现类
日常使用时,使用
ElasticsearchRestTemplate
即可,代码如下
@Autowired
private ElasticsearchRestTemplate template;
IndexOperations
需要从ElasticsearchRestTemplate
中获取,例如:template.indexOps(User.class)
操作索引
// 获取IndexOperations对象
IndexOperations indexOperations = template.indexOps(User.class);
// 查
boolean exists = indexOperations.exists();
// 删
boolean delete = indexOperations.delete();
// 增
boolean flag = indexOperations.create();
// 设置Mapping
boolean mapping = indexOperations.putMapping();
完整示例: com.maxqiu.demo.IndexApi
操作文档
// 增/改
User user = new User();
user.set...
template.save(user);
// 批量 增/改
List<User> userList = new ArrayList<>();
userList.add(new User);
...
Iterable<User> users = template.save(userList);
// 查
User user = template.get("1", User.class);
// 删
String delete = template.delete("1", User.class);
完整示例: com.maxqiu.demo.DocumentApi
搜索
// 新建一个QueryBuilder(该对象是Elasticsearch的,QueryBuilders可以构建各种各样的条件查询)
QueryBuilder queryBuilder = QueryBuilders.matchAllQuery();
// 新建一个Query(该对象是Spring Data Elasticsearch的)
Query query = new NativeSearchQueryBuilder().withQuery(queryBuilder).build();
// 使用template执行查询,SearchHits<User>就是执行后的返回结果的映射实体
SearchHits<User> search = template.search(query, User.class);
完整示例: com.maxqiu.demo.SearchApi
ElasticsearchRepository
官方文档: 8. Elasticsearch Repositories
一个类似于 Spring Data JPA
的文档操作方法
// 新建一个User的数据持久层
@Repository
public interface UserRepository extends ElasticsearchRepository<User, Integer> {}
建立此持久层后,如果
User
实体@Document
注解内的createIndex
为true
时(默认为true
),则服务启动时会先检查索引是否存在,若不存在则会自动创建索引
默认的CRUD示例
// 增/改
User user = new User(1, "张三", 18, "上海市闵行区", LocalDateTime.now());
User save = repository.save(user);
// 查
Optional<User> optionalUser = repository.findById(1);
// 删
repository.deleteById(1);
完整示例: com.maxqiu.demo.repository.UserRepositoryTest
自定义的条件查询
在 UserRepository
内新建抽象方法
List<User> findUsersByNameAndAddress(String name, String address);
调用
@Test
void test() {
List<User> userList = repository.findUsersByNameAndAddress("张三", "上海");
for (User user : userList) {
System.out.println(user);
}
}