目录

  • Elasticsearch与springboot整合的方式
    • 原生客户端
    • REST
    • Jest
    • Spring Data
      • Spring Data的配置
      • Spring Data的使用
        • 插入或修改数据
        • 删除数据
        • 全量查询
        • 判断文档是否存在
        • 结构化查询
          • term查询
          • range查询
          • exists查询
          • match查询
          • bool查询
        • 自定义方法
        • 聚合操作
          • 平均、最大、最小、求和
          • 去重
          • 扩展查询
          • terms词聚合
          • top_hits最高匹配权值聚合
          • 综合查询

Elasticsearch与springboot整合的方式

spring的官网中对Elasticsearch客户端的描述如下
https://docs.spring.io/spring-boot/docs/2.1.11.RELEASE/reference/html/boot-features-nosql.html#boot-features-elasticsearch%60

在spring的官网中主要介绍了三种整合方式,分别是REST、Jest和Spring Data,比较常见的就是REST和Spring Data,不过下面主要只会介绍Spring Data方式。

原生客户端

Elasticsearch的java原生客户端很复杂,并不是基于面向对象的,使用起来非常不方便

@Test
void testRestInsert() throws IOException {//1.连接rest接口HttpHost http = new HttpHost("192.168.204.209", 9200, "http");RestClientBuilder restClientBuilder = RestClient.builder(http);//rest构建器RestHighLevelClient restHighLevelClient = new RestHighLevelClient(restClientBuilder);//获取高级客户端对象//2.封装请求对象//BulkRequest bulkRequest = new BulkRequest(); //用于批量操作IndexRequest indexRequest = new IndexRequest("test_rest", "_doc", "1");HashMap skuMap = new HashMap();skuMap.put("name","法拉利 LaFerrari Aperta");skuMap.put("brandName","法拉利");skuMap.put("categoryName","超级跑车");HashMap spec = new HashMap();spec.put("动力","963匹");spec.put("扭矩","880N/m");spec.put("车长","4975mm");spec.put("重量","1250kg");skuMap.put("spec",spec);skuMap.put("createTime","2017-08-10");skuMap.put("price",43000000);skuMap.put("saleNum",209);skuMap.put("commentNum",6128746);indexRequest.source(skuMap);//bulkRequest.add(indexRequest); //用于批量操作//3.获取响应结果IndexResponse indexResponse = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);//BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT); //用于批量操作int status = indexResponse.status().getStatus();System.out.println(status);restHighLevelClient.close();
}

可以发现原生的客户端是将命令封装成一个map数据,类似于我们原生的json命令格式,最后返回的也是一个字符串,如下所示,所以我们还需要自己进行字符串拆分。

REST

下面是官网对REST客户端的描述

Jest

下面是官网对Jest客户端的描述

Spring Data

下面是官网对Spring Data的描述

spring data的官方文档
https://docs.spring.io/spring-data/elasticsearch/docs/3.2.3.RELEASE/reference/html/

spring data官方文档的描述如下,这个客户端也是本文重点介绍的,也是目前来说使用的最为广泛的。

Spring Data的配置

首先还是需要引入的依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

然后写一个配置类

我们需要创建一个继承ElasticsearchConfigurationSupport的实现类,通过这个类我们可以配置Elasticsearch的相关参数。下面就是官网对此类的描述

下面是我们创建的ElasticsearchConfigurationSupport子类实现,三个方法分别实现了对Elasticsearch的配置和将其整合进我们的springboot项目中。

@Configuration
public class TransportClientConfig extends ElasticsearchConfigurationSupport {@Beanpublic Client elasticsearchClient() throws UnknownHostException {Settings settings = Settings.builder().put("cluster.name", "taibai").build();TransportClient client = new PreBuiltTransportClient(settings);client.addTransportAddress(new TransportAddress(InetAddress.getByName("192.168.204.209"), 9300));return client;}@Bean(name = {"elasticsearchOperations", "elasticsearchTemplate"})public ElasticsearchTemplate elasticsearchTemplate() throws UnknownHostException {return new ElasticsearchTemplate(elasticsearchClient(), entityMapper());}@Bean@Overridepublic EntityMapper entityMapper() {ElasticsearchEntityMapper entityMapper = new ElasticsearchEntityMapper(elasticsearchMappingContext(),new DefaultConversionService());entityMapper.setConversions(elasticsearchCustomConversions());return entityMapper;}
}

