说明:elasticsearch查询操作除了使用DSL语句的方式(参考:elasticsearch查询操作(语句方式)),也可以使用API的方式。
准备
使用前需先导入依赖
<!--RestHighLevelClient依赖-->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>
创建一个测试类,查询操作代码都写在测试类里面,首先先建立RestHighLevelClient的连接
/**
* 定义连接
*/
private RestHighLevelClient client;
/**
* 初始化客户端
*/
@BeforeEach
public void init(){
client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://服务器IP地址:9200")));
}
/**
* 关闭客户端
* @throws IOException
*/
@AfterEach
public void close() throws IOException {
client.close();
}
1、模糊查询
(1)全部查询;
查询student索引库的所有文档;
/**
* 1.1 全部查询
* @throws IOException
*/
@Test
public void queryMatchAll() throws IOException {
// 1.创建请求
SearchRequest request = new SearchRequest("student");
// 2.编写DSL语句
request.source().equals(QueryBuilders.matchAllQuery());
// 3.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 4.解析返回值,并打印
SearchHits hits = response.getHits();
// 遍历his
for (SearchHit hit : hits) {
// 获取字符串
String json = hit.getSourceAsString();
// 解析字符串成对象
StudentDoc studentDoc = JSON.parseObject(json, StudentDoc.class);
// 打印
System.out.println("studentDoc = " + studentDoc);
}
可以看到,API方式的全查默认还是值返回前10条;
把解析返回值的代码抽取出来成一个方法,方便后面使用
/**
* 解析返回值并打印
* @param response
*/
private void parseJson(SearchResponse response) {
// 获取his数据
SearchHits hits = response.getHits();
// 遍历his
for (SearchHit hit : hits) {
// 获取字符串
String json = hit.getSourceAsString();
// 解析字符串成对象
StudentDoc studentDoc = JSON.parseObject(json, StudentDoc.class);
// 打印
System.out.println("studentDoc = " + studentDoc);
}
}
(2)单字段查询;
例如,查询all字段值为马尔克斯的文档;
/**
* 1.2 单字段查询
* @throws IOException
*/
@Test
public void queryMatch() throws IOException {
// 1.创建请求
SearchRequest request = new SearchRequest("student");
// 2.编写DSL语句
request.source().query(QueryBuilders.matchQuery("all","马尔克斯"));
// 3.发送请求
SearchResponse search = client.search(request, RequestOptions.DEFAULT);
// 4.解析返回值,并打印
parseJson(search);
}
代码执行完成,查询成功;
(3)多字段查询;
例如,查询name、username和gender字段值包括“陀”的文档;
/**
* 1.3 多字段查询
* @throws IOException
*/
@Test
public void multiMatchQuery() throws IOException {
// 1.创建请求
SearchRequest request = new SearchRequest("student");
// 2.创建DSL语句
request.source().query(QueryBuilders.multiMatchQuery("陀","name","username","gender"));
// 3.发送请求
SearchResponse search = client.search(request, RequestOptions.DEFAULT);
// 4.解析返回值,并打印
parseJson(search);
}
代码执行完成,查询成功;
2、精确查询
(1)term查询;
例如,查询name值为杜甫的文档;
/**
* 2.1 term查询
* @throws IOException
*/
@Test
public void termQuery() throws IOException {
// 1.创建请求
SearchRequest request = new SearchRequest("student");
// 2.创建DSL语句
request.source().query(QueryBuilders.termQuery("name","杜甫"));
// 3.发送请求
SearchResponse search = client.search(request, RequestOptions.DEFAULT);
// 4.解析返回值,并打印
parseJson(search);
}
查询完成;
(2)range查询;
例如,查询job大于1,小于等于3的文档;
/**
* 2.2 range查询
* @throws IOException
*/
@Test
public void rangeQuery() throws IOException {
// 1.创建请求
SearchRequest request = new SearchRequest("student");
// 2.编写DSL语句
request.source().query(QueryBuilders.rangeQuery("job").gt(1).lte(3));
// 3.发送请求
SearchResponse search = client.search(request, RequestOptions.DEFAULT);
// 4.解析返回值,并打印
parseJson(search);
}
查询完成;
3、复合查询
例如,查询all字段为萨特,并且job≥2,≤4的文档;
/**
* 3. 复合查询
* @throws IOException
*/
@Test
public void booleanQuery() throws IOException {
// 1.创建请求
SearchRequest request = new SearchRequest("student");
// 2.编写DSL语句
request.source().query(QueryBuilders.boolQuery()
.must(QueryBuilders.matchQuery("all","萨特"))
.filter(QueryBuilders.rangeQuery("job").gte(2).lte(4)));
// 3.发送请求
SearchResponse search = client.search(request, RequestOptions.DEFAULT);
// 4.解析返回值,并打印
parseJson(search);
}
查询完成,因为萨特的job=1,所以未查询出来;
更换job条件为≥1,再查询,可以查询出来;
4、分页、排序查询
例如,查询job≥1,≤4,按照job降序排序,并且从第2条文档开始,往后取8条;
/**
* 4. 分页、排序查询
* @throws IOException
*/
@Test
public void queryByPageAndSort() throws IOException {
// 1.创建请求
SearchRequest request = new SearchRequest("student");
// 2.编写DSL语句
request.source().query(QueryBuilders.rangeQuery("job").gte(1).lte(4));
// 3.分页查询,查询从第2条开始,往后8条
request.source().from(2).size(8);
// 4.排序
request.source().sort("job", SortOrder.DESC);
// 5.发送请求
SearchResponse search = client.search(request, RequestOptions.DEFAULT);
// 6.解析返回值,并打印
parseJson(search);
}
全部符合条件的记录;
分页、排序查询后,可以看到只有当前页的内容,并且job按照升序排序;
从结果可以看出,from()中的索引是从0开始的,from(2)表示从第三条开始计算;
5、高亮查询
例如,把name等于关羽的文档,name字段的值设置为斜体(em);
/**
* 6.高亮显示
*/
@Test
public void heightLight() throws Exception {
// 1.创建请求
SearchRequest request = new SearchRequest("student");
// 2.编写DSL语句
request.source().query(QueryBuilders.matchQuery("name","关羽"));
// 3.声明高亮显示
request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));
// 4.发送请求
SearchResponse search = client.search(request, RequestOptions.DEFAULT);
// 5.解析返回值
SearchHits hits = search.getHits();
// 6.遍历his
for (SearchHit hit : hits) {
// 7.获取字符串
String json = hit.getSourceAsString();
// 8.解析字符串成对象
StudentDoc studentDoc = JSON.parseObject(json, StudentDoc.class);
// 9.获取高亮字段
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
// 10.判断高亮字段不能为空
if (!CollectionUtils.isEmpty(highlightFields)) {
// 11.获取高亮字段值
HighlightField highlightField = highlightFields.get("name");
// 12.判断高亮字段值不等于空
if (highlightField != null){
// 13.获取高亮字段值
String heightFightName = highlightField.getFragments()[0].string();
// 14.将高亮字段值重新赋值给对象并打印
studentDoc.setName(heightFightName);
System.out.println("studentDoc = " + studentDoc);
}
}
}
}
执行代码,可以看到关羽的name字段值被em标签包裹;