该篇文章参考下面博主文章
Java中ElasticSearch的各种查询(普通,模糊,前缀,高亮,聚合,范围)
【es】java使用es中三种查询用法from size、search after、scroll
@Autowired
private RestHighLevelClient restHighLevelClient;//es高级客户端
/**
* 创建索引
*
* @throws IOException
*/
@Test
void createIdx() throws IOException {
String idx = "user_idx";//索引名称
GetIndexRequest request = new GetIndexRequest(idx);
boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
//判断索引是否存在
if (!exists) {
System.out.println(idx + "索引不存在");
// 创建索引的请求
CreateIndexRequest createIndexRequest = new CreateIndexRequest(idx);
// client执行请求
CreateIndexResponse response = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
System.out.println(idx + "索引是否创建成功:" + response.isAcknowledged());
} else {
System.out.println(idx + "索引存在");
}
}
/**
* 更新索引结构
* @throws IOException
*/
@Test
void updateIdxMappings() throws IOException {
String idx = "user_idx";//你已经创建好的索引名称
PutMappingRequest putMappingRequest = new PutMappingRequest(idx);
//构建索引结构
putMappingRequest.source("{\n" +
" \"properties\": {\n" +
" \"userId\":{\n" +
" \"type\": \"long\"\n" +
" },\n" +
" \"age\":{\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \"userName\":{\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \"content\":{\n" +
" \"type\": \"text\"\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n", XContentType.JSON);
//创建索引结构
AcknowledgedResponse acknowledgedResponse = restHighLevelClient.indices().putMapping(putMappingRequest, RequestOptions.DEFAULT);
System.out.println("mapping是否创建成功:"+acknowledgedResponse.isAcknowledged());
//获取索引结构
if(acknowledgedResponse.isAcknowledged()){
//构建请求
GetMappingsRequest getMappingsRequest = new GetMappingsRequest().indices(idx);
//使用RestHighLevelClient发起请求
GetMappingsResponse getMappingsResponse = restHighLevelClient.indices().getMapping(getMappingsRequest, RequestOptions.DEFAULT);
MappingMetaData indexMapping = getMappingsResponse.mappings().get(idx);
Map<String, Object> mapping = indexMapping.sourceAsMap();
System.out.println(mapping);
}
}
/**
* 获取索引结构
* @throws IOException
*/
@Test
void getIdxMappings() throws IOException {
//构建请求
GetMappingsRequest request = new GetMappingsRequest().indices("user_idx");
//使用RestHighLevelClient发起请求
GetMappingsResponse response = restHighLevelClient.indices().getMapping(request, RequestOptions.DEFAULT);
MappingMetaData indexMapping = response.mappings().get("user_idx");
Map<String, Object> mapping = indexMapping.sourceAsMap();
System.out.println(mapping);
}
删除索引会把索引中已经创建好的数据也删除,就好像我们在mysql中删除库,会把库的数据也删除掉一样。
/**
* 删除索引
*
* @throws IOException
*/
@Test
void delteIdx() throws IOException {
String idx = "user_idx";
GetIndexRequest request = new GetIndexRequest(idx);
boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
if (exists) {
//创建删除索引请求
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(idx);
//执行
AcknowledgedResponse delete = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
//得到相应
boolean acknowledged = delete.isAcknowledged();
System.out.println(idx + "是否删除索引成功:" + acknowledged);
} else {
System.out.println(idx + "索引不存在");
}
}
类似关闭数据库
/**
* 关闭索引
*
* @throws IOException
*/
@Test
void stopIdx() throws IOException {
String idx = "nan_index_5";
GetIndexRequest request = new GetIndexRequest(idx);
boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
if (exists) {
CloseIndexRequest closeIndexRequest = new CloseIndexRequest(idx);
AcknowledgedResponse close = restHighLevelClient.indices().close(closeIndexRequest, RequestOptions.DEFAULT);
boolean acknowledged = close.isAcknowledged();
System.out.println(idx + "索引是否关闭:" + acknowledged);
} else {
System.out.println(idx + "索引不存在");
}
}
类似启动数据库
/**
* 启动索引
*
* @throws IOException
*/
@Test
void openIdx() throws IOException {
String idx = "nan_index_5";
GetIndexRequest request = new GetIndexRequest(idx);
boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
if (exists) {
OpenIndexRequest openIndexRequest = new OpenIndexRequest(idx);
OpenIndexResponse open = restHighLevelClient.indices().open(openIndexRequest, RequestOptions.DEFAULT);
boolean acknowledged = open.isAcknowledged();
System.out.println(idx + "索引是否启动:" + acknowledged);
} else {
System.out.println(idx + "索引不存在");
}
}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@NoArgsConstructor //无参构造函数
@AllArgsConstructor//有参构造(全字段)
@Accessors(chain = true)//链式; 存取器。通过该注解可以控制getter和setter方法的形式。
public class UserStrDto implements Serializable {
private static final long serialVersionUID = 1L;
private String userId;//主键
private Integer age;
private String userName;
private String content;
}
如果是更新文档,不传的值es会设为空,谨慎操作
/**
* 插入/更新文档
* @throws IOException
*/
@Test
public void updateAllDoc() throws IOException {
//String idStr = "1680826880220434434";//更新已插入的文档
String idStr = IdWorker.getIdStr();//插入文档
UserStrDto userDto = new UserStrDto();
userDto.setUserId(idStr)
.setUserName("小尾")
.setAge(45)
.setContent("我是小尾");
String userStrJson = JSON.toJSONString(userDto);
System.out.println(userStrJson);
IndexRequest indexRequest = new IndexRequest("user_idx").id(idStr);
indexRequest.source(userStrJson, XContentType.JSON);
IndexResponse index = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
System.out.println(index.status());//CREATED=新增成功
}
es推荐使用id进行删除,不建议通过查询进行删除
/**
* 根据id删除
*
* @throws IOException
*/
@Test
public void deleteDoc() throws IOException {
DeleteRequest deleteRequest = new DeleteRequest("user_idx", "167977903112262861");
DeleteResponse delete = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
System.out.println(delete.status());
}
这里只修改传值的字段,不传的字段值不会修改,还是原样
/**
* 根据id更新
*
* @throws IOException
*/
@Test
public void updateDoc() throws IOException {
UpdateRequest updateRequest = new UpdateRequest("user_idx", "1681124336241922050");
UserStrDto userDto = new UserStrDto();
userDto.setUserName("大黄");//仅更新指定的字段
String userStrJson = JSON.toJSONString(userDto);
System.out.println(userStrJson);
updateRequest.doc(userStrJson, XContentType.JSON);
UpdateResponse update = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
System.out.println(update.status());
}
from + size是有限制的,from和size二者之和不能超过1W
@Autowired
private RestHighLevelClient restHighLevelClient;
@Test
void termQuery() throws IOException {
//1. 创建Request对象
SearchRequest request = new SearchRequest("user_idx");
//2. 指定查询条件
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.from(0);//跳过开始的结果数,默认0 -> (页数-1)*结果数
builder.size(5);//结果数,默认10
builder.query(QueryBuilders.termQuery("userName","小白"));
request.source(builder);
//3. 执行查询
SearchResponse resp = restHighLevelClient.search(request, RequestOptions.DEFAULT);
//4. 获取到_source中的数据,并展示
for (SearchHit hit : resp.getHits().getHits()) {
Map<String, Object> result = hit.getSourceAsMap();
System.out.println(result);
}
}
@Autowired
private RestHighLevelClient restHighLevelClient;
@Test
void scrollQuery() throws IOException {
//1. 创建SearchRequest
SearchRequest request = new SearchRequest("user_idx");
//2. 指定scroll信息!
request.scroll(TimeValue.timeValueMinutes(1L));//指定生存时间为1m,1分钟
//3. 指定查询条件
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.size(1);//每页4条数据
builder.sort("age", SortOrder.DESC);//按年龄排序
builder.fetchSource(new String[]{"userName", "age"},null);//只返回userName和age两个字段
builder.query(QueryBuilders.matchAllQuery());
request.source(builder);
//4. 获取返回结果scrollId,source
SearchResponse resp = restHighLevelClient.search(request, RequestOptions.DEFAULT);
String scrollId = resp.getScrollId();
System.out.println("----------首页---------"+scrollId);
for (SearchHit hit : resp.getHits().getHits()) {
System.out.println(hit.getSourceAsMap());
}
//模拟下一页
while(true) {
//5. 循环 - 创建SearchScrollRequest
SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);//根据前面得到的scorll_id去指定
//6. 指定scrollId的生存时间!
scrollRequest.scroll(TimeValue.timeValueMinutes(1L));
//7. 执行查询获取返回结果
SearchResponse scrollResp = restHighLevelClient.scroll(scrollRequest, RequestOptions.DEFAULT);
//8. 判断是否查询到了数据,输出
SearchHit[] hits = scrollResp.getHits().getHits();
if(hits != null && hits.length > 0) {
System.out.println("----------下一页---------");
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsMap());
}
}else{
//9. 判断没有查询到数据-退出循环
System.out.println("----------结束---------");
break;
}
}
//10. 创建CLearScrollRequest
ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
//11. 指定ScrollId
clearScrollRequest.addScrollId(scrollId);
//12. 删除ScrollId
ClearScrollResponse clearScrollResponse = restHighLevelClient.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);
//13. 输出结果
System.out.println("删除scroll:" + clearScrollResponse.isSucceeded());
}
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RegexpQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.IOException;
import java.util.Arrays;
@SpringBootTest
public class EsSearchAfterTest {
@Autowired
private RestHighLevelClient restHighLevelClient;
/**
* 首页
* @throws IOException
*/
@Test
void searchAfterQuery() throws IOException {
// 请求 es
SearchRequest searchRequest = new SearchRequest("user_idx");
//查询条件
BoolQueryBuilder boolQueryBuild = QueryBuilders.boolQuery();
QueryBuilder matchQuery = QueryBuilders.matchQuery("content", "我是小");
boolQueryBuild.filter(matchQuery);
// 构建请求 设置查询条件 排序条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.size(1)
.sort(SortBuilders.fieldSort("age").order(SortOrder.ASC))
.sort(SortBuilders.fieldSort("userName").order(SortOrder.ASC))
.query(boolQueryBuild);
searchRequest.source(searchSourceBuilder);
SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHit[] hits = search.getHits().getHits();
Object[] sortValue = hits[hits.length - 1].getSortValues();
System.out.println("最后一条数据sort_id为:"+ Arrays.toString(sortValue));
System.out.println("----------首页---------");
for (SearchHit hit : search.getHits().getHits()) {
//System.out.println(hit.getSourceAsMap());//map
System.out.println(hit.getSourceAsString());//json字符
Object[] sortValues = hit.getSortValues();
//System.out.println(Arrays.toString(sortValues));//每条数据的sort值
}
}
/**
* 获取下一页
* @param sortData 上一页最后一条数据的sort值
* @throws IOException
*/
@Test
void nextSearchAfterQuery(Object[] sortData) throws IOException{
// 请求 es
SearchRequest searchRequest = new SearchRequest("user_idx");
//查询条件
BoolQueryBuilder boolQueryBuild = QueryBuilders.boolQuery();
QueryBuilder matchQuery = QueryBuilders.matchQuery("content", "我是小");
boolQueryBuild.filter(matchQuery);
// 构建请求 设置查询条件 排序条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.size(1)
.sort(SortBuilders.fieldSort("age").order(SortOrder.ASC))
.sort(SortBuilders.fieldSort("userName").order(SortOrder.ASC))
.query(boolQueryBuild)
.searchAfter(sortData);//下一页的时候才加这个,放上一页最后一条数据的sort值
searchRequest.source(searchSourceBuilder);
SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHit[] hits = search.getHits().getHits();
Object[] sortValue = hits[hits.length - 1].getSortValues();
System.out.println("最后一条数据sort_id为:"+ Arrays.toString(sortValue));
System.out.println("----------下一页---------");
for (SearchHit hit : search.getHits().getHits()) {
System.out.println(hit.getSourceAsString());//json字符
}
}
}