创建索引的实体类

将我们需要使用的索引创建其对应的实体类,通过@Document注解配置索引的一些参数,通过@Id注解创建一个必须要有的id字段,接着就可以通过@Field注解配置其他的字段,其中analyzer属性可以配置它的分词器(只有text类型的字段可以配置),type属性可以配置字段的类型。

@Document(indexName = "test_springdata_es",type = "_doc",shards = 1,replicas = 0,createIndex = true,useServerConfiguration = false,versionType = VersionType.EXTERNAL)
public class Item {@Overridepublic String toString() {return "Item{" +"ld=" + ld +", name='" + name + '\'' +", sex='" + sex + '\'' +", age=" + age +", interest=" + interest +", childItem=" + childItem +'}';}@Idprivate long ld;@Field(analyzer = "ik_max_word",type = FieldType.Text)private String name;@Field(type = FieldType.Keyword)private String sex;@Field(type = FieldType.Integer)private Integer age;@Field(type = FieldType.Keyword)private List<String> interest;@Field(type = FieldType.Object)private ChildItem childItem;public Item(){}public Item(long ld, String name, String sex, Integer age, List<String> interest, ChildItem childItem) {this.ld = ld;this.name = name;this.sex = sex;this.age = age;this.interest = interest;this.childItem = childItem;}public long getLd() {return ld;}public void setLd(long ld) {this.ld = ld;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public List<String> getInterest() {return interest;}public void setInterest(List<String> interest) {this.interest = interest;}public ChildItem getChildItem() {return childItem;}public void setChildItem(ChildItem childItem) {this.childItem = childItem;

通过上面的实体类我们可以创建索引或映射

我们之前在ElasticsearchConfigurationSupport的子类中注入的ElasticsearchTemplate的bean我们就可以在这里使用。下面是使用这个ElasticsearchTemplate创建索引或映射

@Autowired
private ElasticsearchTemplate elasticsearchTemplate;@Test
void createIndex(){//创建索引及映射elasticsearchTemplate.createIndex(Item.class);//创建映射//elasticsearchTemplate.putMapping(Item.class);
}

创建索引的mapper接口

如果我们需要对我们的索引中的数据进行操作还是需要创建一个mapper来操作的,类似于mybatis的mapper,不过同样的,我们不需要真正去实现它,只需要创建一个mapper接口,剩下的交给spring和elasticsearch实现。然后我们就可以直接像调用一个普通bean一样调用这个mapper了。

下面就是刚刚我们创建的实体类索引的mapper,只需要继承ElasticsearchRepository接口就可以了,在泛型中写上我们的实体类。

public interface ItemMapper extends ElasticsearchRepository<Item,String>{}

Spring Data的使用

下面会介绍一些基本的API使用,这里我们前面已经完成了Elasticsearch与spring的整合,已经创建了索引实体类和对象的mapper。

插入或修改数据

下面通过mapper的save方法(此方法不需要我们创建,是父接口提供的)实现了单条数据的插入或者修改。

//添加一条数据 and  修改一条数据
@Test
void insertGoods() {SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String str = simpleDateFormat.format(new Date());Goods goods=new Goods(1025332689,"","OPPO R17新年版 2500万美颜拍照 6.4英寸水滴屏 光感屏幕指纹 6G+128G 全网通 移动联通电信4G 双卡双待手机",37400,20,100,"https://m.360buyimg.com/mobilecms/s720x720_jfs/t1/10441/9/5525/162976/5c177debEaf815b43/3aa7d4dc182cc4d9.jpg!q70.jpg.webp","https://m.360buyimg.com/mobilecms/s720x720_jfs/t1/10441/9/5525/162976/5c177debEaf815b43/3aa7d4dc182cc4d9.jpg!q70.jpg.webp",10,str,str,"10000243333000",558,"手机","OPPO","{'颜色': '王者荣耀定制版', '版本': 'R17'}",1,1,1,4L);System.out.println(goodsMapper.save(goods));
}

在实体类中我们可以创建一个version字段,这个字段我们可以进行并发控制,加上@Version注解

通过saveAll方法我们可以将一个集合中的实体类插入到索引中

//批量插入和批量修改
@Test
void insertGoodsList() {List<Goods> list=new ArrayList<>();SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String str = simpleDateFormat.format(new Date());Goods goods=new Goods(1001332689,"","OPPO R17新年版 2500万美颜拍照 6.4英寸水滴屏 光感屏幕指纹 6G+128G 全网通 移动联通电信4G 双卡双待手机",37400,10000,100,"https://m.360buyimg.com/mobilecms/s720x720_jfs/t1/10441/9/5525/162976/5c177debEaf815b43/3aa7d4dc182cc4d9.jpg!q70.jpg.webp","https://m.360buyimg.com/mobilecms/s720x720_jfs/t1/10441/9/5525/162976/5c177debEaf815b43/3aa7d4dc182cc4d9.jpg!q70.jpg.webp",10,str,str,"10000243333000",558,"手机","OPPO","{'颜色': '王者荣耀定制版', '版本': 'R17'}",1,1,1);Goods goods2=new Goods(1001368912,"","OPPO R17新年版 2500万美颜拍照 6.4英寸水滴屏 光感屏幕指纹 6G+128G 全网通 移动联通电信4G 双卡双待手机",37400,10000,100,"https://m.360buyimg.com/mobilecms/s720x720_jfs/t1/10441/9/5525/162976/5c177debEaf815b43/3aa7d4dc182cc4d9.jpg!q70.jpg.webp","https://m.360buyimg.com/mobilecms/s720x720_jfs/t1/10441/9/5525/162976/5c177debEaf815b43/3aa7d4dc182cc4d9.jpg!q70.jpg.webp",10,str,str,"10000243333000",558,"手机","OPPO","{'颜色': '王者荣耀定制版', '版本': 'R17'}",1,1,1);Goods goods3=new Goods(100001402792L,"","OPPO R17新年版 2500万美颜拍照 6.4英寸水滴屏 光感屏幕指纹 6G+128G 全网通 移动联通电信4G 双卡双待手机",37400,10000,100,"https://m.360buyimg.com/mobilecms/s720x720_jfs/t1/10441/9/5525/162976/5c177debEaf815b43/3aa7d4dc182cc4d9.jpg!q70.jpg.webp","https://m.360buyimg.com/mobilecms/s720x720_jfs/t1/10441/9/5525/162976/5c177debEaf815b43/3aa7d4dc182cc4d9.jpg!q70.jpg.webp",10,str,str,"10000243333000",558,"手机","OPPO","{'颜色': '王者荣耀定制版', '版本': 'R17'}",1,1,1);list.add(goods);list.add(goods2);list.add(goods3);goodsMapper.saveAll(list);
}
删除数据

通过deleteById可以删除指定id的数据,通过deleteAll方法则可以删除映射索引中的所有数据

//删除数据
@Test
void updateGoods() {//删除一条
//      goodsMapper.deleteById("1001332689");//删除所有或者传入集合 删除集合中的数据goodsMapper.deleteAll();
}
全量查询

提供了十分方便的分页排序的工具类Pageable

//查询数据
@Test
void uqueryGoods() {//查询一条数据
//      Optional<Goods> goods = goodsMapper.findById("100001402792");
//      System.out.println(goods.get());//      System.out.println("====================================");//查询所有数据
//      Iterable<Goods> goodsAll = goodsMapper.findAll();
//      Iterator<Goods> goodsIterator = goodsAll.iterator();
//      int count=0;
//      while (goodsIterator.hasNext()){//          Goods goods1 = goodsIterator.next();
//          System.out.println(goods1);
//          count++;
//      }
//      System.out.println(count);//        System.out.println("====================================");//分页排序// page页码   并不是跳过多少数据//返回数Pageable pageable=PageRequest.of(1,100,Sort.by(Sort.Direction.ASC, "num"));Page<Goods> goodsPage = goodsMapper.findAll(pageable);Iterator<Goods> goodsIterator = goodsPage.iterator();int count=0;while (goodsIterator.hasNext()){Goods goods1 = goodsIterator.next();System.out.println(goods1);count++;}System.out.println(count);
}
判断文档是否存在

通过existsById判断指定id的数据是否存在

@Test
void exists(){//判断文档是否存在boolean exists = goodsMapper.existsById("文档ID");
}
结构化查询
term查询

不会进行分词,属于精确查询,借助TermQueryBuilder类完成查询对象的封装

//term查询
@Test
void termGoods(){//主要用于精确匹配哪些值,比如数字,日期,布尔值或 not_analyzed 的字符串(未经分析的文本数据类型)// 搜索前不会再对搜索词进行分词,所以我们的搜索词必须是文档分词集合中的一个。TermQueryBuilder termQueryBuilder=new TermQueryBuilder("name","2018");Pageable pageable=PageRequest.of(0,100);Iterable<Goods> goods = goodsMapper.search(termQueryBuilder,pageable);Iterator<Goods> goodsIterator = goods.iterator();int count=0;while (goodsIterator.hasNext()){Goods goods1 = goodsIterator.next();System.out.println(goods1);count++;}System.out.println(count);
}

还可以同时查询多个条件

//terms查询
@Test
void termsGoods(){//terms 跟 term 有点类似,但 terms 允许指定多个匹配条件。// 如果某个字段指定了多个值,那么文档需要一起去做匹配    或者关系TermsQueryBuilder termsQueryBuilder=new TermsQueryBuilder("name","2018","最新","女鞋");Pageable pageable=PageRequest.of(0,100);Iterable<Goods> goods = goodsMapper.search(termsQueryBuilder,pageable);Iterator<Goods> goodsIterator = goods.iterator();int count=0;while (goodsIterator.hasNext()){Goods goods1 = goodsIterator.next();System.out.println(goods1);count++;}System.out.println(count);
}
range查询

范围查询,借助RangeQueryBuilder对象封装需要查询的范围

//range查询
@Test
void rangelGoods(){//范围查询RangeQueryBuilder rangeQueryBuilder=new RangeQueryBuilder("price");rangeQueryBuilder.gt(20);rangeQueryBuilder.lt(10000);Pageable pageable=PageRequest.of(0,100);Iterable<Goods> goods = goodsMapper.search(rangeQueryBuilder,pageable);Iterator<Goods> goodsIterator = goods.iterator();int count=0;while (goodsIterator.hasNext()){Goods goods1 = goodsIterator.next();System.out.println(goods1);count++;}System.out.println(count);
}
exists查询

判断是否存在某个字段,注意这个个前面的exist不一样,一个是查询数据是否存在,一个是查询字段是否存在。

//exists查询
@Test
void existsGoods(){//exists 查询可以用于查找文档中是否包含指定字段或没有某个字段,类似于SQL语句中的 IS_NULL 条件//包含这个字段就返回返回这条数据ExistsQueryBuilder existsQueryBuilder=new ExistsQueryBuilder("category_name");Pageable pageable=PageRequest.of(0,100);Iterable<Goods> goods = goodsMapper.search(existsQueryBuilder,pageable);Iterator<Goods> goodsIterator = goods.iterator();int count=0;while (goodsIterator.hasNext()){Goods goods1 = goodsIterator.next();System.out.println(goods1);count++;}System.out.println(count);
}
match查询

会经过分词之后再查询,这种查询和term查询形成对比

//match查询
@Test
void matchGoods(){//match查询会先对搜索词进行分词,分词完毕后再逐个对分词结果进行匹配,因此相比于term的精确搜索,match是分词匹配搜索//如果用 match 下指定了一个确切值,在遇到数字,日期,布尔值或者 not_analyzed 的字符串时,它将为你搜索你给定的值MatchQueryBuilder matchQueryBuilder=new MatchQueryBuilder("name","2018年最新女鞋");Pageable pageable=PageRequest.of(0,100);Iterable<Goods> goods = goodsMapper.search(matchQueryBuilder,pageable);Iterator<Goods> goodsIterator = goods.iterator();int count=0;while (goodsIterator.hasNext()){Goods goods1 = goodsIterator.next();System.out.println(goods1);count++;}System.out.println(count);
}
bool查询

条件查询,存在多个条件,可以形成各种嵌套,比较复杂的查询

//bool查询 和 filter 查询
@Test
void boolGoods(){//      bool 查询可以用来合并多个条件查询结果的布尔逻辑,它包含一下操作符:
//      must :: 多个查询条件的完全匹配,相当于 and 。
//      must_not :: 多个查询条件的相反匹配,相当于 not 。
//      should :: 至少有一个查询条件匹配, 相当于 or 。BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder();//搜索2018年价格在1000-2000之内的女鞋   颜色不能是白色的  只能是黑色或者是红色RangeQueryBuilder rangeQueryBuilder=new RangeQueryBuilder("price");rangeQueryBuilder.lte(2000);rangeQueryBuilder.gte(1000);MatchQueryBuilder matchQueryBuilder=new MatchQueryBuilder("name","2018女鞋");MatchQueryBuilder matchQueryBuilder2=new MatchQueryBuilder("spec","蓝色");boolQueryBuilder.must(rangeQueryBuilder);boolQueryBuilder.must(matchQueryBuilder);boolQueryBuilder.mustNot(matchQueryBuilder2);MatchQueryBuilder matchQueryBuilder3=new MatchQueryBuilder("spec","黑色 红色");boolQueryBuilder.must(matchQueryBuilder3);TermQueryBuilder termsQueryBuilder=new TermQueryBuilder("num",10000);boolQueryBuilder.filter(termsQueryBuilder);//     Pageable pageable=PageRequest.of(0,100);Iterable<Goods> goods = goodsMapper.search(boolQueryBuilder);Iterator<Goods> goodsIterator = goods.iterator();int count=0;while (goodsIterator.hasNext()){Goods goods1 = goodsIterator.next();System.out.println(goods1);count++;}System.out.println(count);
}
自定义方法

我们可以使用自定义方法,这样就不需要写那些复杂的查询逻辑了,假如下面的方法是根据name字段并返回相应分页后的结果。方法我们写在mapper接口中就可以了,我们不需要实现,需要注意的是命名是有规范的。

下面是对自定义方法的测试

下面是自定义方法名的规则

聚合操作

聚合之后的结果对象需要通过真正返回的json分析使用特定的api得到结果,这个就需要注解我们的ElasticsearchTemplate对象。

平均、最大、最小、求和
//平均最大最小求和聚合
@Test
void testAggregation(){AvgAggregationBuilder avgAggregationBuilder = AggregationBuilders.avg("taibai").field("price");
//        MaxAggregationBuilder maxAggregationBuilder = AggregationBuilders.max("taibai").field("price");SearchQuery searchQuery = new NativeSearchQueryBuilder().addAggregation(avgAggregationBuilder).withIndices("goods").withTypes("_doc").build();Aggregations aggregations = elasticsearchTemplate.query(searchQuery, new ResultsExtractor<Aggregations>() {@Overridepublic Aggregations extract(SearchResponse response) {return response.getAggregations();}});Aggregation aggregation1 = aggregations.asList().get(0);InternalNumericMetricsAggregation.SingleValue singleValue= (InternalNumericMetricsAggregation.SingleValue) aggregation1;double value = singleValue.value();System.out.println(value);
}
去重
//去重
@Test
void testAggregationCardinality(){CardinalityAggregationBuilder aggregationBuilder = AggregationBuilders.cardinality("taibai").field("price");SearchQuery searchQuery = new NativeSearchQueryBuilder().addAggregation(aggregationBuilder).withIndices("goods").withTypes("_doc").build();Aggregations aggregations = elasticsearchTemplate.query(searchQuery, new ResultsExtractor<Aggregations>() {@Overridepublic Aggregations extract(SearchResponse response) {return response.getAggregations();}});Aggregation aggregation1 = aggregations.getAsMap().get("taibai");InternalNumericMetricsAggregation.SingleValue singleValue= (InternalNumericMetricsAggregation.SingleValue) aggregation1;double value = singleValue.value();System.out.println(value);
}
扩展查询
//扩展查询
@Test
void testAggregationextended_stats(){ExtendedStatsAggregationBuilder extendedStatsAggregationBuilder = AggregationBuilders.extendedStats("taibai").field("price");SearchQuery searchQuery = new NativeSearchQueryBuilder().addAggregation(extendedStatsAggregationBuilder).withIndices("goods").withTypes("_doc").build();Aggregations aggregations = elasticsearchTemplate.query(searchQuery, new ResultsExtractor<Aggregations>() {@Overridepublic Aggregations extract(SearchResponse response) {return response.getAggregations();}});Aggregation aggregation1 = aggregations.getAsMap().get("taibai");InternalNumericMetricsAggregation.MultiValue multiValue= (InternalNumericMetricsAggregation.MultiValue ) aggregation1;System.out.println(multiValue.value("max"));
}
terms词聚合
//terms词聚合
@Test
void testAggregationTerms(){TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("taibai").field("price");SearchQuery searchQuery = new NativeSearchQueryBuilder().addAggregation(termsAggregationBuilder).withIndices("goods").withTypes("_doc").build();Aggregations aggregations = elasticsearchTemplate.query(searchQuery, new ResultsExtractor<Aggregations>() {@Overridepublic Aggregations extract(SearchResponse response) {return response.getAggregations();}});Aggregation aggregation1 = aggregations.getAsMap().get("taibai");Terms term1 = (Terms)aggregation1;List<? extends Terms.Bucket> buckets = term1.getBuckets();for (Terms.Bucket bucket : buckets) {System.out.println(bucket.getKey()+"||"+bucket.getDocCount());}
}
top_hits最高匹配权值聚合
//top_hits最高匹配权值聚合
@Test
void testAggregationtop_hits(){TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("taibai").field("price");TopHitsAggregationBuilder topHitsAggregationBuilder = AggregationBuilders.topHits("top").size(3);termsAggregationBuilder.subAggregation(topHitsAggregationBuilder);SearchQuery searchQuery = new NativeSearchQueryBuilder().addAggregation(termsAggregationBuilder).withIndices("goods").withTypes("_doc").build();Aggregations aggregations = elasticsearchTemplate.query(searchQuery, new ResultsExtractor<Aggregations>() {@Overridepublic Aggregations extract(SearchResponse response) {return response.getAggregations();}});Aggregation aggregation1 = aggregations.getAsMap().get("taibai");Terms term1 = (Terms)aggregation1;List<? extends Terms.Bucket> buckets = term1.getBuckets();for (Terms.Bucket bucket : buckets) {System.out.println(bucket.getKey()+"||"+bucket.getDocCount());Aggregation aggregation = bucket.getAggregations().getAsMap().get("top");TopHits topHits= (TopHits) aggregation;Iterator<SearchHit> iterator = topHits.getHits().iterator();while (iterator.hasNext()){SearchHit next = iterator.next();Object object=JSONObject.parse(next.getSourceAsString());System.out.println(object);}}
}

综合查询

@Test
void testAggregationLast(){RangeAggregationBuilder rangeAggregationBuilder = AggregationBuilders.range("age_range").field("age").addRange(20,30).addRange(30,40).addRange(40,50);TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("gender_group").field("gender.keyword");AvgAggregationBuilder aggregationBuilder = AggregationBuilders.avg("balance_avg").field("balance");termsAggregationBuilder.subAggregation(aggregationBuilder);rangeAggregationBuilder.subAggregation(termsAggregationBuilder);SearchQuery searchQuery = new NativeSearchQueryBuilder().addAggregation(rangeAggregationBuilder).withIndices("bank").withTypes("_doc").build();Aggregations aggregations = elasticsearchTemplate.query(searchQuery, new ResultsExtractor<Aggregations>() {@Overridepublic Aggregations extract(SearchResponse response) {return response.getAggregations();}});Aggregation aggregation1 = aggregations.getAsMap().get("age_range");Range range = (Range)aggregation1;List<? extends Range.Bucket> buckets = range.getBuckets();for (Range.Bucket bucket : buckets) {System.out.println(bucket.getKeyAsString()+"--"+bucket.getDocCount());Aggregation gender_group = bucket.getAggregations().getAsMap().get("gender_group");Terms terms=(Terms)gender_group;List<? extends Terms.Bucket> buckets1 = terms.getBuckets();for (Terms.Bucket bucket1 : buckets1) {System.out.println(bucket1.getKeyAsString()+"--"+bucket1.getDocCount());Aggregation balance_avg = bucket1.getAggregations().getAsMap().get("balance_avg");Avg avg= (Avg) balance_avg;System.out.println(avg.getValue());}}
}

2019.12.24笔记——SpringBoot整合Elasticsearch及其使用相关推荐

