文章目录
1、写在前面
Elasticsearch 1 : https://blog.csdn.net/a__int__/article/details/111593162
Elasticsearch 2 : https://blog.csdn.net/a__int__/article/details/111604720
Elasticsearch 3 : 本文
Elasticsearch 4 : https://blog.csdn.net/a__int__/article/details/111875343
2、ES客户端官方文档
ES客户端官方文档:https://www.elastic.co/guide/en/elasticsearch/client/index.html
如上图,点击高级客户端旁边那个加号,就能看到详细文档
怎么找我们需要的依赖
在Dependencies中能看到org.elasticsearch.client本质是基于如下两个包封装的
3、springboot整合ES
3.1、准备环境
先用idea创建一个空项目,再往里面添加模块demo1
在项目右边,我们可以看看目前使用的springboot 2.4.1引入的es版本:7.9.3
使用默认版本是最佳的,但是现在我们要测试7.10这个版本,所以我们自定义一下版本号
<elasticsearch.version>7.10.1</elasticsearch.version>
关于版本信息,我们除了可以在右边找到,还可以按住ctrl键,然后右击你想要查看的依赖
如下例:
3.2、整合ES
第一步:如上标题,导入依赖
第二步:启动es服务端
启动es
启动kibana
启动head
第三步:在项目里写配置类,注入es客户端
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class EsClientConfig {
@Bean
public RestHighLevelClient restHighLevelClient(){
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("127.0.0.1", 9200, "http")));
return client;
}
}
多个集群还可以new多个HttpHost
第四步:开始使用
3.3、测试:创建一个索引
在一个测试类里面测试
CreateIndexRequest
@SpringBootTest
class Demo1ApplicationTests {
//Qualifier的意思是合格者,通过这个标示,表明了哪个实现类才是我们所需要的
@Autowired
@Qualifier("restHighLevelClient")
private RestHighLevelClient rhc;
@Test
void contextLoads() throws IOException {
// 1、创建索引连接,索引名: test4
CreateIndexRequest test5 = new CreateIndexRequest("test5");
// 2、客户端执行请求, 获得响应
CreateIndexResponse createIndexResponse = rhc.indices().create(test5, RequestOptions.DEFAULT);
// 打印索引名字
System.out.println(createIndexResponse.index());
// 打印返回类型
System.out.println(createIndexResponse);
}
}
打印结果
查看head
3.4、测试:获取一个索引
GetIndexRequest
@SpringBootTest
class Demo1ApplicationTests {
//Qualifier的意思是合格者,通过这个标示,表明了哪个实现类才是我们所需要的
@Autowired
@Qualifier("restHighLevelClient")
private RestHighLevelClient rhc;
@Test
void contextLoads2() throws IOException {
GetIndexRequest test5 = new GetIndexRequest("test5");
boolean exists = rhc.indices().exists(test5, RequestOptions.DEFAULT);
System.out.println(exists);
}
}
3.5、测试:删除一个索引
DeleteIndexRequest
@SpringBootTest
class Demo1ApplicationTests {
//Qualifier的意思是合格者,通过这个标示,表明了哪个实现类才是我们所需要的
@Autowired
@Qualifier("restHighLevelClient")
private RestHighLevelClient rhc;
@Test
void contextLoads3() throws IOException {
DeleteIndexRequest test5 = new DeleteIndexRequest("test5");
AcknowledgedResponse delete = rhc.indices().delete(test5, RequestOptions.DEFAULT);
System.out.println(delete.isAcknowledged());
}
}
4、查看es源码
先找到源码:
从spring的自动注入中,可以查看elasticsearch构建客户端的相关类
es在spring里面也被归为数据库的一种类型,我们在data里面可以看到es的默认配置、相关源码
5、springboot + es 的 CRUD
创建一个实体类User
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
public class User {
private String name;
private int age;
}
这里我们用的时候需要把实体类,转为json字符串,我们引入一下json依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
5.1、添加一条数据
在测试类里写如下代码,运行
@Autowired
@Qualifier("restHighLevelClient")
private RestHighLevelClient rhc;
@Test
void addDocument() throws IOException {
User user1 = new User("猪小明", 33);
// 创建索引
IndexRequest tset6 = new IndexRequest("tset6");
// 设置属性、文档id
tset6.id("1");
// 设置超时为1秒
// tset6.timeout(TimeValue.timeValueSeconds(1));
tset6.timeout("1s");
// 将我们的数据放入请求
tset6.source(JSON.toJSONString(user1), XContentType.JSON);
// 发送到es服务端
IndexResponse index = rhc.index(tset6, RequestOptions.DEFAULT);
// 将响应结果打印出来
System.out.println(index.toString());
System.out.println(index.status());
}
运行结果
5.2、获取一条数据
判断一条数据(文档)是否存在
@Autowired
@Qualifier("restHighLevelClient")
private RestHighLevelClient rhc;
@Test
void getDocument() throws IOException {
GetRequest test6_1 = new GetRequest("tset6", "1");
// 不获取返回的_source的上下文了
test6_1.fetchSourceContext(new FetchSourceContext(false));
test6_1.storedFields("_none_");
boolean exists = rhc.exists(test6_1, RequestOptions.DEFAULT);
System.out.println(exists);
}
获取文档信息
@Autowired
@Qualifier("restHighLevelClient")
private RestHighLevelClient rhc;
@Test
void getDocument1() throws IOException {
GetRequest test6_1 = new GetRequest("tset6", "1");
GetResponse documentFields = rhc.get(test6_1, RequestOptions.DEFAULT);
System.out.println(documentFields.getSourceAsString());
System.out.println(documentFields);
}
5.3、更新一条数据
@Autowired
@Qualifier("restHighLevelClient")
private RestHighLevelClient rhc;
@Test
void updateDocument() throws IOException {
UpdateRequest tset6_1 = new UpdateRequest("tset6", "1");
tset6_1.timeout("1s");
User user = new User("米线", 18);
tset6_1.doc(JSON.toJSONString(user),XContentType.JSON);
UpdateResponse update = rhc.update(tset6_1, RequestOptions.DEFAULT);
System.out.println(update.status());
System.out.println(update);
}
5.4、删除一条数据
@Autowired
@Qualifier("restHighLevelClient")
private RestHighLevelClient rhc;
@Test
void delDocument() throws IOException {
DeleteRequest tset6_1 = new DeleteRequest("tset6", "1");
tset6_1.timeout("1s");
DeleteResponse del = rhc.delete(tset6_1, RequestOptions.DEFAULT);
System.out.println(del.status());
}
5.5、批量执行
@Autowired
@Qualifier("restHighLevelClient")
private RestHighLevelClient rhc;
@Test
void addDocuments() throws IOException {
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.timeout("10s");
ArrayList<User> users = new ArrayList<>();
users.add(new User("闰土",25));
users.add(new User("妹大爷",65));
users.add(new User("球球",18));
users.add(new User("茅台",36));
users.add(new User("蘑菇头",29));
for(int i = 0; i<users.size();i++){
// 批量操作:增删改 都可以
bulkRequest.add(new IndexRequest("tset6")
.id(""+(i+1))
.source(JSON.toJSONString(users.get(i)),XContentType.JSON));
}
BulkResponse bulk = rhc.bulk(bulkRequest, RequestOptions.DEFAULT);
//输出是否执行失败
System.out.println(bulk.hasFailures());
}
返回的false表示没有失败
批量增删改
id填或不填都行
5.6、搜索/查询
@Autowired
@Qualifier("restHighLevelClient")
private RestHighLevelClient rhc;
@Test
void search() throws IOException {
SearchRequest tset6 = new SearchRequest("tset6");
// 搜索条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// QueryBuilders用来构建查询条件
// termQuery精确查询 matchQuery条件查询 matchAllQuery()匹配所有
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "妹");
searchSourceBuilder.query(termQueryBuilder);
// 分页,分页也可以不写,默认有实现
//searchSourceBuilder.from();
//searchSourceBuilder.size();
// 设置超时时间
// searchSourceBuilder.timeout(TimeValue.timeValueSeconds(60));
searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
// 将搜索条件加入 请求
tset6.source(searchSourceBuilder);
// 发起请求,并获取返回结果
SearchResponse searchResponse = rhc.search(tset6, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(searchResponse.getHits()));
// 循环打印
for(SearchHit documentFields:searchResponse.getHits().getHits()){
System.out.println(documentFields.getSourceAsMap());
}
}
跳坑日记:
如上代码,我使用的termQuery精确查询,如果你的字段是“text”类型,是会被分词器分词的,
比如这里我搜索”妹大爷“,就搜不出来,因为分词器拆分后“妹大爷”不是一个词,被拆成了“妹”、“大爷”
SearchSourceBuilder : 用来构建搜索条件
HighlightBuilder :构建高亮
xxxQueryBuilder 对应的就是es里的条件指令
比如 TermQueryBuilder