ES7.X版本较之前改动比较大,相应的springboot对它的支持改动也特别明显。
在spring-date-elasticsearch官网:https://docs.spring.io/spring-data/elasticsearch/docs/4.0.1.RELEASE/reference/html/#new-features,可以查看到版本匹配信息,如下:
(一定要学会去官网查看文档)
如果版本不匹配,比如我本地安装elasticsearch7.x版本,springboot是2.1.X版本,在保证所有配置都正确的前提下。
客户端异常信息如下:
org.elasticsearch.client.transport.NoNodeAvailableException: None of the configured nodes are available: [{#transport#-1}{XeevRzArRHmG0u17ftnPOA}{localhost}{127.0.0.1:9300}]
-- 所有配置的节点不可用
es异常信息如下(es日志在,es安装路径/logs路径里面):
java.lang.IllegalStateException: Received message from unsupported version: [6.4.2] minimal compatible version is: [6.8.0]
-- 当前访问es的客户端版本位6.4.2,最低要求访问的版本的6.8.0
这个访问es的客户端版本就是spring-data-elasticsearch中,访问es的客户端版本,可以在项目依赖库中查看:
坐标:
org.elasticsearch.client
transport
所以,需要将springboot版本升级。该文档的版本信息:springboot是2.3.3.RELEASE,es版本是7.10.1。
springboot-data-elasticsearch较之前最大的区别有两点:
1.配置文件
## 旧版本以spring.data.elasticsearch.开头;访问地址配置不用声明访问协议,监听es的tcp端口
spring.data.elasticsearch.cluster-nodes=localhost:9300
## 新版本以spring.elasticsearch.rest.开头;访问地址配置需要声明访问协议,直接监听es访问端口
spring.elasticsearch.rest.uris=http://localhost:9200
2.核心访问对象
旧版的核心访问对象是ElasticsearchTemplate;新版的核心访问对象是ElasticsearchRestTemplate;
另外,在新版中,不会对ElasticsearchTemplate做自动装配,如果还需要使用它,需要手动装配,当然,应该禁止这么做。如下:
@Bean(name = "elasticsearchTemplate")
public ElasticsearchTemplate initElasticsearchTemplate(Client client) {
ElasticsearchTemplate elasticsearchTemplate = new ElasticsearchTemplate(client);
return elasticsearchTemplate;
}
org.springframework.boot
spring-boot-starter-data-elasticsearch
# es访问地址,多个用英文逗号隔开
spring.elasticsearch.rest.uris=http://localhost:9200
# 连接超时时间,单位是s
# spring.elasticsearch.rest.connection-timeout=10
# 读超时时间,单位是s
spring.elasticsearch.rest.read-timeout=5
# 访问用户名
# spring.elasticsearch.rest.username=username
# 访问密码
# spring.elasticsearch.rest.password=password
核心操作对象ElasticsearchRestTemplate是自动装配的,所以接下来就可以直接访问了。
和访问数据库一样,统统以对象的形式访问
import java.math.BigDecimal;
import java.time.LocalDateTime;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
/**
* 更多注解详细说明参考官网:https://docs.spring.io/spring-data/elasticsearch/docs/4.0.1.RELEASE/reference/html/#elasticsearch.mapping.meta-model
* 一定要习惯从官网获取信息
* */
// @Document指定当前类是索引对象。indexName:索引名称;shards:创建索引时的分片数;replicas:创建索引时的备份数
@Document(indexName = "book_", shards = 5, replicas = 1)
public class BookIndexMapping {
// @Id标记数据主键
@Id
private String id;
// @Field标记字段。name:映射es中的字段;type:字段类型
@Field(name = "title_", type = FieldType.Keyword)
private String title;
@Field(name = "content_", type = FieldType.Text)
private String content;
@Field(name = "price_", type = FieldType.Double)
private BigDecimal price;
// 如果java类型使用java.util.Date,反序列化会失败
@Field(name = "publish_date_", type = FieldType.Date, format = DateFormat.date_hour_minute_second)
private LocalDateTime publishDate;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public LocalDateTime getPublishDate() {
return publishDate;
}
public void setPublishDate(LocalDateTime publishDate) {
this.publishDate = publishDate;
}
public BookIndexMapping() {
super();
}
}
@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;
@Test
public void createIndexTest() {
boolean exists = elasticsearchRestTemplate.indexOps(BookIndexMapping.class).exists();
// 如果索引已存在,删除索引
if(exists) {
// 删除索引
elasticsearchRestTemplate.indexOps(BookIndexMapping.class).delete();
}
// 创建索引
elasticsearchRestTemplate.indexOps(BookIndexMapping.class).create();
// 创建映射
Document mappings = elasticsearchRestTemplate.indexOps(BookIndexMapping.class).createMapping();
elasticsearchRestTemplate.indexOps(BookIndexMapping.class).putMapping(mappings);
System.out.println("---执行成功---");
}
// 新增文档数据
@Test
public void save() {
BookIndexMapping entity = new BookIndexMapping();
entity.setTitle("高一英语(上册 人教版)");
entity.setContent("how are you! how old are you!");
entity.setPrice(new BigDecimal(23.9));
entity.setPublishDate(LocalDateTime.now());
elasticsearchRestTemplate.save(entity);
System.out.println("---插入成功---");
}
// 新增文档数据:指定id
@Test
public void save2() {
BookIndexMapping entity = new BookIndexMapping();
entity.setId(UUID.randomUUID().toString());
entity.setTitle("大一英语(上册 人教版)");
entity.setContent("are you ok?");
entity.setPrice(new BigDecimal(13.92));
entity.setPublishDate(LocalDateTime.now());
elasticsearchRestTemplate.save(entity);
System.out.println("---插入成功---");
}
// 删除索引
@Test
public void deleteIndex() {
boolean deleted = elasticsearchRestTemplate.indexOps(BookIndexMapping.class).delete();
System.out.println("是否删除成功 : " + deleted);
}
// 删除文档数据
@Test
public void deleteDoc() {
// 返回被删除的数据id
String result = elasticsearchRestTemplate.delete("b87ea2a1-d812-433f-a70a-9a83ed22b150", BookIndexMapping.class);
System.out.println(result);
}
以下查询不包含所有查询操作。
// 根据id获取文档数据
@Test
public void getByIdTest() {
BookIndexMapping entity = elasticsearchRestTemplate.get("_IpxsnYBmfMmPE5SYcob", BookIndexMapping.class);
System.out.println(JSONObject.toJSONString(entity));
}
// query查询
@Test
public void queryTest() {
// match查询,匹配content_字段
NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchQuery("content_", "are")).build();
SearchHits list = elasticsearchRestTemplate.search(query, BookIndexMapping.class);
System.out.println(JSONObject.toJSONString(list));
}
// filter查询
@Test
public void filterTest() {
// match查询,匹配content_字段
NativeSearchQuery query = new NativeSearchQueryBuilder().withFilter(QueryBuilders.matchQuery("content_", "are")).build();
SearchHits list = elasticsearchRestTemplate.search(query, BookIndexMapping.class);
System.out.println(JSONObject.toJSONString(list));
}