在SpringBoot中使用ElasticSearch(7.x版本)

前言

ES7.X版本较之前改动比较大,相应的springboot对它的支持改动也特别明显。

在spring-date-elasticsearch官网:https://docs.spring.io/spring-data/elasticsearch/docs/4.0.1.RELEASE/reference/html/#new-features,可以查看到版本匹配信息,如下:

(一定要学会去官网查看文档)

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MTM4MTg2Mw==,size_16,color_FFFFFF,t_70

如果版本不匹配,比如我本地安装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的客户端版本,可以在项目依赖库中查看:

坐标:

<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>

20201230100433153.png

 

所以,需要将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;
}

 

引入jar包

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

配置

# 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<BookIndexMapping> 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<BookIndexMapping> list = elasticsearchRestTemplate.search(query, BookIndexMapping.class);
		System.out.println(JSONObject.toJSONString(list));
	}

 

 

 

 

 

 

 

 

  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值