前言
上一章节袁老师主要带领大家学习了Elasticsearch客户端基础部分的内容,Elasticsearch客户端还有很多高级相关的操作,这一章节主要带领大家来学习Elasticsearch客户端高级相关的操作。接下来就跟上袁老师的节奏继续探讨Elasticsearch的相关知识。
一. 搜索数据
1.查询所有match_all
1.先准备一部分数据。通过Kibana向yx索引库中插入以下5条数据。
POST /yx/product/1
{
"title": "小米手机Mix",
"category": "手机",
"brand": "小米",
"price": 2899.00,
"images": "http://image.yx.com/12479122.jpg"
}
POST /yx/product/2
{
"title": "坚果手机R1",
"category": "手机",
"brand": "锤子",
"price": 3699.00,
"images": "http://image.yx.com/12479122.jpg"
}
POST /yx/product/3
{
"title": "华为META20",
"category": "手机",
"brand": "华为",
"price": 4499.00,
"images": "http://image.yx.com/12479122.jpg"
}
POST /yx/product/4
{
"title": "小米Pro",
"category": "手机",
"brand": "小米",
"price": 4299.00,
"images": "http://image.yx.com/12479122.jpg"
}
POST /yx/product/5
{
"title": "荣耀V20",
"category": "手机",
"brand": "华为",
"price": 2799.00,
"images": "http://image.yx.com/12479122.jpg"
}
2.在ElasticsearchTests类中编写查询所有文档的matchAllQuery()方法。
/** 查询所有数据 */
@Test
public void matchAllQuery() throws IOException {
// 创建搜索对象
SearchRequest request = new SearchRequest();
// 查询构建工具
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 添加查询条件,通过QueryBuilders获取各种查询
sourceBuilder.query(QueryBuilders.matchAllQuery());
request.source(sourceBuilder);
// 搜索
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
// 解析
SearchHits hits = response.getHits();
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
// 取出source数据
String json = hit.getSourceAsString();
// 反序列化
Product product = gson.fromJson(json, Product.class);
System.err.println(product);
}
}
3.运行matchAllQuery()方法,输出结果见下:
Product(id=null, title=坚果手机R1, category=手机, brand=锤子, price=3699.0, images=http://image.yx.com/12479122.jpg)
Product(id=null, title=小米Pro, category=手机, brand=小米, price=4299.0, images=http://image.yx.com/12479122.jpg)
Product(id=null, title=荣耀V20, category=手机, brand=华为, price=2799.0, images=http://image.yx.com/12479122.jpg)
Product(id=null, title=小米手机Mix, category=手机, brand=小米, price=2899.0, images=http://image.yx.com/12479122.jpg)
Product(id=null, title=华为META20, category=手机, brand=华为, price=4499.0, images=http://image.yx.com/12479122.jpg)
注意,上面的代码中,搜索条件是通过sourceBuilder.query(QueryBuilders.matchAllQuery())来添加的。这个query()方法接受的参数是QueryBuilder接口类型。
这个接口提供了很多实现类,分别对应我们在之前学习的不同类型的查询。例如:term查询、match查询、range查询、boolean查询等。见下图(Mac快捷键:command+option+B):
因此,我们如果要使用各种不同查询,其实仅仅是传递给sourceBuilder.query(QueryBuilder query)方法的参数不同而已。而这些实现类不需要我们去手动创建 ,官方提供了QueryBuilders工厂帮我们构建各种实现类。
2.关键字搜索match
1.在ElasticsearchTests类中定义关键字查询文档数据的matchQuery()方法。
/** 关键字查询数据 */
@Test
public void matchQuery() throws IOException {
// 创建搜索对象
SearchRequest request = new SearchRequest();
// 查询构建工具
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 添加查询条件,通过QueryBuilders获取各种查询
sourceBuilder.query(QueryBuilders.matchQuery("title", "手机"));
request.source(sourceBuilder);
// 搜索
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
// 解析
SearchHits hits = response.getHits();
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
// 取出source数据
String json = hit.getSourceAsString();
// 反序列化
Product product = gson.fromJson(json, Product.class);
System.err.println(product);
}
}
2.运行matchQuery()方法,输出结果见下:
Product(id=null, title=坚果手机R1, category=手机, brand=锤子, price=3699.0, images=http://image.yx.com/12479122.jpg)
Product(id=null, title=小米手机Mix, category=手机, brand=小米, price=2899.0, images=http://image.yx.com/12479122.jpg)
其实搜索类型的变化,仅仅是利用QueryBuilders构建的查询对象不同而已,其他代码基本一致。因此,我们可以把这段代码封装,然后把查询条件作为参数传递。
3.在ElasticsearchTests类中定义basicQuery()方法封装代码,然后重构matchQuery()方法。
/** 关键字查询数据 */
@Test
public void matchQuery() throws IOException {
// 查询构建工具
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 添加查询条件,通过QueryBuilders获取各种查询
sourceBuilder.query(QueryBuilders.matchQuery("title", "手机"));
basicQuery(sourceBuilder);
/*
// 创建搜索对象
SearchRequest request = new SearchRequest();
// 查询构建工具
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 添加查询条件,通过QueryBuilders获取各种查询
sourceBuilder.query(QueryBuilders.matchQuery("title", "手机"));
request.source(sourceBuilder);
// 搜索
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
// 解析
SearchHits hits = response.getHits();
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
// 取出source数据
String json = hit.getSourceAsString();
// 反序列化
Product product = gson.fromJson(json, Product.class);
System.err.println(product);
}
*/
}
public void basicQuery(SearchSourceBuilder sourceBuilder) throws IOException {
// 创建搜索对象
SearchRequest request = new SearchRequest();
request.source(sourceBuilder);
// 搜索
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
// 解析
SearchHits hits = response.getHits();
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
// 取出source数据
String json = hit.getSourceAsString();
// 反序列化
Product product = gson.fromJson(json, Product.class);
System.err.println(product);
}
}
3.范围查询range
QueryBuilders类中定义返回查询的方法。
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery(String name);
RangeQueryBuilder提供多种范围查询API,常见用的见下:
方法 | 说明 |
gt(Object from) | 大于 |
gte(Object from) | 大于等于 |
lt(Object from) | 小于 |
lte(Object from) | 小于等于 |
1.在ElasticsearchTests类中定义范围查询的rangeQuery()方法。
/** 范围查询数据 */
@Test
public void rangeQuery() throws IOException {
// 查询构建工具
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 添加查询条件,通过QueryBuilders获取各种查询
sourceBuilder.query(QueryBuilders.rangeQuery("price").gt(3000).lt(5000));
basicQuery(sourceBuilder);
}
2.运行rangeQuery()方法,输出结果见下:
Product(id=null, title=坚果手机R1, category=手机, brand=锤子, price=3699.0, images=http://image.yx.com/12479122.jpg)
Product(id=null, title=小米Pro, category=手机, brand=小米, price=4299.0, images=http://image.yx.com/12479122.jpg)
Product(id=null, title=华为META20, category=手机, brand=华为, price=4499.0, images=http://image.yx.com/12479122.jpg)
4.source过滤
默认情况下,索引库中所有数据都会返回(_source属性中存储原始文档),如果我们想只返回部分字段,可以通过source filter来控制。
1.在ElasticsearchTests类中定义过滤查询的sourceFilter()方法。
/** 过滤查询数据 */
@Test
public void sourceFilter() throws IOException {
// 查询构建工具
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 添加查询条件,通过QueryBuilders获取各种查询
sourceBuilder.query(QueryBuilders.matchAllQuery());
// 添加source过滤
sourceBuilder.fetchSource(new String[] {"id", "title", "price"}, null);
basicQuery(sourceBuilder);
}
2.运行sourceFilter()方法,输出结果见下:
Product(id=null, title=坚果手机R1, category=null, brand=null, price=3699.0, images=null)
Product(id=null, title=小米Pro, category=null, brand=null, price=4299.0, images=null)
Product(id=null, title=荣耀V20, category=null, brand=null, price=2799.0, images=null)
Product(id=null, title=小米手机Mix, category=null, brand=null, price=2899.0, images=null)
Product(id=null, title=华为META20, category=null, brand=null, price=4499.0, images=null)
二. 排序
排序依然是通过SearchSourceBuilder来进行配置。
1.在ElasticsearchTests类中定义过滤查询的sort()方法。
/** 排序查询数据 */
@Test
public void sort() throws IOException {
// 创建搜索对象
SearchRequest request = new SearchRequest();
// 查询构建工具
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 添加查询条件,通过QueryBuilders获取各种查询
sourceBuilder.query(QueryBuilders.matchAllQuery());
// 添加排序
sourceBuilder.sort("price", SortOrder.DESC);
basicQuery(sourceBuilder);
}
2.运行sort()方法,输出结果见下:
Product(id=null, title=华为META20, category=手机, brand=华为, price=4499.0, images=http://image.yx.com/12479122.jpg)
Product(id=null, title=小米Pro, category=手机, brand=小米, price=4299.0, images=http://image.yx.com/12479122.jpg)
Product(id=null, title=坚果手机R1, category=手机, brand=锤子, price=3699.0, images=http://image.yx.com/12479122.jpg)
Product(id=null, title=小米手机Mix, category=手机, brand=小米, price=2899.0, images=http://image.yx.com/12479122.jpg)
Product(id=null, title=荣耀V20, category=手机, brand=华为, price=2799.0, images=http://image.yx.com/12479122.jpg)
三. 分页
1.分页语法
分页需要视图层传递两个参数给后台。
参数 | 描述 |
page | 当前页 |
size | 每页大小 |
而Elasticsearch中需要的不是当前页,而是当前页的起始位置,还好有公式可以计算出。
起始位置:from = (page - 1) * size
2.分页案例
1.在ElasticsearchTests类中定义分页查询的paging()方法。
/** 分页查询数据 */
@Test
public void paging() throws IOException {
// 创建搜索对象
SearchRequest request = new SearchRequest();
// 查询构建工具
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 添加查询条件,通过QueryBuilders获取各种查询
sourceBuilder.query(QueryBuilders.matchAllQuery());
// 分页查询
int page = 1;
int size = 3;
int from = (page - 1) * size;
// 配置分页
sourceBuilder.from(from);
sourceBuilder.size(size);
basicQuery(sourceBuilder);
}
2.运行paging()方法,输出结果见下:
Product(id=null, title=坚果手机R1, category=手机, brand=锤子, price=3699.0, images=http://image.yx.com/12479122.jpg)
Product(id=null, title=小米Pro, category=手机, brand=小米, price=4299.0, images=http://image.yx.com/12479122.jpg)
Product(id=null, title=荣耀V20, category=手机, brand=华为, price=2799.0, images=http://image.yx.com/12479122.jpg)
四. 结语
Elasticsearch客户端高级操作的内容袁老师就带领大学学习到这里,这一章节主要带领大学学习了:搜索数据,包括查询所有match_all、关键字搜索match、范围查询range和source过滤内容,同时还介绍了排序和分页等操作。好了关于Elasticsearch客户端操作的所有内容我们就学完啦。
今天的内容就分享到这里吧。关注「袁庭新」,干货天天都不断!