优缺点

优点:
使用Transport 接口进行通信,能够使用ES集群中的一些特性,性能最好。
缺点:
JAR包版本需与ES集群版本一致,ES集群升级,客户端也跟着升级到相同版本。
ES 7.0 之后要逐步去掉

使用准备

maven依赖

<!-- ES -->
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>transport</artifactId>
    <version>5.6.4</version>
</dependency>
<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>5.6.4</version>
</dependency>
<!-- log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.17.0</version>
</dependency>

config.proerties

#es
es_ip=x.x.10.183
es_port=9300
es_cluster_name=my-application

初始化

import com.jfinal.kit.Prop;
import com.jfinal.kit.PropKit;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;

import java.io.File;
import java.net.InetAddress;
import java.net.UnknownHostException;

public enum EsClientEnum {
    INSTANCE;
    private TransportClient client;
    private EsClientEnum(){
        Prop prop = PropKit.use(new File("./conf/config.properties"),"gbk");
        String es_cluster_name = prop.get("es_cluster_name");
        String es_ip = prop.get("es_ip");
        Integer es_port = prop.getInt("es_port");
        System.out.println("es_cluster_name = " + es_cluster_name);

         //设置集群名称
        try {
            Settings settings = Settings.builder()
                    .put("cluster.name", es_cluster_name)
                      .put("client.transport.sniff", false) //启动嗅探功能,自动嗅探整个集群的状态,把集群中其他ES节点的ip添加到本地的客户端列表中
//                      .put("client.transport.ignore_cluster_name", true)//忽略集群名字验证, 打开后集群名字不对也能连接上
//                     .put("client.transport.nodes_sampler_interval", 5)//报错
//                     .put("client.transport.ping_timeout", 5) //报错, ping等待时间
                    .build();// 集群名
            //创建client
            client=  new PreBuiltTransportClient(settings)
                    .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(es_ip), es_port));
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

    public TransportClient getClient()  {
        return client;
    }
}

 crud使用封装


import org.apache.log4j.Logger;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;


public class ElasticSearchUtil {
private static final Logger logger = Logger.getLogger(ElasticSearchUtil.class);
    private static TransportClient client =EsClientEnum.INSTANCE.getClient();
    /**
     * 通过prepareIndex增加文档,参数为json字符串
     * @param index 索引名
     * @param type  类型
     * @param _id   数据id
     * @param json  数据
     */
    @SuppressWarnings("deprecation")
    public static void insertData(String index, String type, String _id, String json) {
        IndexResponse indexResponse = client.prepareIndex(index, type).setId(_id)
                .setSource(json)
                .get();
        System.out.println(indexResponse.getVersion());
        logger.info("数据插入ES成功!");
    }


    /**
     * 功能描述:更新数据
     * @param index 索引名
     * @param type  类型
     * @param _id   数据id
     * @param json  数据
     */
    @SuppressWarnings("deprecation")
    public static void updateData(String index, String type, String _id, String json){
        try {
            UpdateRequest updateRequest = new UpdateRequest(index, type, _id).doc(json);
//            client.prepareUpdate(index, type, _id).setDoc(json).get();
            client.update(updateRequest).get();
        } catch (Exception e) {
            logger.error("update data failed." + e.getMessage());
        }
    }

    /**
     * 功能描述:删除指定数据
     * @param index 索引名
     * @param type  类型
     * @param _id   数据id
     */
    public static void deleteData(String index, String type, String _id) {
        try {
            DeleteResponse response = client.prepareDelete(index, type, _id).get();
            System.out.println(response.isFragment());
            logger.info("删除指定数据成功!");
        } catch (Exception e) {
            logger.error("删除指定数据失败!" + e);
        }
    }

    /**
     * 功能描述:批量插入数据
     * @param index    索引名
     * @param type     类型
     * @param jsonList 批量数据
     */
    @SuppressWarnings("deprecation")
    public void bulkInsertData(String index, String type, List<String> jsonList) {
        BulkRequestBuilder bulkRequest = client.prepareBulk();
        jsonList.forEach(item -> {
            bulkRequest.add(client.prepareIndex(index, type).setSource(item));
        });
        BulkResponse bulkResponse = bulkRequest.get();
        if(!bulkResponse.hasFailures()) {
            System.out.println(bulkResponse.getItems().length + "条数据插入完成!");
        }
    }


