Elasticsearch全文检索企业开发记录总结(二):ES客户端搭建

项目依赖

   <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>transport</artifactId>
        <version>5.4.0</version>
    </dependency>

<dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-to-slf4j</artifactId>
        <version>2.8.2</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.24</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>1.7.21</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.6.1</version>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.6.1</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.7</version>
    </dependency>

配置ES集群节点

public class EsConfig {
    /**
     * Es集群名称
     */
    public static final String ES_CLUSTER_NAME = SystemConfig.get("es.cluster.name");

    /**
     * 已经解析的端口和地址
     */
    public static List<URL> es_cluster_urls = loadUrls();

    public static List<URL> loadUrls() {
        String urls = SystemConfig.get("es.cluster.url");
        if (!StringUtils.hasLength(urls)) {
            throw new IllegalStateException("Es cluster urls must not be empty.");
        }
        List<URL> ups = new LinkedList<>();
        String[] urlArray = urls.split(",");
        for (String up : urlArray) {
            String url = up.split(":")[0];
            String port = up.split(":")[1];
            ups.add(new URL(url, Integer.parseInt(port)));
        }
        return ups;
    }

    public static class URL {
        private String url;
        private int port;

        public URL() {
        }

        public URL(String url, int port) {
            this.port = port;
            this.url = url;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }

        public int getPort() {
            return port;
        }

        public void setPort(int port) {
            this.port = port;
        }
    }
}

ES客户端单例创建

public class ESClient {
    private static Logger log = LoggerFactory.getLogger(ESClient.class);
    private static ESClient instance = new ESClient();
    private static TransportClient client;

    private ESClient() {
        newTransportClient();
    }

    public static ESClient instance() {
        return instance;
    }

    public TransportClient getTransportClient() {
        // client创建完成后,如果es连接失败将会自动重连
        if (client == null/* || client.connectedNodes().isEmpty()*/) {
            newTransportClient();
        }
        return client;
    }

    private void newTransportClient() {
        Settings settings = Settings.EMPTY;
        if (StringUtils.hasLength(EsConfig.ES_CLUSTER_NAME))
            settings = Settings.builder().put("cluster.name", EsConfig.ES_CLUSTER_NAME).build();
        client = new PreBuiltTransportClient(settings);
        if (EsConfig.es_cluster_urls.size() == 0) {
            throw new NoNodeAvailableException("There is no available node be defined, please check you cluster url configuration.");
        }
        EsConfig.es_cluster_urls.forEach(url -> {
            try {
                client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(url.getUrl()), url.getPort()));
            } catch (UnknownHostException e) {
                log.error("Es cluster configuration throw UnkownHostException : ", e);
            }
        });
    }

    public void closeClient() {
        instance().getTransportClient().close();
    }
}

ES客户端的增删改查接口

public interface ESService {
    /**
     * 创建索引。
     * <p>
     * 路由如果为空,则不设置路由。
     *
     * @param index       索引名称
     * @param type        类型名称
     * @param id          id
     * @param jsonContent 索引内容
     * @param parent      关联父级的字段
     * @param routing     路由
     * @return 索引结果对象
     */
    IndexResponse index(String index, String type, String id, String jsonContent, String parent, String routing);

    /**
     * 创建索引。
     *
     * @param index       索引名称
     * @param type        类型名称
     * @param id          id
     * @param jsonContent 索引内容
     * @return 索引结果对象
     */
    IndexResponse index(String index, String type, String id, String jsonContent);

    /**
     * 批量创建索引。
     *
     * @param index    索引名称,不能为空
     * @param type     索引类型,不能为空
     * @param ids      索引id列表,必须与索引内容列表一一对应
     * @param contents 索引内容列表,必须与索引id列表一一对应
     * @param parent   父级ID
     * @param routing  路由
     * @return 批量操作结果
     */
    BulkResponse bulkIndex(String index, String type, List<String> ids, List<String> contents, String parent, String routing);

    /**
     * 根据id查询。
     *
     * @param index 索引名称
     * @param type  类型名称
     * @param id    id
     * @return 结果对象
     */
    GetResponse get(String index, String type, String id);

    /**
     * 根据id查询,如果<code>routing</code>为null,则不设置路由。
     *
     * @param index   索引名称
     * @param type    类型名称
     * @param id      id
     * @param parent  父级
     * @param routing 路由
     * @return 结果对象
     */
    GetResponse get(String index, String type, String id, String parent, String routing);

    /**
     * 批量查询。
     *
     * @param index 索引名称
     * @param type  类型名称
     * @param ids   批量查询的id数组
     * @return 结果对象
     */
    MultiGetResponse multiGet(String index, String type, String[] ids);

    /**
     * 更新。
     *
     * @param index       索引名称
     * @param type        类型名称
     * @param id          id
     * @param jsonContent 更新内容
     * @param create      不存在时是否创建,true - 创建, false - 不创建(默认值)
     * @return 结果对象
     * @throws ExecutionException
     * @throws InterruptedException
     */
    UpdateResponse update(String index, String type, String id, String jsonContent, boolean create) throws ExecutionException, InterruptedException;