  1. SpringBoot整合Elasticsearch详细步骤以及代码示例(附源码)

    准备工作# 环境准备# JAVA版本 Copy java version "1.8.0_121" Java(TM) SE Runtime Environment (build 1. ...

  2. java-web系列(九)---SpringBoot整合ElasticSearch

    前言 这个项目的github地址:extensible项目的github地址 extensible项目当前功能模块如下: java-web系列(一)-搭建一个基于SSM框架的java-web项目 ja ...

  3. 七、SpringBoot整合elasticsearch集群

    @Author : By Runsen @Date : 2020/6/12 作者介绍:Runsen目前大三下学期,专业化学工程与工艺,大学沉迷日语,Python, Java和一系列数据分析软件.导致翘 ...

  4. SpringBoot整合ElasticSearch实现多版本的兼容

    前言 在上一篇学习SpringBoot中,整合了Mybatis.Druid和PageHelper并实现了多数据源的操作.本篇主要是介绍和使用目前最火的搜索引擎ElastiSearch,并和Spring ...

  5. SpringBoot整合elasticsearch (java整合es)

    欢迎大家进群,一起探讨学习 微信公众号,每天给大家提供技术干货 博主技术笔记 博主网站地址1 博主网站地址2 博主开源微服架构前后端分离技术博客项目源码地址,欢迎各位star SpringBoot整合 ...

