4.ES的Java客户端
在elasticsearch官网中提供了各种语言的客户端:
https://www.elastic.co/guide/en/elasticsearch/client/index.html
而Java的客户端就有两个:
不过Java API这个客户端(Transport Client)已经在7.0以后过期了,而且在8.0版本中将直接废弃
Java REST Client 其实就是利用Java语言向 ES服务发 Http的请求
3.1.准备数据库数据
我们需要从数据库导入数据到ES中,因此需要做一些准备:
- 引入依赖
- 执行sql,准备数据
- 引入实体类
- 引入mybatis相关配置
- 引入mapper和service代码
3.1.1.引入依赖
在项目的pom文件中引入一些依赖:
3.1.2.执行sql
3.1.3.引入实体类
3.1.4.引入mybatis配置
3.1.5.引入mapper和Service
此处均省略,大家可自行配置
3.2.连接ElasticSearch
在官网上可以看到连接ES的教程:
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-getting-started-initialization.html
首先需要与ES建立连接,ES提供了一个客户端RestHighLevelClient。
代码如下:
RestHighLevelClient client = new RestHighLevelClient(
? ? ? ? ? ? ? ?RestClient.builder(
? ? ? ? ? ? ? ? ? ? ? ?new HttpHost("localhost", 9200, "http"),
? ? ? ? ? ? ? ? ? ? ? ?new HttpHost("localhost", 9201, "http"),
? ? ? ? ? ? ? ? ? ? ? ?new HttpHost("localhost", 9202, "http")
? ? ? ? ? ? ? )
? ? ? );
ES中的所有操作都是通过RestHighLevelClient来完成的:
为了后面测试方便,我们写到一个单元测试中,并且通过@Before注解来初始化客户端连接。
/**
*
*/
public class ElasticDemo {
private RestHighLevelClient client;
/**
* 建立连接
*/
@Before
public void init() throws IOException {
client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http"),
new HttpHost("localhost", 9201, "http"),
new HttpHost("localhost", 9202, "http")
)
);
}
/**
* 关闭客户端连接
*/
@After
public void close() throws IOException {
client.close();
}
}
4.Java实现创建库和映射
开发中,往往库和映射的操作一起完成,官网详细文档地址:
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.x/_index_apis.html
4.1.思路分析
按照官网给出的步骤,创建索引包括下面几个步骤:
- 1)创建CreateIndexRequest对象,并指定索引库名称
- 2)指定settings配置
- 3)指定mapping配置
- 4)发起请求,得到响应
其实仔细分析,与我们在Kibana中的Rest风格API完全一致:
PUT /heima
{
?"settings": {
? ?"number_of_shards": 3,
? ?"number_of_replicas": 1
},
?"mappings": {
? ?
}
}
4.2.设计映射规则
Java代码中设置mapping,依然与REST中一致,需要JSON风格的映射规则。因此我们先在kibana中给User实体类定义好映射规则。
User包括下面的字段:
- Id:主键,在ES中是唯一标示,数字,可以选择long类型
- name:姓名,字符串类型,但是无需分词,使用keyword,也无需查找,index为false
- age:年龄,整数,可以使用integer
- gender:性别,字符串类型,但是无需分词,使用keyword
- note:备注,用户详细信息,字符串类型。需要分词,使用text
4.3.代码实现
我们在上面新建的ElasticDemo类中新建单元测试,完成代码,思路就是之前分析的4步骤:
- 1)创建CreateIndexRequest对象,并指定索引库名称
- 2)指定settings配置
- 3)指定mapping配置
- 4)发起请求,得到响应
private RestHighLevelClient client;
@Test
public void testCreateIndex() throws IOException {
// 1.创建CreateIndexRequest对象,并指定索引库名称
CreateIndexRequest request = new CreateIndexRequest("user");
// 2.指定settings配置
request.settings(Settings.builder()
.put("index.number_of_shards", 3)
.put("index.number_of_replicas", 1)
);
// 3.指定mapping配置
request.mapping(
"{\n" +
" \"properties\": {\n" +
" \"id\": {\n" +
" \"type\": \"long\"\n" +
" },\n" +
" \"name\":{\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \"age\":{\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \"gender\":{\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \"note\":{\n" +
" \"type\": \"text\",\n" +
" \"analyzer\": \"ik_max_word\"\n" +
" }\n" +
" }\n" +
" }",
XContentType.JSON);
// 4.发起请求,得到响应
CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
System.out.println("response = " + response.isAcknowledged());
}
5.Java实现文档的CRUD
文档操作包括:新增文档、查询文档、修改文档、删除文档等。
官网地址:
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.x/java-rest-high-supported-apis.html
5.1.新增
官网地址:
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.x/java-rest-high-document-index.html
5.1.1.实现思路
根据官网文档,实现的步骤如下:
- 1)创建IndexRequest对象,并指定索引库名称
- 2)指定新增的数据的id
- 3)将新增的文档数据变成JSON格式
- 4)将JSON数据添加到IndexRequest中
- 5)发起请求,得到结果
不过,我们的文档数据需要去查询数据库,因此前面会多出一个步骤:从数据库查询文档数据
- 1)从数据库查询文档数据
- 2)创建IndexRequest对象,并指定索引库名称
- 3)指定新增的数据的id
- 4)将新增的文档数据变成JSON格式
- 5)将JSON数据添加到IndexRequest中
- 6)发起请求,得到结果
5.1.2.具体代码
需要在单元测试类中线初始化UserService对象:
private UserService userService = new UserService();
新增文档:
@Test
public void addDocument() throws IOException {
? ?// 1.从数据库查询文档数据
? ?User user = userService.findById(6L);
? ?// 2.创建IndexRequest对象,并指定索引库名称
? ?IndexRequest request = new IndexRequest("user");
? ?// 3.指定新增的数据的id,这里的id一定要用string
? ?request.id(user.getId().toString());
? ?// 4.将新增的文档数据变成JSON格式
? ?String jsonString = JSON.toJSONString(user);
? ?// 5.将JSON数据添加到IndexRequest中
? ?request.source(jsonString, XContentType.JSON);
? ?// 6.发起请求,得到结果
? ?IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
? ?System.out.println("indexResponse = " + indexResponse.getResult());
}
结果:
indexResponse = CREATED
5.1.3.新增的ID一致时
我们直接测试过,新增的时候如果ID存在则变成修改,我们试试,再次执行刚才的代码,可以看到结果变了
5.2.查询文档
官网地址:
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.x/java-rest-high-document-get.html
5.2.1.实现思路
这里的查询是根据id查询,必须知道文档的id才可以。
根据官网文档,实现的步骤如下:
- 1)创建GetRequest 对象,并指定索引库名称、文档ID
- 2)发起请求,得到结果
- 3)从结果中得到source,是json字符串
- 4)将JSON反序列化为对象
5.2.2.具体代码
@Test
public void getDocument() throws IOException {
? ?// 1.创建GetRequest对象,并指定索引库名称、文档ID
? ?GetRequest request = new GetRequest("user", "6");
? ?// 2.发起请求,得到结果
? ?GetResponse response = client.get(request, RequestOptions.DEFAULT);
? ?// 3.从结果中得到source,是json字符串
? ?String source = response.getSourceAsString();
? ?// 4.将JSON反序列化为对象
? ?User user = JSON.parseObject(source, User.class);
? ?System.out.println("user = " + user);
}
结果如下:
user = User(id=6, name=李磊, age=23, gender=男, note=李磊同学在传智播客学Java)
5.3.修改文档
新增时,如果ID一致就会覆盖旧的数据,实现修改。不过,如果我们只修改文档中的某个字段,可以使用另外的API:
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.x/java-rest-high-document-update.html
5.3.1.思路
根据官网信息,修改时需要指定某个已经存在的文档的id、然后指定要修改的字段及新的值。
基本步骤如下:
- 1.创建UpdateRequest对象,指定索引库名称、文档ID
- 2.指定要修改的字段及属性值
- 3.发起请求
5.3.2.代码实现
@Test
public void updateDocument() throws IOException {
? ?// 1.创建UpdateRequest对象,指定索引库名称、文档ID
? ?UpdateRequest request = new UpdateRequest(
? ? ? ?"user",
? ? ? ?"6");
? ?// 2.指定要修改的字段及属性值
? ?request.doc("gender", "女");
? ?// 3.发起请求
? ?UpdateResponse updateResponse = client.update(
? ? ? ?request, RequestOptions.DEFAULT);
? ?System.out.println("updateResponse = " + updateResponse.getResult());
}
结果如下:
updateResponse = UPDATED
如果再次查询
user = User(id=6, name=李磊, age=23, gender=女, note=柳岩同学在欢哥身边跳舞)
5.4.删除文档
官网地址:
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.x/java-rest-high-document-delete.html
实现思路非常简单,直接根据ID删除即可:
- 1.创建DeleteRequest对象,指定索引库名称、文档ID
- 2.发起请求
代码实现:
@Test
public void deleteDocument() throws IOException {
? ?// 1.创建DeleteRequest对象,指定索引库名称、文档ID
? ?DeleteRequest request = new DeleteRequest(
? ? ? ?"user",
? ? ? ?"6");
? ?// 2.发起请求
? ?DeleteResponse deleteResponse = client.delete(
? ? ? ?request, RequestOptions.DEFAULT);
? ?System.out.println("deleteResponse = " + deleteResponse.getResult());
}
结果:
deleteResponse = DELETED
5.5.批处理
如果我们需要把数据库中的所有用户信息都导入索引库,可以批量查询出多个用户,但是刚刚的新增文档是一次新增一个文档,这样效率太低了。
因此ElasticSearch提供了批处理的方案:BulkRequest
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.x/java-rest-high-document-bulk.html
5.5.1.思路分析
A BulkRequest can be used to execute multiple index, update and/or delete operations using a single request.
一个BulkRequest可以在一次请求中执行多个 新增、更新、删除请求。
所以,BulkRequest就是把多个其它增、删、改请求整合,然后一起发送到ES来执行。
我们拿批量新增来举例,步骤如下:
- 1.从数据库查询文档数据
- 2.创建BulkRequest对象
- 3.创建多个IndexRequest对象,组织文档数据,并添加到BulkRequest中
- 4.发起请求
5.5.2.具体代码
@Test
public void testBulk() throws IOException {
? ?// 1.从数据库查询文档数据
? ?List list = userService.findAll();
? ?// 2.创建BulkRequest对象
? ?BulkRequest bulkRequest = new BulkRequest();
? ?// 3.创建多个IndexRequest对象,并添加到BulkRequest中
? ?for (User user : list) {
? ? ? ?bulkRequest.add(new IndexRequest("user")
? ? ? ? ? ? ? ? ? ? ? .id(user.getId().toString())
? ? ? ? ? ? ? ? ? ? ? .source(JSON.toJSONString(user), XContentType.JSON)
? ? ? ? ? ? ? ? ? ? ? );
? }
? ?// 4.发起请求
? ?BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
? ?System.out.println("status: " + bulkResponse.status());
}
结果如下:
status: OK
6.Java实现搜索
查询、搜索相关功能主要包括:
- 基本查询:query分词查询:match查询词条查询:term查询范围查询:range查询布尔查询:bool查询filter功能
- 排序:sort
- 分页:from和size
- 高亮:highlight
- source过滤
官方文档:
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.x/java-rest-high-search.html
6.1.搜索的核心API
先来看下REST风格中查询的语法:
整个请求对象是一个大JSON对象,包含5部分属性:
- query:查询属性
- sort:排序属性
- from和size:分页属性
- highlight:高亮属性
- aggs:聚合属性
而Java客户端,其实也是在构建这样的JSON对象。
6.1.1.SearchSourceBuilder
在Java客户端中,SearchSourceBuilder就是用来构建上面提到的大JSON对象,其中包含了5个方法:
- query(QueryBuilder):查询条件
- sort(String, SortOrder):排序条件
- from(int)和size(int):分页条件
- highlight(HighlightBuilder):高亮条件
- aggregation(AggregationBuilder):聚合条件
搜索得到的结果整体是一个JSON对象,包含下列2个属性:
- hits:查询结果,其中又包含两个属性:total:总命中数量hits:查询到的文档数据,是一个数组,数组中的每个对象就包含一个文档结果,又包含:_source:文档原始信息highlight:高亮结果信息
- aggregations:聚合结果对象,其中包含多个属性,属性名称由添加聚合时的名称来确定:gender_agg:这个是我们创建聚合时用的聚合名称,其中包含聚合结果buckets:聚合结果数组
Java客户端中的SearchResponse代表整个JSON结果
6.2.1.SearchResponse
Java客户端中的SearchResponse代表整个JSON结果,包含下面的方法:
包含两个方法:
- getHits():返回的是SearchHits,代表查询结果
- getAggregations():返回的是Aggregations,代表聚合结果
6.2.2.SearchHits查询结果
SearchHits代表查询结果的JSON对象:
核心方法有3个:
- getHits():返回SearchHit数组
- getMaxScore():返回float,文档的最大得分
- getTotalHists():返回TotalHists,总命中数
6.2.3.SearchHit结果对象
- getSourceAsString():返回的是_source
- getHighLightFields():返回是高亮结果
6.3.基本查询
6.3.1.思路分析
步骤如下:
- 1.创建SearchSourceBuilder对象1.1.添加查询条件QueryBuilders1.2.添加排序、分页等其它条件
- 2.创建SearchRequest对象,并制定索引库名称
- 3.添加SearchSourceBuilder对象到SearchRequest对象中
- 4.发起请求,得到结果
- 5.解析结果5.1.获取总条数5.2.获取SearchHits数组,并遍历获取其中的_source,是JSON数据把_source反序列化为User对象
6.3.2.查询所有
QueryBuilders可以实现各种查询,比如查询所有:match_all
代码如下:
@Test
public void testBasicSearch() throws IOException {
? ?// 1.创建SearchSourceBuilder对象
? ?SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
? ?// 1.1.添加查询条件QueryBuilders,这里选择match_all,查询所有
? ?sourceBuilder.query(QueryBuilders.matchAllQuery());
? ?// 1.2.添加排序、分页等其它条件
? ?// 2.创建SearchRequest对象,并制定索引库名称
? ?SearchRequest request = new SearchRequest("user");
? ?// 3.添加SearchSourceBuilder对象到SearchRequest对象中
? ?request.source(sourceBuilder);
? ?// 4.发起请求,得到结果
? ?SearchResponse response = client.search(request, RequestOptions.DEFAULT);
? ?// 5.解析结果
? ?SearchHits searchHits = response.getHits();
? ?// 5.1.获取总条数
? ?long total = searchHits.getTotalHits().value;
? ?System.out.println("total = " + total);
? ?// 5.2.获取SearchHits数组,并遍历
? ?SearchHit[] hits = searchHits.getHits();
? ?for (SearchHit hit : hits) {
? ? ? ?// - 获取其中的`_source`,是JSON数据
? ? ? ?String json = hit.getSourceAsString();
? ? ? ?// - 把`_source`反序列化为User对象
? ? ? ?User user = JSON.parseObject(json, User.class);
? ? ? ?System.out.println("user = " + user);
? }
}
结果如下
total = 5
user = User(id=5, name=李娜, age=28, gender=女, note=李娜同学在欢哥房间学画画)
user = User(id=2, name=李四, age=21, gender=男, note=李四同学在华为敲代码)
user = User(id=4, name=张伟, age=20, gender=男, note=张伟同学在交友软件谈恋爱)
user = User(id=10, name=范冰冰, age=25, gender=女, note=范冰冰同学在欢哥旁边表演)
user = User(id=8, name=柳岩, age=21, gender=女, note=柳岩同学在欢哥旁边唱歌)
6.3.3.分词查询
MatchQuery就是分词查询,会对搜索的内容分词后查询:
sourceBuilder.query(QueryBuilders.matchQuery("note", "唱歌表演"));
完整代码如下:
@Test
public void testBasicSearch() throws IOException {
? ?// 1.创建SearchSourceBuilder对象
? ?SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
? ?// 1.1.添加查询条件QueryBuilders,这里选择match_all,查询所有
? ?// ? ? ? sourceBuilder.query(QueryBuilders.matchAllQuery());
? ?sourceBuilder.query(QueryBuilders.matchQuery("note", "唱歌表演"));
? ?// 1.2.添加排序、分页等其它条件
? ?// 2.创建SearchRequest对象,并制定索引库名称
? ?SearchRequest request = new SearchRequest("user");
? ?// 3.添加SearchSourceBuilder对象到SearchRequest对象中
? ?request.source(sourceBuilder);
? ?// 4.发起请求,得到结果
? ?SearchResponse response = client.search(request, RequestOptions.DEFAULT);
? ?// 5.解析结果
? ?SearchHits searchHits = response.getHits();
? ?// 5.1.获取总条数
? ?long total = searchHits.getTotalHits().value;
? ?System.out.println("total = " + total);
? ?// 5.2.获取SearchHits数组,并遍历
? ?SearchHit[] hits = searchHits.getHits();
? ?for (SearchHit hit : hits) {
? ? ? ?// - 获取其中的`_source`,是JSON数据
? ? ? ?String json = hit.getSourceAsString();
? ? ? ?// - 把`_source`反序列化为User对象
? ? ? ?User user = JSON.parseObject(json, User.class);
? ? ? ?System.out.println("user = " + user);
? }
}
结果:
total = 2
user = User(id=10, name=范冰冰, age=25, gender=女, note=范冰冰同学在欢哥旁边表演)
user = User(id=8, name=柳岩, age=21, gender=女, note=柳岩同学在欢哥旁边唱歌)
6.3.4.布尔查询
BooleanQuery就是布尔查询,需要把其它几个查询用must、must_not组合,另外过滤条件最好使用filter来实现。比如:
// 布尔查询
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
// 添加must条件
queryBuilder.must(QueryBuilders.matchQuery("note", "唱歌表演"));
// 添加filter条件,不参与打分
queryBuilder.filter(QueryBuilders.rangeQuery("age").gte(18).lte(24));
sourceBuilder.query(queryBuilder);
完整代码:
@Test
public void testBasicSearch() throws IOException {
? ?// 1.创建SearchSourceBuilder对象
? ?SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
? ?// 1.1.添加查询条件QueryBuilders,这里选择match_all,查询所有
? ?// ? ? ? sourceBuilder.query(QueryBuilders.matchAllQuery());
? ?// ? ? ? sourceBuilder.query(QueryBuilders.matchQuery("note", "唱歌表演"));
? ?// 布尔查询
? ?BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
? ?// 添加must条件
? ?queryBuilder.must(QueryBuilders.matchQuery("note", "唱歌表演"));
? ?// 添加filter条件,不参与打分
? ?queryBuilder.filter(QueryBuilders.rangeQuery("age").gte(18).lte(24));
? ?sourceBuilder.query(queryBuilder);
? ?// 1.2.添加排序、分页等其它条件
? ?// 2.创建SearchRequest对象,并制定索引库名称
? ?SearchRequest request = new SearchRequest("user");
? ?// 3.添加SearchSourceBuilder对象到SearchRequest对象中
? ?request.source(sourceBuilder);
? ?// 4.发起请求,得到结果
? ?SearchResponse response = client.search(request, RequestOptions.DEFAULT);
? ?// 5.解析结果
? ?SearchHits searchHits = response.getHits();
? ?// 5.1.获取总条数
? ?long total = searchHits.getTotalHits().value;
? ?System.out.println("total = " + total);
? ?// 5.2.获取SearchHits数组,并遍历
? ?SearchHit[] hits = searchHits.getHits();
? ?for (SearchHit hit : hits) {
? ? ? ?// - 获取其中的`_source`,是JSON数据
? ? ? ?String json = hit.getSourceAsString();
? ? ? ?// - 把`_source`反序列化为User对象
? ? ? ?User user = JSON.parseObject(json, User.class);
? ? ? ?System.out.println("user = " + user);
? }
}
结果:
total = 1
user = User(id=8, name=柳岩, age=21, gender=女, note=柳岩同学在欢哥旁边唱歌)
6.4.source过滤
在原来搜索的基础上,通过SearchSourceBuilder的fetchSource(String[] includes, String[] excludes)方法实现:
- includes:包含的字段
- excludes:要排除的字段
代码:
// 2.source过滤,指定includes,只要id、name、note
sourceBuilder.fetchSource(new String[]{"id", "name", "note"}, new String[0]);
完整代码:
@Test
public void testBasicSearch() throws IOException {
? ?// 1.创建SearchSourceBuilder对象
? ?SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
? ?// 1.1.添加查询条件QueryBuilders,这里选择match_all,查询所有
? ?sourceBuilder.query(QueryBuilders.matchQuery("note", "唱歌表演"));
? ?// 2.source过滤,指定includes,只要id、name、note
? ?sourceBuilder.fetchSource(new String[]{"id", "name", "note"}, new String[0]);
? ?// 3.创建SearchRequest对象,并制定索引库名称
? ?SearchRequest request = new SearchRequest("user");
? ?// 4.添加SearchSourceBuilder对象到SearchRequest对象中
? ?request.source(sourceBuilder);
? ?// 5.发起请求,得到结果
? ?SearchResponse response = client.search(request, RequestOptions.DEFAULT);
? ?// 6.解析结果
? ?SearchHits searchHits = response.getHits();
? ?// 6.1.获取总条数
? ?long total = searchHits.getTotalHits().value;
? ?System.out.println("total = " + total);
? ?// 6.2.获取SearchHits数组,并遍历
? ?SearchHit[] hits = searchHits.getHits();
? ?for (SearchHit hit : hits) {
? ? ? ?// - 获取其中的`_source`,是JSON数据
? ? ? ?String json = hit.getSourceAsString();
? ? ? ?// - 把`_source`反序列化为User对象
? ? ? ?User user = JSON.parseObject(json, User.class);
? ? ? ?System.out.println("user = " + user);
? }
}
结果:
total = 2
user = User(id=10, name=范冰冰, age=null, gender=null, note=范冰冰同学在欢哥旁边表演)
user = User(id=8, name=柳岩, age=null, gender=null, note=柳岩同学在欢哥旁边唱歌)
6.5.排序
6.5.1.API介绍
通过SearchSourceBuilder的sort(String, SortOrder)方法用来实现排序条件的封装:
/**
?* Adds a sort against the given field name and the sort ordering.
?*
?* @param name The name of the field,排序字段名称
?* @param order The sort ordering,排序的方式
?*/
public SearchSourceBuilder sort(String name, SortOrder order) {
? ?// ...
}
其中的SortOrder是一个枚举,包含ASC和DESC两个枚举项:
public enum SortOrder implements Writeable {
? ?/**
? ? * Ascending order.
? ? */
? ?ASC {
// ..
? },
? ?/**
? ? * Descending order.
? ? */
? ?DESC {
// ..
? };
? ?// ...
}
6.5.2.具体实现
在原由查询的基础上,给SearchSourceBuilder中添加sort即可:
? ?// 1.2.添加排序条件
? ?sourceBuilder.sort("id", SortOrder.ASC);
完整代码如下:
@Test
public void testBasicSearchAndSort() throws IOException {
? ?// 1.创建SearchSourceBuilder对象
? ?SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
? ?// 1.1.添加查询条件QueryBuilders,这里选择match_all,查询所有
? ?sourceBuilder.query(QueryBuilders.matchAllQuery());
? ?
? ?// 1.2.添加排序条件
? ?sourceBuilder.sort("id", SortOrder.ASC);
? ?
? ?// 2.创建SearchRequest对象,并制定索引库名称
? ?SearchRequest request = new SearchRequest("user");
? ?// 3.添加SearchSourceBuilder对象到SearchRequest对象中
? ?request.source(sourceBuilder);
? ?// 4.发起请求,得到结果
? ?SearchResponse response = client.search(request, RequestOptions.DEFAULT);
? ?// 5.解析结果
? ?SearchHits searchHits = response.getHits();
? ?// 5.1.获取总条数
? ?long total = searchHits.getTotalHits().value;
? ?System.out.println("total = " + total);
? ?// 5.2.获取SearchHits数组,并遍历
? ?SearchHit[] hits = searchHits.getHits();
? ?for (SearchHit hit : hits) {
? ? ? ?// - 获取其中的`_source`,是JSON数据
? ? ? ?String json = hit.getSourceAsString();
? ? ? ?// - 把`_source`反序列化为User对象
? ? ? ?User user = JSON.parseObject(json, User.class);
? ? ? ?System.out.println("user = " + user);
? }
}
查询结果:
total = 5
user = User(id=2, name=李四, age=21, gender=男, note=李四同学在华为敲代码)
user = User(id=4, name=张伟, age=20, gender=男, note=张伟同学在交友软件谈恋爱)
user = User(id=5, name=李娜, age=28, gender=女, note=李娜同学在欢哥房间学画画)
user = User(id=8, name=柳岩, age=21, gender=女, note=柳岩同学在欢哥旁边唱歌)
user = User(id=10, name=范冰冰, age=25, gender=女, note=范冰冰同学在欢哥旁边表演)
6.5.分页
在原由查询的基础上,给SearchSourceBuilder中添加from和size即可。例如我们的分页信息是:
page = 1,size = 5,代表查询第一页,每页5条,可以计算出: from = (page - 1) * size = 0
所以,代码如下:
// 1.3.添加分页条件
int page = 1, size = 5;
int from = (page - 1) * size;
sourceBuilder.from(from);
sourceBuilder.size(size);
完整代码:
@Test
public void testBasicSearchWithSortAndPage() throws IOException {
? ?// 1.创建SearchSourceBuilder对象
? ?SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
? ?// 1.1.添加查询条件QueryBuilders,这里选择match_all,查询所有
? ?sourceBuilder.query(QueryBuilders.matchAllQuery());
? ?// 1.2.添加排序、分页等其它条件
? ?sourceBuilder.sort("id", SortOrder.ASC);
? ?// 1.3.添加分页条件
? ?int page = 1, size = 5;
? ?int from = (page - 1) * size;
? ?sourceBuilder.from(from);
? ?sourceBuilder.size(size);
? ?// 2.创建SearchRequest对象,并制定索引库名称
? ?SearchRequest request = new SearchRequest("user");
? ?// 3.添加SearchSourceBuilder对象到SearchRequest对象中
? ?request.source(sourceBuilder);
? ?// 4.发起请求,得到结果
? ?SearchResponse response = client.search(request, RequestOptions.DEFAULT);
? ?// 5.解析结果
? ?SearchHits searchHits = response.getHits();
? ?// 5.1.获取总条数
? ?long total = searchHits.getTotalHits().value;
? ?System.out.println("total = " + total);
? ?// 5.2.获取SearchHits数组,并遍历
? ?SearchHit[] hits = searchHits.getHits();
? ?for (SearchHit hit : hits) {
? ? ? ?// - 获取其中的`_source`,是JSON数据
? ? ? ?String json = hit.getSourceAsString();
? ? ? ?// - 把`_source`反序列化为User对象
? ? ? ?User user = JSON.parseObject(json, User.class);
? ? ? ?System.out.println("user = " + user);
? }
}
结果如下:
total = 5
user = User(id=2, name=李四, age=21, gender=男, note=李四同学在华为敲代码)
user = User(id=4, name=张伟, age=20, gender=男, note=张伟同学在交友软件谈恋爱)
user = User(id=5, name=李娜, age=28, gender=女, note=李娜同学在欢哥房间学画画)
user = User(id=8, name=柳岩, age=21, gender=女, note=柳岩同学在欢哥旁边唱歌)
user = User(id=10, name=范冰冰, age=25, gender=女, note=范冰冰同学在欢哥旁边表演)
本文暂时没有评论,来添加一个吧(●'◡'●)