    /**
     * 执行查询
     *
     * @param query 查询器
     * @return 当前查询对象
     */
    private static List<Map<String, Object>> executeQuery(QueryBuilder query, String indexName,int from , int size) {
        //搜索结果存入SearchResponse
        SearchResponse response = client.prepareSearch(indexName)
                .setQuery(query) //设置查询器
                .setFrom(from)  //开始位置
                .setSize(size)      //一次查询文档数
                .get();

        SearchHits hits = response.getHits();
        if (response.getHits() == null) {
            return null;
        }
        List<Map<String, Object>> resultList = new ArrayList<>();
        for (SearchHit hit : hits) {
            resultList.add(hit.getSourceAsMap());
        }
        return resultList;
    }

    /**
     * 功能描述:关闭链接
     */
    private static void close() {
        client.close();
    }
}

QueryBuilders

精确查询

精确,指的是查询关键字(或者关键字分词后),必须与目标分词结果完全匹配。
1.指定字符串作为关键词查询,关键词支持分词

//查询title字段中,包含 ”开发”、“开放" 这个字符串的document;相当于把"浦东开发开放"分词了,再查询;
QueryBuilders.queryStringQuery("开发开放").defaultField("title");
//不指定feild,查询范围为所有feild
QueryBuilders.queryStringQuery("青春");
//指定多个feild
QueryBuilders.queryStringQuery("青春").field("title").field("content");

2.以关键字“开发开放”,关键字不支持分词

QueryBuilders.termQuery("title", "开发开放")
QueryBuilders.termsQuery("fieldName", "fieldlValue1","fieldlValue2...")

3.以关键字“开发开放”,关键字支持分词

QueryBuilders.matchQuery("title", "开发开放")
QueryBuilders.multiMatchQuery("fieldlValue", "fieldName1", "fieldName2", "fieldName3")

模糊查询


模糊,是指查询关键字与目标关键字可以模糊匹配。
1.左右模糊查询,其中fuzziness的参数作用是在查询时,es动态的将查询关键词前后增加或者删除一个词,然后进行匹配

QueryBuilders.fuzzyQuery("title", "开发开放").fuzziness(Fuzziness.ONE)

2.前缀查询,查询title中以“开发开放”为前缀的document;

QueryBuilders.prefixQuery("title", "开发开放")

3.通配符查询,支持*和?,?表示单个字符;注意不建议将通配符作为前缀,否则导致查询很慢

QueryBuilders.wildcardQuery("title", "开*放")
QueryBuilders.wildcardQuery("title", "开?放")

注意
在分词的情况下,针对fuzzyQuery、prefixQuery、wildcardQuery不支持分词查询,即使有这种doucment数据,也不一定能查出来。

范围查询


QueryBuilders.rangeQuery("fieldName").from("fieldValue1").to("fieldValue2");
//开区间查询,默认是true,也就是包含
QueryBuilders.rangeQuery("fieldName").from("fieldValue1").to("fieldValue2")

.includeUpper(false).includeLower(false);
//大于
QueryBuilders.rangeQuery("fieldName").gt("fieldValue");
//大于等于
QueryBuilders.rangeQuery("fieldName").gte("fieldValue");
//小于
QueryBuilders.rangeQuery("fieldName").lt("fieldValue");
//小于等于
QueryBuilders.rangeQuery("fieldName").lte("fieldValue");
 

布尔查询

QueryBuilders.boolQuery()
QueryBuilders.boolQuery().must();//文档必须完全匹配条件,相当于and
QueryBuilders.boolQuery().mustNot();//文档必须不匹配条件,相当于not
QueryBuilders.boolQuery().should();//至少满足一个条件,这个文档就符合should,相当于or

 短语查询

PhraseQuery

由于精准/精确查询要求太严格,而关键词查询只是取决于包含与否,并不对term之间的位置有所要求,但是 对于 短语来说是有位置要求的,如 hello world这一短语,当进行 关键词搜索keywords = world hello,也会返回出来因为 关键词查询只进行包含判断,并不进行位置判断,那么在这种情况下 短语查询应运而生。

QueryBuilders.matchPhraseQuery("title","hello world");

PhrasePrefixQuery

PhrasePrefixQuery和PhraseQuery的区别

摘自ES官网:The match_phrase_prefix is the same as match_phrase, except that it allows for prefix matches on the last term in the text.

当搜索项为中文时,几乎无差别,当搜索英文时存在较大差异,比如quick brown fox,

当搜索 quick brown f时 addPhraseQuery不会返回结果,当进行addPhrasePrefixQuery 时会返回结果,因为会对最后一个 term 的前缀进行匹配;

QueryBuilders.matchPhrasePrefixQuery("title","hello world");

SearchResponse

EsPageUtil封装

