项目介绍
本项目是一个由spring boot 3.0.2在gradle 8.4和java 21的环境下搭建的elasticsearch项目demo,这个项目是基于新版的Elasticsearch Java API 制作的,符合最新的框架要求,由于是运用了Elasticsearch新版的java jar包,所以在查询的时候使用了大量的Stream流式编程和闭包,亦可以作为流式编程的巩固。
导入项目
项目可以使用文章绑定的资源,或者去底部的GitHub地址下载
Elasticsearch Java API 查询文档
快速入门
我们以match_all查询为例
发起查询请求
代码解读:
上面的代码使用了流式编程的思想,首先选择用search表示是选择查询模式,然后用index决定搜索的索引库,然后用query构建查询索引,然后选择查询模式matchAll。
es中的查询语句
GET hotel/_search { "query": { "match_all": {} } }
解析响应
elasticsearch返回的结果是一个JSON字符串,结构包含:
hits
:命中的结果
total
:总条数,其中的value是具体的总条数值max_score
:所有结果中得分最高的文档的相关性算分hits
:搜索结果的文档数组,其中的每个文档都是一个json对象
source
:文档中的原始数据,也是json转化成实体类的对象
因此,我们解析响应结果,就是逐层解析JSON字符串,流程如下:
HitsMetadata
:通过response.hits()获取,就是JSON中的最外层的hits,代表命中的结果
HitsMetadata.total().value()
:获取总条数信息SearchHits#getHits()
:获取SearchHit数组,也就是文档数组
完整代码
完整代码如下:
@Test void testMatchAll() throws IOException { //进行查询 SearchResponse<HotelDoc> response = esClient.search(s -> s .index("hotel") .query(q -> q .matchAll(m->m)), HotelDoc.class ); handleResponse(response); } private void handleResponse( SearchResponse<HotelDoc> response) { HitsMetadata<HotelDoc> searchHits = response.hits(); // 4.1.总条数 long total = searchHits.total().value(); System.out.println("总条数:" + total); // 4.2.获取文档数组 List<Hit<HotelDoc>> hits = searchHits.hits(); // 4.3.遍历 hits.forEach(i->{ // 4.4 自动序列化 HotelDoc hotelDoc = i.source(); // 4.6.处理高亮结果 // 1)获取高亮字段和高亮数据的map Map<String, List<String>> map = i.highlight(); if (map!=null){ // 2)根据字段名,获取高亮结果 List<String> name = map.get("name"); if (name!=null){ // 3)获取高亮结果字符串数组中的第1个元素 String hName= name.get(0); // 4)把高亮结果放到HotelDoc中 hotelDoc.setName(hName); } } System.out.println(hotelDoc); // System.out.println(i.highlight()); }); }
match查询
全文检索的match和multi_match查询与match_all的API基本一致。差别是查询条件,也就是query的部分。
因此,Java代码上的差异主要是request.source().query()中的参数了。同样是利用QueryBuilders提供的方法:
而结果解析代码则完全一致,可以抽取并共享。
完整代码如下:
@Test void testMatch() throws IOException { SearchResponse<HotelDoc> response = esClient.search(i->i .index("hotel") .query(q->q.match(t->t .field("all")//设置请求字段 .query("如家")//设置请求参数 )), HotelDoc.class ); handleResponse(response); }
精确查询
精确查询主要是两者:
- term:词条精确匹配
- range:范围查询
与之前的查询相比,差异同样在查询条件,其它都一样。
es语句
GET /hotel/_search { "query": { "match": { "all": "如家" } } }
查询条件构造的API如下:
SearchResponse<HotelDoc> response = esClient.search(s -> s .index("hotel") .query(q->q. term(t->t .field("city") .value("上海"))),
elasticsearch 实战(二)https://developer.aliyun.com/article/1392076