赞
踩
该文章,主要是介绍elasticsearch7.x的rest java客户端。
参考文章:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/index.html
主要是利用restHighLevelClient进行封装的
阅读该文章的前提的,需要对es有所理解,推荐我之前写的文章:
https://blog.csdn.net/qq_34168515/article/details/108428406
https://blog.csdn.net/qq_34168515/article/details/108549851
定义一个request
IndexRequest request = new IndexRequest(索引名称);
request.id(文档id);
String jsonString = "{" +
"\"user\":\"kimchy\"," +
"\"postDate\":\"2013-01-30\"," +
"\"message\":\"trying out Elasticsearch\"" +
"}";
request.source(jsonString, XContentType.JSON);
执行request命令,分同步异步,一般使用同步
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
定义一个request
根据文档id进行删除
DeleteRequest request = new DeleteRequest(
索引名称,
文档id);
执行request命令
DeleteResponse deleteResponse = client.delete(request, RequestOptions.DEFAULT);
定义一个request
UpdateRequest request = new UpdateRequest(索引名称, 文档id);
String jsonString = "{" +
"\"updated\":\"2017-01-01\"," +
"\"reason\":\"daily update\"" +
"}";
request.doc(jsonString, XContentType.JSON);
执行request命令
UpdateResponse updateResponse = client.update(request, RequestOptions.DEFAULT);
查有非常多方式,elasticsearch作为一个开源搜索引擎,全文检索,结构化检索,数据分析,所以有很强大的搜索功能
定义一个request
SearchRequest searchRequest = new SearchRequest();
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
searchRequest.source(searchSourceBuilder);
同样具有分页功能
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.termQuery("user", "kimchy"));
sourceBuilder.from(0);
sourceBuilder.size(5);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
执行request命令
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
elasticsearch的版本要与客户端的版本一致
按照es官方文档描述elasticsearch-rest-client还需要依赖
The High Level Java REST Client depends on the following artifacts and their transitive dependencies:
org.elasticsearch.client:elasticsearch-rest-client
org.elasticsearch:elasticsearch
<properties> <java.version>1.8</java.version> <elasticsearch>7.5.1</elasticsearch> </properties> <dependencies> <!--SpringBoot整合Spring Data Elasticsearch的依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>${elasticsearch}</version> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-client</artifactId> <version>${elasticsearch}</version> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>${elasticsearch}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.62</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>1.8.3</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
下图整理出部分搜索相关的
参考大神文章:https://blog.csdn.net/weixin_42408648/article/details/108199320
单个匹配termQuery
//不分词查询 参数1: 字段名,参数2:字段查询值,因为不分词,所以汉字只能查询一个字,英语是一个单词.
QueryBuilder queryBuilder=QueryBuilders.termQuery("fieldName", "fieldlValue");
//分词查询,采用默认的分词器
QueryBuilder queryBuilder2 = QueryBuilders.matchQuery("fieldName", "fieldlValue");
多个匹配
//不分词查询,参数1: 字段名,参数2:多个字段查询值,因为不分词,所以汉字只能查询一个字,英语是一个单词.
QueryBuilder queryBuilder=QueryBuilders.termsQuery("fieldName", "fieldlValue1","fieldlValue2...");
//分词查询,采用默认的分词器
QueryBuilder queryBuilder= QueryBuilders.multiMatchQuery("fieldlValue", "fieldName1", "fieldName2", "fieldName3");
//匹配所有文件,相当于就没有设置查询条件
QueryBuilder queryBuilder=QueryBuilders.matchAllQuery();
//模糊查询常见的5个方法如下
//1.常用的字符串查询
QueryBuilders.queryStringQuery("fieldValue").field("fieldName");//左右模糊
//2.常用的用于推荐相似内容的查询
QueryBuilders.moreLikeThisQuery(new String[] {"fieldName"}).addLikeText("pipeidhua");//如果不指定filedName,则默认全部,常用在相似内容的推荐上
//3.前缀查询 如果字段没分词,就匹配整个字段前缀
QueryBuilders.prefixQuery("fieldName","fieldValue");
//4.fuzzy query:分词模糊查询,通过增加fuzziness模糊属性来查询,如能够匹配hotelName为tel前或后加一个字母的文档,fuzziness 的含义是检索的term 前后增加或减少n个单词的匹配查询
QueryBuilders.fuzzyQuery("hotelName", "tel").fuzziness(Fuzziness.ONE);
//5.wildcard query:通配符查询,支持* 任意字符串;?任意一个字符
QueryBuilders.wildcardQuery("fieldName","ctr*");//前面是fieldname,后面是带匹配字符的字符串
QueryBuilders.wildcardQuery("fieldName","c?r?");
//闭区间查询
QueryBuilder queryBuilder0 = QueryBuilders.rangeQuery("fieldName").from("fieldValue1").to("fieldValue2");
//开区间查询
QueryBuilder queryBuilder1 = QueryBuilders.rangeQuery("fieldName").from("fieldValue1").to("fieldValue2").includeUpper(false).includeLower(false);//默认是true,也就是包含
//大于
QueryBuilder queryBuilder2 = QueryBuilders.rangeQuery("fieldName").gt("fieldValue");
//大于等于
QueryBuilder queryBuilder3 = QueryBuilders.rangeQuery("fieldName").gte("fieldValue");
//小于
QueryBuilder queryBuilder4 = QueryBuilders.rangeQuery("fieldName").lt("fieldValue");
//小于等于
QueryBuilder queryBuilder5 = QueryBuilders.rangeQuery("fieldName").lte("fieldValue");
QueryBuilders.boolQuery()
QueryBuilders.boolQuery().must();//文档必须完全匹配条件,相当于and
QueryBuilders.boolQuery().mustNot();//文档必须不匹配条件,相当于not
QueryBuilders.boolQuery().should();//至少满足一个条件,这个文档就符合should,相当于or
采用spring对RestHighLevelClient进行初始化
@Configuration
public class ElasticsearchConfig {
@Bean
public RestHighLevelClient restHighLevelClient(){
RestHighLevelClient client=new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http")));
return client;
}
}
/** * es 的工具类 * * @author czchen * @version 1.0 * @date 2020/8/25 14:37 */ @Slf4j @Component public class EsUtil { @Autowired private RestHighLevelClient restHighLevelClient; /** * 关键字 */ public static final String KEYWORD = ".keyword"; /** * 创建索引 * * @param index 索引 * @return */ public boolean createIndex(String index) throws IOException { if(isIndexExist(index)){ log.error("Index is exits!"); return false; } //1.创建索引请求 CreateIndexRequest request = new CreateIndexRequest(index); //2.执行客户端请求 CreateIndexResponse response = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT); log.info("创建索引{}成功",index); return response.isAcknowledged(); } /** * 删除索引 * * @param index * @return */ public boolean deleteIndex(String index) throws IOException { if(!isIndexExist(index)) { log.error("Index is not exits!"); return false; } //删除索引请求 DeleteIndexRequest request = new DeleteIndexRequest(index); //执行客户端请求 AcknowledgedResponse delete = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT); log.info("删除索引{}成功",index); return delete.isAcknowledged(); } /** * 判断索引是否存在 * * @param index * @return */ public boolean isIndexExist(String index) throws IOException { GetIndexRequest request = new GetIndexRequest(index); boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT); return exists; } /** * 数据添加,正定ID * * @param jsonObject 要增加的数据 * @param index 索引,类似数据库 * @param id 数据ID, 为null时es随机生成 * @return */ public String addData(JSONObject jsonObject, String index, String id) throws IOException { //创建请求 IndexRequest request = new IndexRequest(index); //规则 put /test_index/_doc/1 request.id(id); request.timeout(TimeValue.timeValueSeconds(1)); //将数据放入请求 json IndexRequest source = request.source(jsonObject, XContentType.JSON); //客户端发送请求 IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT); log.info("添加数据成功 索引为: {}, response 状态: {}, id为: {}",index,response.status().getStatus(), response.getId()); return response.getId(); } /** * 数据添加 随机id * * @param jsonObject 要增加的数据 * @param index 索引,类似数据库 * @return */ public String addData(JSONObject jsonObject, String index) throws IOException { return addData(jsonObject, index, UUID.randomUUID().toString().replaceAll("-", "").toUpperCase()); } /** * 通过ID删除数据 * * @param index 索引,类似数据库 * @param id 数据ID */ public void deleteDataById(String index, String id) throws IOException { //删除请求 DeleteRequest request = new DeleteRequest(index, id); //执行客户端请求 DeleteResponse delete = restHighLevelClient.delete(request, RequestOptions.DEFAULT); log.info("索引为: {}, id为: {}删除数据成功",index, id); } /** * 通过ID 更新数据 * * @param object 要增加的数据 * @param index 索引,类似数据库 * @param id 数据ID * @return */ public void updateDataById(Object object, String index, String id) throws IOException { //更新请求 UpdateRequest update = new UpdateRequest(index, id); //保证数据实时更新 //update.setRefreshPolicy("wait_for"); update.timeout("1s"); update.doc(JSON.toJSONString(object), XContentType.JSON); //执行更新请求 UpdateResponse update1 = restHighLevelClient.update(update, RequestOptions.DEFAULT); log.info("索引为: {}, id为: {}, 更新数据成功",index, id); } /** * 通过ID 更新数据,保证实时性 * * @param object 要增加的数据 * @param index 索引,类似数据库 * @param id 数据ID * @return */ public void updateDataByIdNoRealTime(Object object, String index, String id) throws IOException { //更新请求 UpdateRequest update = new UpdateRequest(index, id); //保证数据实时更新 update.setRefreshPolicy("wait_for"); update.timeout("1s"); update.doc(JSON.toJSONString(object), XContentType.JSON); //执行更新请求 UpdateResponse update1 = restHighLevelClient.update(update, RequestOptions.DEFAULT); log.info("索引为: {}, id为: {}, 更新数据成功",index, id); } /** * 通过ID获取数据 * * @param index 索引,类似数据库 * @param id 数据ID * @param fields 需要显示的字段,逗号分隔(缺省为全部字段) * @return */ public Map<String,Object> searchDataById(String index, String id, String fields) throws IOException { GetRequest request = new GetRequest(index, id); if (StringUtils.isNotEmpty(fields)){ //只查询特定字段。如果需要查询所有字段则不设置该项。 request.fetchSourceContext(new FetchSourceContext(true,fields.split(","), Strings.EMPTY_ARRAY)); } GetResponse response = restHighLevelClient.get(request, RequestOptions.DEFAULT); Map<String, Object> map = response.getSource(); //为返回的数据添加id map.put("id",response.getId()); return map; } /** * 通过ID判断文档是否存在 * @param index 索引,类似数据库 * @param id 数据ID * @return */ public boolean existsById(String index,String id) throws IOException { GetRequest request = new GetRequest(index, id); //不获取返回的_source的上下文 request.fetchSourceContext(new FetchSourceContext(false)); request.storedFields("_none_"); return restHighLevelClient.exists(request, RequestOptions.DEFAULT); } /** * 获取低水平客户端 * @return */ public RestClient getLowLevelClient() { return restHighLevelClient.getLowLevelClient(); } /** * 高亮结果集 特殊处理 * map转对象 JSONObject.parseObject(JSONObject.toJSONString(map), Content.class) * @param searchResponse * @param highlightField */ public List<Map<String, Object>> setSearchResponse(SearchResponse searchResponse, String highlightField) { //解析结果 ArrayList<Map<String,Object>> list = new ArrayList<>(); for (SearchHit hit : searchResponse.getHits().getHits()) { Map<String, HighlightField> high = hit.getHighlightFields(); HighlightField title = high.get(highlightField); hit.getSourceAsMap().put("id", hit.getId()); Map<String, Object> sourceAsMap = hit.getSourceAsMap();//原来的结果 //解析高亮字段,将原来的字段换为高亮字段 if (title!=null){ Text[] texts = title.fragments(); String nTitle=""; for (Text text : texts) { nTitle+=text; } //替换 sourceAsMap.put(highlightField,nTitle); } list.add(sourceAsMap); } return list; } /** * 查询并分页 * @param index 索引名称 * @param query 查询条件 * @param size 文档大小限制 * @param from 从第几页开始 * @param fields 需要显示的字段,逗号分隔(缺省为全部字段) * @param sortField 排序字段 * @param highlightField 高亮字段 * @return */ public List<Map<String, Object>> searchListData(String index, SearchSourceBuilder query, Integer size, Integer from, String fields, String sortField, String highlightField) throws IOException { SearchRequest request = new SearchRequest(index); SearchSourceBuilder builder = query; if (StringUtils.isNotEmpty(fields)){ //只查询特定字段。如果需要查询所有字段则不设置该项。 builder.fetchSource(new FetchSourceContext(true,fields.split(","),Strings.EMPTY_ARRAY)); } from = from <= 0 ? 0 : from*size; //设置确定结果要从哪个索引开始搜索的from选项,默认为0 builder.from(from); builder.size(size); if (StringUtils.isNotEmpty(sortField)){ //排序字段,注意如果proposal_no是text类型会默认带有keyword性质,需要拼接.keyword builder.sort(sortField+".keyword", SortOrder.ASC); } //高亮 HighlightBuilder highlight = new HighlightBuilder(); highlight.field(highlightField); //关闭多个高亮 highlight.requireFieldMatch(false); highlight.preTags("<span style='color:red'>"); highlight.postTags("</span>"); builder.highlighter(highlight); //不返回源数据。只有条数之类的数据。 //builder.fetchSource(false); request.source(builder); SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT); log.error("=="+response.getHits().getTotalHits()); if (response.status().getStatus() == 200) { // 解析对象 return setSearchResponse(response, highlightField); } return null; } }
大部分的程序员,都是面向百度或者谷歌进行编程的,而网上的资料乱七八糟,有时候找起来让人难受,于是本人无偿进行资料收集的工作,大部分资料都是本人实打实收集的而且测试过,大家不用怀疑准确性,奈何能力有限,免于遗漏,希望读者可以在评论或者私信我,进行改正,大家一起为互联网技术做贡献。
收集资料枯燥无味,如果本文对你有帮助,可以点个赞,这个也是对我最大的鼓励和赞许。
本人行不改名坐不改姓,潮汕的灿灿展
立志在互联网这一行,做出自己的贡献
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。