  6. SpringBoot 整合ElasticSearch全文检索

    ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java语言开发的,并作为Apa ...

  7. Springboot 整合ElasticSearch 常用的插入查询,模糊查询,范围查询

    前言 本来该篇教程就应该写到 Springboot 整合 ElasticSearch 入门教学必看 https://blog.csdn.net/qq_35387940/article/details/ ...

  8. 【数据篇】SpringBoot 整合 Elasticsearch 实践数据搜索引擎

    写在最前 Elasticsearch 入门必读 Docker安装ELK Spring Data Elasticsearch 参考文档 版本选择 Spring Data Release Train Sp ...

  9. 微服务商城系统(六)商品搜索 SpringBoot 整合 Elasticsearch

    文章目录 一.Elasticsearch 和 IK 分词器的安装 二.Kibana 使用 三.数据导入 Elasticsearch 1.SpringData Elasticsearch 介绍 2.搜索 ...

最新文章

  1. html公共模块提取出去,webpack 填坑之路--提取独立文件(模块)
  2. 微服务与单体架构:IT变革中企业及个体如何自处?
  3. PyTorch导出JIT模型并用C++ API libtorch调用
  4. 中国特夫行业市场供需与战略研究报告
  5. js jquery 判断元素是否在数组内
  6. php 数据库时间具体到分钟,php – 在设定的到期时间后删除数据库行(例如5分钟)...
  7. Head First C 学习日志 第十章 进程间通信 输入输出重定向
  8. 未来互联网最稀缺的能力是什么?
  9. 【干货】Vray渲染器的使用方法
  10. 如何在Linux上下载MongoDB
  11. 考研数学数学二有手就行系列之多元函数微分学(六)
  12. Moore-Penrose 广义逆/伪逆 (The Moore-Penrose Pseudoinverse)
  13. 计算机网络ip进制转换方法,IP地址与二进制之间的转换
  14. L1-023 输出GPLT Python 团体程序设计天梯赛-练习集
  15. html如何添加时钟效果,HTML5实现时钟效果
  16. 9.14 PreScan自动驾驶建模与仿真技术培训(第三期)
  17. WPF x:Key标签
  18. Windows fatal exception: access violation / Process finished with exit code -1073741819 (0xC0000005)
  19. 深入浅出matplotlib(96):标记的疏密控制
  20. c语言堆、栈、数据段、代码段、bss段的疑惑

热门文章

  1. Android安卓开发集成微信第三方扫描二维码登录-超级无敌具详细
  2. 单片机按键开发库-支持连击、长按等操作
  3. 弯曲文字检测之SPCNet
  4. 简单使用scrapy框架下载漫画
  5. asp.net+sqlserver餐厅餐饮管理系统C#项目源码
  6. latex写带声调上标的字母
  7. 最简单 VB6.易语言选股接口案例
  8. Vue.js(七) http (vue-resource和axios)
  9. TQ2440_LED
  10. Go语言圣经 - 第11章 测试 - 11.3 测试覆盖率