额外依赖

<dependency>
    <groupId>com.github.miemiedev</groupId>
    <artifactId>mybatis-paginator</artifactId>
    <version>1.2.17</version>
</dependency>


import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import page.PageBounds;
import page.PageList;
import page.Paginator;

import java.util.ArrayList;
import java.util.List;
 
/**
 * @Description: Es 查询公用方法类
 * @Date:Created in 2018/11/12 0012
 */
public class EsPageUtil<E> {
 
	private Logger logger = LoggerFactory.getLogger(this.getClass());
 
	private Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
 
	/**
	 * 设置ES分页查询
	 *
	 * @param pageBounds    分页对象
	 * @param sourceBuilder 查询条件
	 */
	public static void setPageByPageBounds(PageBounds pageBounds, SearchSourceBuilder sourceBuilder) {
		int begin = (pageBounds.getPage() - 1) * pageBounds.getLimit();
		int end = begin + pageBounds.getLimit();
		//设置from确定结果索引的选项以开始搜索。默认为0。
		sourceBuilder.from(begin);
		//设置size确定要返回的搜索命中数的选项。默认为10。
		sourceBuilder.size(end);
	}
 
 
	/**
	 * 返回分页对象
	 *
	 * @param pageBounds 分页对象
	 * @param response   Es 查询结果
	 * @param clazz      clazz对象
	 * @return page list
	 */
	public PageList<E> getPageList(PageBounds pageBounds, SearchResponse response, Class<E> clazz) {
		logger.debug("es 查询结果:{}", response.toString());
		List<E> list = new ArrayList<>();
		SearchHit[] hits = response.getHits().getHits();
		for (SearchHit hit : hits) {
			E e = gson.fromJson(gson.toJson(hit.getSource()), clazz);
			list.add(e);
		}
		Paginator paginator = new Paginator(pageBounds.getPage(), pageBounds.getLimit(), (int) response.getHits().getTotalHits());
		return new PageList<>(list, paginator);
	}
 
	/**
	 * @Description: 返回查询列表
	 * @param response
	 * @param clazz
	 * @return List<E>
	 * @throws
	 */
	public List<E> getList(SearchResponse response, Class<E> clazz) {
		logger.debug("es 查询结果:{}", response.toString());
		List<E> list = new ArrayList<>();
		SearchHit[] hits = response.getHits().getHits();
		for (SearchHit hit : hits) {
			E e = gson.fromJson(gson.toJson(hit.getSource()), clazz);
			list.add(e);
		}
		return list;
	}
 
}

EsPageUtil使用

    @Test
    public void pageTest(){
        int page=3;
        int pageSize=2;
        PageBounds pageBounds=new PageBounds(page,pageSize);
        EsPageUtil<Article> esUtil=new EsPageUtil<Article>();

        BoolQueryBuilder boolQueryBuilder= QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.matchAllQuery());

        SearchResponse response= EsClientEnum.INSTANCE.getClient().prepareSearch("article").setTypes("article")
                .setQuery(boolQueryBuilder)
                .addSort("id", SortOrder.ASC)
//                .setFrom((page-1)*pageSize).setSize(pageSize)
                .setFrom(pageBounds.getOffset()).setSize(pageBounds.getLimit())
                .setExplain(true)
                .get();

        PageList<Article> pageList = esUtil.getPageList(pageBounds, response, Article.class);

        Paginator paginator = pageList.getPaginator(); //可以获得page limit totalCount
        System.out.println("---------------------------");

    }

结果高亮

import com.wg.utils.EsClientEnum;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.Test;

import java.util.Map;

public class HighLightTest {

    @Test
    public void testHigh(){
        HighlightBuilder highlightBuilder = getHighlightBuilder("title");
        SearchResponse searchResponse = EsClientEnum.INSTANCE.getClient().prepareSearch("article").setTypes("article")
                .setQuery(QueryBuilders.matchQuery("title", "title"))
                .addSort("id", SortOrder.ASC)
                .highlighter(highlightBuilder)
                .get();

        SearchHits hits = searchResponse.getHits();
        for (SearchHit hit : hits) {
            String title = replaceAttr(hit, "title");
            System.out.println("title = " + title);
        }
    }



