spring boot + Java High Level REST Client7.3操作Es文档

ES文档数据的新增、更新、删除、批量导入、分页查询、查询结果聚合功能

新增索引后默认的文档名称是_doc

1、新增文档数据

创建新增文档请求,设置数据内容,然后在设置一些可选参数,最后异步执行该请求

/**
 * 新增单条文档数据
 *
 * @param indexName 索引名称
 * @param id
 * @throws Exception
 */
public void createDocument(String indexName, String id) throws Exception {
    RestHighLevelClient client = this.getEsClient();
    // 指定单条文档数据,最终会转化成Json格式
    XContentBuilder builder = XContentFactory.jsonBuilder();
    builder.startObject();
    {
        builder.field("name", "张三");
        builder.field("age", 12);
        builder.field("email", "email123");
    }
    builder.endObject();
    // 创建新增文档数据的请求
    IndexRequest indexRequest = new IndexRequest(indexName).id(id).source(builder);
    // 手动指定路由的key,文档查询时可提高性能
    indexRequest.routing("userInfo");
    // 等待主分片保存的超时时长
    indexRequest.timeout(TimeValue.timeValueSeconds(1));
    // 刷新策略,WAIT_UNTIL设置则表示刷新使此请求的内容对搜索可见为止
    indexRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
    // 操作类型为新增
    indexRequest.opType(DocWriteRequest.OpType.CREATE);

    // 异步执行新增文档数据请求
    client.indexAsync(indexRequest, RequestOptions.DEFAULT, new ActionListener<IndexResponse>() {
        @Override
        public void onResponse(IndexResponse indexResponse) {
            System.out.println(indexResponse.toString());
        }

        @Override
        public void onFailure(Exception e) {
            e.printStackTrace();
        }
    });
}
2、更新文档数据

部分文档内容更新,Es采用乐观锁机制,每更新一次Version值加1

/**
 * 更新文档内容
 *
 * @param indexName 索引名称
 * @param id
 */
public void updateDocument(String indexName, String id) throws Exception {
    RestHighLevelClient client = this.getEsClient();
    // 更新部分文档内容
    Map<String, Object> jsonMap = new HashMap<>();
    jsonMap.put("age", 25);
    jsonMap.put("email", "email2020");

    // 创建更新文档请求并设置参数
    UpdateRequest updateRequest = new UpdateRequest(indexName, id);
    updateRequest.doc(jsonMap);
    // 主分片执行更新的超时时长
    updateRequest.timeout(TimeValue.timeValueSeconds(1));
    // 刷新策略
    updateRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
    // 重试更新操作多少次
    updateRequest.retryOnConflict(3);

    // 异步执行更新文档的请求
    client.updateAsync(updateRequest, RequestOptions.DEFAULT, new ActionListener<UpdateResponse>() {
        @Override
        public void onResponse(UpdateResponse updateResponse) {
            System.out.println(updateResponse);
        }

        @Override
        public void onFailure(Exception e) {
            e.printStackTrace();
        }
    });
}
3、删除文档
/**
 * 删除文档数据
 *
 * @param indexName 索引名称
 * @param id
 * @throws Exception
 */
public void deleteDocument(String indexName, String id) throws Exception {
    RestHighLevelClient client = this.getEsClient();
    DeleteRequest deleteRequest = new DeleteRequest(indexName, id);
    // 主分片执行删除的超时时长
    deleteRequest.timeout(TimeValue.timeValueMinutes(2));
    // 刷新策略
    deleteRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
    // 异步执行删除
    client.deleteAsync(deleteRequest, RequestOptions.DEFAULT, new ActionListener<DeleteResponse>() {
        @Override
        public void onResponse(DeleteResponse deleteResponse) {
            System.out.println("删除成功:" + deleteResponse.toString());
        }

        @Override
        public void onFailure(Exception e) {
            System.out.println("删除失败:" + e.getMessage());
        }
    });
}
4、批量导入文档数据

BulkRequest支持批量删除、更新、新增数据

/**
 * 文档数据量插入
 *
 * @param mapList   行数据
 * @param indexName 索引
 * @param idName    主键名称
 * @return
 * @throws Exception
 */
