导入依赖
导入与你es版本对应的依赖
<dependencies>
<!-- 1. elasticsearch-->
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.5.1</version>
</dependency>
<!-- 2. elasticsearch的高级API-->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.5.1</version>
</dependency>
<!-- 3. junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- 4. lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.22</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
创建es连接对象
public class EsClient {
/**
* 这个方法是用来连接ElasticSearch的方法的对象client
*/
public static RestHighLevelClient getClient() {
// 初始化Elasticsearch服务器的地址和端口
HttpHost httpHost = new HttpHost("121.40.249.149", 9200);
// 使用HttpHost创建RestClientBuilder
RestClientBuilder builder = RestClient.builder(httpHost);
// 使用RestClientBuilder创建RestHighLevelClient实例
RestHighLevelClient client = new RestHighLevelClient(builder);
return client;
}
}
文档操作
初始化EsClient的实例
在测试方法执行之前初始化一个EsClient的实例,并将其赋值给client变量。使用@Before注解标识该方法,确保它在所有@Test注解的方法执行之前运行。通过调用EsClient类的getClient()方法获取EsClient实例,为后续的测试提供必要的客户端对象。
public class EsDocTest {
RestHighLevelClient client = null;
@Before // 这个注解的意思是在@Test注解执行之前执行
public void clientTest() {
client = EsClient.getClient();
}
}
添加文档
// 添加文档操作
private String index = "book-index";
@Test
public void addDoc() throws IOException {
String id = UUID.randomUUID().toString().replace("-", "");
Book book = new Book(id, "莽荒纪", "天蚕土豆", new Date(), "纪宁站了起来", 66.8);
// 创建一个索引请求对象。
IndexRequest request = new IndexRequest().index(index);
request.id(book.getBookId());
// 将对象转换为json
String jsonBook = new ObjectMapper().writeValueAsString(book);
// 添加到请求对象中
request.source(jsonBook, XContentType.JSON);
// 将文档添加到 Elasticsearch 索引中,并获取响应对象 IndexResponse
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
// 获取成功索引的分片数
int successful = response.getShardInfo().getSuccessful();
System.out.println(successful);
}
执行后可以进入kibana查看添加的文档,可以看到我们刚添加的书本信息数据
修改文档
// 修改文档操作
@Test
public void updateDoc() throws IOException {
// 创建更新请求,并指定要更新的索引和文档ID
UpdateRequest request = new UpdateRequest().index(index).id("29e380757e094d08a92395cf390918eb");
// 准备要更新的文档内容
Map<String, Object> source = new HashMap<>();
source.put("bookPrice", 99.9);
// 将文档内容设置到更新请求中
request.doc(source);
// 执行更新请求,并获取响应
UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
System.out.println(response);
}
执行后可以进入kibana查看修改的文档,可以看到我们刚修改的书本信息数据
可以看到文档的内容已经被修改成功
获取文档信息
// 获取文档操作
@Test
public void gteDoc() throws IOException {
// 创建一个GetRequest,指定索引和文档ID
GetRequest request = new GetRequest().index(index).id("29e380757e094d08a92395cf390918eb");
// 使用客户端执行GET请求,并接收响应
GetResponse response = client.get(request, RequestOptions.DEFAULT);
// 从响应中获取文档内容,并将其作为字符串返回
String json = response.getSourceAsString();
System.out.println(json);
}
删除文档
// 删除文档操作
@Test
public void delDoc() throws IOException {
// 创建一个删除请求,指定要删除的文档的索引和ID
DeleteRequest request = new DeleteRequest().index(index).id("29e380757e094d08a92395cf390918eb");
// 执行删除请求,并获取删除操作的响应
DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
System.out.println(response);
}
执行后可看到数据已经被删除
批量添加
// 批量添加文档
@Test
public void bulkAddDoc() throws IOException {
List<Book> list = new ArrayList<>();
for (int i = 1; i < 5; i++) {
String id = UUID.randomUUID().toString().replace("-", "");
Book book = new Book(id, "斗罗大陆第" + i + "部", "唐家三少", new Date(), "武魂开....", 166.8);
list.add(book);
}
// 批量添加
BulkRequest bulkRequest = new BulkRequest();
for (Book book : list) {
// 为每本书创建一个索引请求
IndexRequest request = new IndexRequest().index(index);
request.id(book.getBookId()); // 设置书籍的唯一标识符
String jsonBook = new ObjectMapper().writeValueAsString(book); // 将书籍对象转换为JSON格式
// 将JSON数据设置为索引请求的源数据
request.source(jsonBook, XContentType.JSON);
// 单独执行每个索引请求
client.index(request, RequestOptions.DEFAULT);
// 将索引请求添加到批量请求中
bulkRequest.add(request);
}
// 执行批量索引请求
BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println(bulk.status());
}
批量删除
// 批量删除文档
@Test
public void bulkDelDoc() throws IOException {
// 创建批量请求对象
BulkRequest bulkRequest = new BulkRequest();
for (int i = 0; i < 4; i++) {
// 为每个文档创建删除请求,并将其添加到批量请求中
DeleteRequest request = new DeleteRequest().index(index).id("" + i);
client.delete(request, RequestOptions.DEFAULT); // 执行单个删除操作,但不在此处处理响应
bulkRequest.add(request);
}
// 执行批量删除请求,并获取响应
BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println(bulk.status());
}
小结
文档的操作都是在RestHighLevelClient中进行操作
- 添加操作:client.index()
- 删除操作:client.delete()
- 修改操作:client.update()
- 查看操作:client.get()
- 批量操作:client.bulk()
查询操作
为了方便查询操作,我创建了一个Product索引并上传了一些数据
根据商品名称字段查询单个参数
@Test
public void termSearch() throws IOException {
// 创建搜索请求并指定索引
SearchRequest request = new SearchRequest().indices(index);
// 构建搜索源配置,设置查询条件为"productName"字段
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.termQuery("productName", "面"));
// 将构建好的搜索源配置设置到搜索请求中
request.source(builder);
// 执行搜索请求,并获取响应
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 从响应中获取匹配的搜索结果总数
System.out.println(response.getHits().getTotalHits().value);// 获取总记录数
// 获取所有的搜索结果 hit
SearchHit[] searchHits = response.getHits().getHits();
// 遍历并打印每条搜索结果的内容
for (SearchHit searchHit : searchHits) {
System.out.println(searchHit.getSourceAsString());
}
}
根据商品名称字段查询多个参数
@Test
public void termsSearch() throws IOException {
SearchRequest request = new SearchRequest().indices(index);
SearchSourceBuilder builder = new SearchSourceBuilder();
// 构建搜索源配置,设置查询条件为"productName"字段为‘条’和‘面’的
builder.query(QueryBuilders.termsQuery("productName", "条", "面"));
request.source(builder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
System.out.println(hits.getTotalHits().value);
SearchHit[] searchHits = hits.getHits();
for (SearchHit searchHit : searchHits) {
System.out.println(searchHit.getSourceAsString());
}
}
全匹配搜索(查询全部)
@Test
public void matchAllSearch() throws IOException {
// 创建搜索请求,并指定索引
SearchRequest request = new SearchRequest().indices(index);
// 构建搜索源配置
SearchSourceBuilder builder = new SearchSourceBuilder();
// 设置查询条件为全匹配查询,一次返回100条结果
builder.query(QueryBuilders.matchAllQuery());
builder.size(100);
request.source(builder);
// 执行搜索请求,并获取响应
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 从响应中获取搜索结果摘要
SearchHits hits = response.getHits();
// 打印搜索结果总数
System.out.println(hits.getTotalHits().value);
// 获取并遍历所有搜索结果,打印每条结果的源数据
SearchHit[] searchHits = hits.getHits();
for (SearchHit searchHit : searchHits) {
System.out.println(searchHit.getSourceAsString());
}
}
条件搜索
@Test
public void matchBrSearch() throws IOException {
// 创建一个SearchRequest对象,并设置索引
SearchRequest request = new SearchRequest().indices(index);
// 创建一个SearchSourceBuilder对象
SearchSourceBuilder builder = new SearchSourceBuilder();
// 设置查询条件为匹配查询,并指定字段为"productName",查询内容为"咪 条",运算符为AND
builder.query(QueryBuilders.matchQuery("productName", "咪 条").operator(Operator.AND));
// 设置返回结果的数量为100
builder.size(100);
// 将SearchSourceBuilder对象设置为SearchRequest对象的source
request.source(builder);
// 发送搜索请求并获取响应
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 获取搜索结果的总数
SearchHits hits = response.getHits();
System.out.println(hits.getTotalHits().value);
// 遍历搜索结果
SearchHit[] searchHits = hits.getHits();
for (SearchHit searchHit : searchHits) {
// 打印每个搜索结果的源文件字符串
System.out.println(searchHit.getSourceAsString());
}
}
多字段匹配查询
@Test
public void multiMatchSearch() throws IOException {
// 创建搜索请求并指定索引
SearchRequest request = new SearchRequest().indices(index);
// 构建搜索源配置
SearchSourceBuilder builder = new SearchSourceBuilder();
// 设置查询条件为多字段匹配查询,查询关键词为"条",匹配字段为"productName"和"content"
builder.query(QueryBuilders.multiMatchQuery("条", "productName", "content"));
// 设置返回结果的最大数量为100
builder.size(100);
// 将搜索源配置应用到搜索请求中
request.source(builder);
// 执行搜索请求,并获取响应
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 从响应中获取匹配的文档总数
SearchHits hits = response.getHits();
System.out.println(hits.getTotalHits().value); // 打印匹配文档的总数
// 获取并处理每条匹配的文档
SearchHit[] searchHits = hits.getHits();
for (SearchHit searchHit : searchHits) {
// 打印每条匹配文档的源数据
System.out.println(searchHit.getSourceAsString());
}
}
根据id批量查询
@Test
public void idsSearch() throws IOException {
// 创建搜索请求并指定索引
SearchRequest request = new SearchRequest().indices(index);
// 构建搜索源配置
SearchSourceBuilder builder = new SearchSourceBuilder();
// 设置查询条件为指定的IDs
builder.query(QueryBuilders.idsQuery().addIds("1", "2"));
// 设置返回结果的最大数量
builder.size(100);
// 将搜索源配置应用到搜索请求中
request.source(builder);
// 执行搜索请求并获取响应
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 从响应中获取搜索到的文档信息
SearchHits hits = response.getHits();
// 打印搜索结果的总数量
System.out.println(hits.getTotalHits().value);
SearchHit[] searchHits = hits.getHits();
for (SearchHit searchHit : searchHits) {
System.out.println(searchHit.getSourceAsString());
}
}
前缀查询
@Test
public void prefixSearch() throws IOException {
// 创建搜索请求并指定索引
SearchRequest request = new SearchRequest().indices(index);
// 构建搜索源
SearchSourceBuilder builder = new SearchSourceBuilder();
// 设置查询条件为前缀匹配查询,查询字段为productName,前缀为"奥"
builder.query(QueryBuilders.prefixQuery("productName", "奥"));
// 设置返回结果的最大数量
builder.size(100);
// 将构建好的搜索条件设置到搜索请求中
request.source(builder);
// 执行搜索请求并获取响应
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 从响应中获取搜索结果集
SearchHits hits = response.getHits();
System.out.println(hits.getTotalHits().value);
SearchHit[] searchHits = hits.getHits();
for (SearchHit searchHit : searchHits) {
System.out.println(searchHit.getSourceAsString());
}
}
范围查询
@Test
public void rangeSearch() throws IOException {
SearchRequest request = new SearchRequest().indices(index);
SearchSourceBuilder builder = new SearchSourceBuilder();
// 设置查询条件为 productId 大于 5
builder.query(QueryBuilders.rangeQuery("productId").gt(5));
builder.size(100);
request.source(builder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
System.out.println(hits.getTotalHits().value);
SearchHit[] searchHits = hits.getHits();
for (SearchHit searchHit : searchHits) {
// 打印每条文档数据
System.out.println(searchHit.getSourceAsString());
}
}
高亮查询
@Test
public void highLightSearch() throws IOException {
SearchRequest request = new SearchRequest(index);
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.matchQuery("productName", "奥"));
// 创建一个HighlightBuilder对象,用于构建高亮设置
HighlightBuilder highlightBuilder = new HighlightBuilder();
// 设置需要高亮的字段为"productName"
highlightBuilder.field("productName");
// 添加高亮前后缀标签,用于指定高亮内容的显示格式
highlightBuilder.postTags("<font color='red'>").postTags("</font>");
// 在搜索请求的源代码部分中添加高亮设置
builder.highlighter(highlightBuilder);
request.source(builder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
SearchHit[] hits = response.getHits().getHits();
for (SearchHit hit : hits) {
// 获取源数据作为map
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
// 获取高亮字段
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
// 获取名为"productName"的高亮字段
HighlightField highlightField = highlightFields.get("productName");
// 获取第一个高亮字段的文本
Text text = highlightField.fragments()[0];
// 将高亮字段的文本添加到源数据的map中
sourceAsMap.put("productName", text.toString());
System.out.println(sourceAsMap);
}
}
需要安装配置es请点击:【超详细】Docker部署Elasticsearch、Kibana及其分词器的使用