    private HighlightBuilder getHighlightBuilder(String field){
        //配置标题高亮显示

        HighlightBuilder highlightBuilder = new HighlightBuilder(); //生成高亮查询器
        highlightBuilder.field(field);      //高亮查询字段
//        highlightBuilder.field(content);    //高亮查询字段
        highlightBuilder.requireFieldMatch(false);     //如果要多个字段高亮,这项要为false
        highlightBuilder.preTags("<span style=\"color:red\">");   //高亮设置
        highlightBuilder.postTags("</span>");

        //下面这两项,如果你要高亮如文字内容等有很多字的字段,必须配置,不然会导致高亮不全,文章内容缺失等
        highlightBuilder.fragmentSize(800000); //最大高亮分片数
        highlightBuilder.numOfFragments(0); //从第一个分片获取高亮片段
        return highlightBuilder;
    }

    /**
     * 替换高亮属性
     *
     * @param searchHit 查询结果
     * @return
     */
    private String replaceAttr(SearchHit searchHit, String attr)   {

        Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
        HighlightField hField = highlightFields.get(attr);
        if (hField != null) {
            //替换高亮字段
            Text[] fragments = hField.fragments();
            StringBuilder text = new StringBuilder();
            for (Text textGet : fragments) {
                text.append(textGet);
            }
            return text.toString();

        }
        return null;
    }

}

深度分页scroll


    /**
     * 使用Scroll方法分页
     */
    @Test
    public void queryPageScroll(){

        QueryBuilder qb = QueryBuilders.matchAllQuery();

        TransportClient client = EsClientEnum.INSTANCE.getClient();
        SearchResponse scrollResp = client.prepareSearch("article")
//                .addSort(FieldSortBuilder.DOC_FIELD_NAME, SortOrder.ASC)
                .addSort("id", SortOrder.ASC)
                .setScroll(new TimeValue(60000))
                .setQuery(qb)
                .setSize(1).get();
        do {
            for (SearchHit hit : scrollResp.getHits().getHits()) {
                println(hit);
            }
            scrollResp = client.prepareSearchScroll(scrollResp.getScrollId()).setScroll(new TimeValue(60000)).execute().actionGet();
        } while(scrollResp.getHits().getHits().length != 0);
    }

    /**
     * 输出结果SearchResponse
     * @param
     */
    public static void println(SearchHit searchHit){
        System.err.println("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-");
        System.err.println(
                "docId : " + searchHit.docId() + "\n" +
                        "getId : " + searchHit.getId() + "\n" +
                        "getIndex : " + searchHit.getIndex()+ "\n" +
                        "getScore : " + searchHit.getScore() + "\n" +
                        "getSourceAsString : " + searchHit.getSourceAsString() + "\n" +
                        "getType : " + searchHit.getType() + "\n" +
                        "getVersion : " + searchHit.getVersion() + "\n" +
                        "fieldsOrNull : " + searchHit.fieldsOrNull() + "\n" +
                        "getExplanation : " + searchHit.getExplanation() + "\n" +
                        "getFields : " + searchHit.getFields() + "\n" +
                        "highlightFields : " + searchHit.highlightFields() + "\n" +
                        "hasSource : " + searchHit.hasSource()
        );
    }

aggregation

多重聚合封装

import com.wg.utils.EsClientEnum;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.avg.InternalAvg;
import org.elasticsearch.search.aggregations.metrics.cardinality.InternalCardinality;
import org.elasticsearch.search.aggregations.metrics.max.InternalMax;
import org.elasticsearch.search.aggregations.metrics.min.InternalMin;
import org.elasticsearch.search.aggregations.metrics.sum.Sum;
import org.elasticsearch.search.aggregations.metrics.valuecount.InternalValueCount;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

public class AggUtil {
    private ArrayList<Object> results(SearchResponse agg){
        Map<String, Aggregation> aggregations = agg.getAggregations().asMap();


        ArrayList<Object> objects = new ArrayList<>();
        for (Map.Entry<String, Aggregation> entry:aggregations.entrySet()
        ) {

            String key = entry.getKey();
            Aggregation value = entry.getValue();
            HashMap<String, Object> group = new HashMap<>();
            parseAggs(value,group,key,objects);
        }
        return objects;
    }



    //解析聚合结果
    private ArrayList<Object> parseAggs(Aggregation agg, HashMap<String, Object> group,String field,ArrayList<Object> objects){

        if (agg instanceof Terms){
            for (Terms.Bucket bucket:((Terms) agg).getBuckets() ){

                String keyAsString = bucket.getKeyAsString();
                group.put(field,keyAsString);

                for (Map.Entry<String, Aggregation> entry :bucket.getAggregations().asMap().entrySet()
                ) {
                    String key = entry.getKey();
                    Aggregation value = entry.getValue();

                    if (value instanceof Terms){
                        parseAggs(value,group,key,objects);
                    }else {
                        LinkedHashMap<String, Object> map = package2map(bucket);
                        map.putAll(group);
                        objects.add(map);
                        break;
                    }
                }
            }
        }

        return objects;

    }