public void importDocument(List<Map> mapList, String indexName, String idName) {
    IndexRequest indexRequest = null;
    BulkRequest bulkRequest = new BulkRequest();
    RestHighLevelClient restHighLevelClient = null;
    try {
        restHighLevelClient = this.getEsClient();
        for (Map mp : mapList) {
            indexRequest = new IndexRequest(indexName).id(mp.get(idName).toString()).source(mp);
            bulkRequest.add(indexRequest);
        }
        BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        System.out.println(bulkResponse.toString());
    } catch (Exception ex) {
        ex.printStackTrace();
    } finally {
        try {
            restHighLevelClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
5、查询文档数据

实现了精确匹配查询、模糊匹配查询、组合条件查询、分页、自定义返回列的功能,值得注意的是精确匹配查询时字段名称需要拼接.keyword才能正确执行

/**
 * 检索、分页
 *
 * @param indexName    索引名称
 * @param mpParams     查询参数
 * @param from         起始页
 * @param size         每页数量
 * @param fieldArray   返回列数组
 * @param preciseQuery 1:精确查询 2:模糊查询
 * @return
 */
public List<Map<String, Object>> searchDocument(String indexName, Map<String, Object> mpParams,
                                                int from, int size, String[] fieldArray, Integer preciseQuery) {
    RestHighLevelClient restHighLevelClient = null;
    SearchRequest searchRequest = new SearchRequest(indexName);
    // 大多数搜索参数添加到searchSourceBuilder
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    List<Map<String, Object>> mapList = new ArrayList<>();
    try {
        restHighLevelClient = this.getEsClient();
        // 组合字段查询
        BoolQueryBuilder boolQueryBuilder = this.getBoolQueryBuilder(mpParams, preciseQuery);
        searchSourceBuilder.query(boolQueryBuilder);
        // 自定义返回列
        if (fieldArray != null && fieldArray.length > 0) {
            searchSourceBuilder.fetchSource(fieldArray, null);
        }
        // 按照Id倒序
        searchSourceBuilder.sort(new FieldSortBuilder("id").order(SortOrder.DESC));
        // 分页
        searchSourceBuilder.from(from);
        searchSourceBuilder.size(size);
        // 允许搜索的超时时长
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        // 返回结果
        SearchHits searchHitArray = searchResponse.getHits();
        for (SearchHit searchHit : searchHitArray.getHits()) {
            Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
            mapList.add(sourceAsMap);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            restHighLevelClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return mapList;
}

/**
 * 组合字段查询条件
 *
 * @param mpParams
 * @param preciseQuery 1:精确查询 2:模糊查询
 * @return
 */
public BoolQueryBuilder getBoolQueryBuilder(Map<String, Object> mpParams, Integer preciseQuery) {
    BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    try {
        if (mpParams != null) {
            for (Map.Entry<String, Object> entry : mpParams.entrySet()) {
                if (preciseQuery != null && preciseQuery == 1) {
                    // 精确匹配
                    TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(entry.getKey() + ".keyword", entry.getValue());
                    boolQueryBuilder = boolQueryBuilder.must(termQueryBuilder);
                } else {
                    // 模糊匹配
                    MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(entry.getKey(), entry.getValue());
                    boolQueryBuilder = boolQueryBuilder.must(matchQueryBuilder);
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return boolQueryBuilder;
}
6、查询文档结果聚合

需要聚合的字段类型必须是keyword类型的

/**
 * 查询结果聚合
 *
 * @param mpParams     查询参数
 * @param indexName    索引名称
 * @param fieldName    字段名称
 * @param preciseQuery 1:精确查询 2:模糊查询
 * @return
 */
public Map<String, Object> searchAggregationDocument(Map<String, Object> mpParams, String indexName,
                                                     String fieldName, Integer preciseQuery) {
    Map<String, Object> mpResult = new HashMap<>();
    RestHighLevelClient restHighLevelClient = null;
    SearchResponse searchResponse = null;
    try {
        restHighLevelClient = this.getEsClient();
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 指定要聚合的字段,类似数据库的group by
        TermsAggregationBuilder aggregation = AggregationBuilders.terms(fieldName).field(fieldName);
        searchSourceBuilder.aggregation(aggregation);
        // 组合字段查询
        BoolQueryBuilder boolQueryBuilder = this.getBoolQueryBuilder(mpParams, preciseQuery);
        searchSourceBuilder.query(boolQueryBuilder);
        // 执行查询请求
        SearchRequest searchRequest = new SearchRequest(indexName);
        searchRequest.source(searchSourceBuilder);
        searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        // 汇总聚合结果
        Aggregations aggregations = searchResponse.getAggregations();
        Terms byCompanyAggregation = aggregations.get(fieldName);
        if (byCompanyAggregation != null) {
            List<Terms.Bucket> bucketList = (List<Terms.Bucket>) byCompanyAggregation.getBuckets();
            for (Terms.Bucket bucket : bucketList) {
                String key = bucket.getKeyAsString();
                Long value = bucket.getDocCount();
                mpResult.put(key, value);
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            restHighLevelClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return mpResult;
}

以上就是关于关于Es文档的新增、删除、更新、批量导入、分页查询、聚合查询功能

你可能感兴趣的:(spring,boot)