    /**
     * 更新。
     * <p>
     * 如果<code>routing</code>为null,则不设置路由。
     *
     * @param index       索引名称
     * @param type        类型名称
     * @param id          id
     * @param jsonContent 更新内容
     * @param parent      父级
     * @param routing     路由
     * @param create      不存在时是否创建,true - 创建, false - 不创建(默认值)
     * @return 结果对象
     * @throws ExecutionException
     * @throws InterruptedException
     */
    UpdateResponse update(String index, String type, String id, String jsonContent, String parent, String routing, boolean create) throws ExecutionException, InterruptedException;

    /**
     * 批量更新。
     * <p>
     * 如果<code>routing</code>为null,则不设置路由。
     * <p>
     * 如果文档不存在,会自动创建文档。如果不希望创建文档,可以参见带create参数的bulkUpdate方法。
     *
     * @param index    索引名称
     * @param type     类型名称
     * @param contents 更新内容
     * @param ids      更新的id列表
     * @param parent   父级
     * @param routing  路由
     * @return 结果对象
     */
    BulkResponse bulkUpdate(String index, String type, List<String> ids, List<String> contents, String parent, String routing);

    /**
     * 批量更新。
     * <p>
     * 如果<code>routing</code>为null,则不设置路由。
     *
     * @param index    索引名称
     * @param type     类型名称
     * @param contents 更新内容
     * @param ids      更新的id列表
     * @param parent   父级
     * @param routing  路由
     * @param create   不存在,则创建文档。默认false
     * @return 结果对象
     */
    BulkResponse bulkUpdate(String index, String type, List<String> ids, List<String> contents, String parent, String routing, boolean create);

    /**
     * 删除。
     * <p>
     * 如果<code>routing</code>为null,则不设置路由。
     *
     * @param index 索引名称
     * @param type  类型名称
     * @param id    id
     * @return 删除结果
     */
    DeleteResponse delete(String index, String type, String id);

    /**
     * 删除。
     *
     * @param index   索引名称
     * @param type    类型名称
     * @param id      id
     * @param routing 路由
     * @param parent  关联父级
     * @return 删除结果
     */
    DeleteResponse delete(String index, String type, String id, String parent, String routing);

    /**
     * 批量删除。
     *
     * @param index 索引名称
     * @param type  类型名称
     * @param ids   被删除的id列表
     * @return 删除结果
     */
    BulkResponse bulkDelete(String index, String type, List<String> ids);

    /**
     * 带父id和路由的批量删除。
     *
     * @param index   索引名称
     * @param type    类型名称
     * @param ids     id列表
     * @param parent  父id
     * @param routing 路由
     * @return 删除结果
     */
    BulkResponse bulkDelete(String index, String type, List<String> ids, String parent, String routing);

    /**
     * 搜索。
     *
     * @param index               索引名称
     * @param type                类型名称
     * @param searchSourceBuilder 设置好的结果字段过滤器
     * @param query               设置好的查询构建器
     * @param postFlter           设置好的查询过滤器
     * @param from                开始位置,从0开始
     * @param size                查询数量,默认为10
     * @param aggregationBuilders 基于查询的聚合构建器
     * @return 搜索结果
     */
    SearchResponse search(String index, String type,
                          SearchSourceBuilder searchSourceBuilder,
                          QueryBuilder query, QueryBuilder postFlter,
                          Integer from, Integer size,
                          AggregationBuilder[] aggregationBuilders,
                          SortBuilder[] sortBuilders);
}

接口实现参照ES官网JAVA API的文档编写即可,search方法实现如下:

@Override
    public SearchResponse search(String index, String type,
                                 SearchSourceBuilder searchSourceBuilder,
                                 QueryBuilder query, QueryBuilder postFlter,
                                 Integer from, Integer size,
                                 AggregationBuilder[] aggregationBuilders,
                                 SortBuilder[] sortBuilders) {
        if (!StringUtils.hasLength(index))
            throw new IllegalArgumentException("Index name must not be null.");
        SearchRequestBuilder requestBuilder = getClient().prepareSearch(index);
        if (StringUtils.hasLength(type))
            requestBuilder.setTypes(type);
        if (searchSourceBuilder != null)
            requestBuilder.setSource(searchSourceBuilder);
        if (query != null)
            requestBuilder.setQuery(query);
        if (postFlter != null)
            requestBuilder.setPostFilter(postFlter);
        if (from == null)
            from = 0;
        if (size == null) // 默认为10,如果传入0表示不显示命中结果
            size = 10;
        requestBuilder.setFrom(from).setSize(size);
        requestBuilder.setSearchType(SearchType.QUERY_THEN_FETCH);
        // 聚合
        if (aggregationBuilders != null && aggregationBuilders.length > 0) {
            for (AggregationBuilder aggregationBuilder : aggregationBuilders) {
                requestBuilder.addAggregation(aggregationBuilder);
            }
        }
        // 排序
        if (sortBuilders != null && sortBuilders.length > 0) {
            for (SortBuilder sortBuilder : sortBuilders) {
                requestBuilder.addSort(sortBuilder);
            }
        }
        // 非格式化输出,日志就打印一行
        Map<String, String> params = new HashMap<>();
        params.put("pretty", "false");
        ToXContent.MapParams mapParams = new ToXContent.MapParams(params);
        log.info("===================== Searching params ===================== ");
        log.info("index : " + index + ", type : " + type + ", from : " + from + ", size : " + size);
        log.info("request : " + requestBuilder.request().source().toString(mapParams));
        return requestBuilder.get();
    }

至此,ES提供的JAVA API的底层操作已经编写完毕,供业务层调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值