Elasticsearch根据ID进行查询

实际工作中经常需要根据id查详情,常规的可以用query的方式实现,这里记录用 MultiGet 来实现的主要代码。

压测的初步感觉是 MultiGet 比用 query 更快,暂时还没有做严谨的对比。

1. 创建 client

// endpoints如: 127.0.0.1:9200,127.0.0.1:9201
public RestHighLevelClient client() {
    try {
        // 解析
        String[] ipAndPortList = endpoints.split(",");
        // 构造host
        HttpHost[] hosts = new HttpHost[ipAndPortList.length];
        for (int i = 0; i < ipAndPortList.length; i++) {
            // 解析
            String[] ipAndPort = ipAndPortList[i].split(":");
            // 获得ip
            String ip = ipAndPort[0];
            // 获得端口
            String port = ipAndPort[1];
            // 打印ip端口日志
            logger.info("ES节点 : ip {},端口 {}", ip, port);
            // 获取HttpHost实例
            hosts[i] = new HttpHost(ip, Integer.parseInt(port), "http");
        }

        // low builder
        RestClientBuilder builder = RestClient.builder(hosts);
        // 配置线程
        builder.setHttpClientConfigCallback(httpClientBuilder -> {
            // 设置最大连接数
            httpClientBuilder.setMaxConnTotal(200);
            // 设置每个route最大连接数
            httpClientBuilder.setMaxConnPerRoute(200);
            return httpClientBuilder;
        });

        // new client
        return new RestHighLevelClient(builder);
    } catch (Exception e) {
        // 打印异常
        logger.error("Create RestHighLevelClient failed.");
        // 此时返回空
        return null;
    }
}

2. multi-get 获取并解析数据

/**
 * multiGet 查询
 *
 * @param ids    多个id
 * @param tClass 类
 * @param index  索引
 */
public <T> PageEntity<T> multiGet(List<String> ids, Class<T> tClass, String index) throws IOException {
    // 参数非空校验
    if (esConfig.client() == null) {
        // 抛出不支持操作异常
        throw new UnsupportedOperationException();
    }
    // 构建 multi get
    MultiGetRequest request = new MultiGetRequest();
    // 为每个 id 构建查询语句
    for (String id : ids) {
        // 为 id 添加查询
        request.add(new MultiGetRequest.Item(index, id));
    }
    // 查询
    MultiGetResponse response = client().mget(request, RequestOptions.DEFAULT);
    // 结果解析
    return parseMultiGetResponse(response, tClass);
}

/**
 * multiGet 查询结果解析
 *
 * @param response 查询结果
 * @param tClass   T Class
 * @param <T>      T
 * @return total size + list of T
 */
private <T> PageEntity<T> parseMultiGetResponse(MultiGetResponse response, Class<T> tClass) {

    MultiGetItemResponse[] itemResponses = response.getResponses();
    // 结果解析
    List<T> retList = new ArrayList<>();
    // 解析
    for (MultiGetItemResponse itemResponse : itemResponses) {
        // 判断当前item获取是否成功
        if (itemResponse.getFailure() != null) {
            continue;
        }
        // 获取响应结果
        GetResponse getResponse = itemResponse.getResponse();
        // 判断结果是否存在
        if (getResponse.isExists()) {
            // 获得命中的信息
            String sourceAsString = getResponse.getSourceAsString();
            // 解析命中的信息
            T t = JSON.parseObject(sourceAsString, tClass);
            // 添加到结果集
            retList.add(t);
        }
    }
    // 返回结果容器
    PageEntity<T> pageEntity = new PageEntity<>();
    // 保存retList
    pageEntity.setResult(retList);
    // 保存总数
    pageEntity.setTotalSize((long) retList.size());
    // 返回结果
    return pageEntity;
}

其中,PageEntity的定义如下

@Data
public class PageEntity<T> {
    private List<T> result;
    private Long totalSize;
}

原文地址:https://www.cnblogs.com/betterwgo/p/12837034.html