    private  LinkedHashMap<String, Object> package2map(Terms.Bucket bucket){
        LinkedHashMap<String, Object> map = new LinkedHashMap<>();

        for (Map.Entry<String, Aggregation> entry :bucket.getAggregations().asMap().entrySet()
        ) {
            String key = entry.getKey();
            Aggregation value = entry.getValue();

            map.put(key,getvalue(value));
        }
        return map;
    }


    //取值
    public String getvalue(Aggregation agg){
        String type = agg.getType();


        String result="";
        switch (type){
            case "avg":
                result=String.valueOf(((InternalAvg) agg).getValue());
                break;
            case "sum":
                result=String.valueOf(((Sum) agg).getValue());
                break;
            case "value_count":
                result=String.valueOf(((InternalValueCount) agg).getValue());
                break;
            case "min":
                result=String.valueOf(((InternalMin) agg).getValue());
                break;
            case "max":
                result=String.valueOf(((InternalMax) agg).getValue());
                break;
            case "cardinality":
                result=String.valueOf(((InternalCardinality) agg).getValue());
                break;
            default:
                result=String.valueOf(agg);
                break;

        }
        return result;
    }

    private void getAggsResult(TransportClient client){
        SearchResponse agg = client.prepareSearch("hisms_sz")
                .setTypes("cz")
                .addAggregation(
                        AggregationBuilders.terms("id_mdc").field("id_mdc").size(26)//设置聚合条件 group by id_mdc,id_drg
                                .subAggregation(
                                        AggregationBuilders.terms("name_drg").field("name_drg").size(700)
                                                .subAggregation(AggregationBuilders.avg("avg").field("yka055"))// 聚合结果 avg(date
                                                .subAggregation(AggregationBuilders.sum("sum").field("yka055"))
                                                .subAggregation(AggregationBuilders.min("min").field("yka055"))
                                                .subAggregation(AggregationBuilders.count("count").field("aac003"))
                                                .subAggregation(AggregationBuilders.cardinality("cardinality").field("aac003"))
                                )
                )
                .execute().actionGet();
        ArrayList<Object> results = results(agg);
        System.out.println(results.size());
    }


    public static void main(String[] args) {
        TransportClient client = EsClientEnum.INSTANCE.getClient();
        QueryBuilder queryBuilder = QueryBuilders.rangeQuery("id").from(0).to(2);
        // select count(1) from article group by site,author
        SearchResponse searchResponse = client.prepareSearch("article").setTypes("article")
        .setQuery(queryBuilder)
                .addAggregation(
                        AggregationBuilders.terms("site").field("site").size(50)
                                .subAggregation(
                                        AggregationBuilders.terms("author").field("author").size(700)
                                            .subAggregation( AggregationBuilders.count("num").field("site"))
                                )
                )
                .execute().actionGet();

        AggUtil aggUtil = new AggUtil();
        ArrayList<Object> results = aggUtil.results(searchResponse);
        for (Object result : results) {
            System.out.println(result);
        }

    }
}

Histogram aggregation

 @Test
    public void hisGramTest(){
        DateHistogramAggregationBuilder aggBuild = AggregationBuilders
                .dateHistogram("agg")
                .field("time")
                .format("yyyy-MM-dd HH:mm:ss")
                .dateHistogramInterval(DateHistogramInterval.DAY);

        TransportClient client = EsClientEnum.INSTANCE.getClient();
        SearchResponse sc = client.prepareSearch("article").setTypes("article")
                .addAggregation(aggBuild).get();

        Histogram agg = sc.getAggregations().get("agg");

            // For each entry
        for (Histogram.Bucket entry : agg.getBuckets()) {
            String keyAsString = entry.getKeyAsString(); // Key as String
            long docCount = entry.getDocCount();         // Doc count
            System.out.println(keyAsString+"::::"+docCount);
        }
        System.out.println("-------------------");
    }

来源

Elasticsearch系列(五)----JAVA客户端之TransportClient操作详解_yinni11的博客-CSDN博客_java transportclient

elasticsearch(六)调用TransportClient查询结果处理_胡易卿的博客-CSDN博客_transportclient 查询 Elasticsearch(Transport Client)常用操作_含江君的博客-CSDN博客_elasticsearch transportclient

ES封装工具类简单增删改查 - 简书

Bucket aggregations | Java API [5.5] | Elastic

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