典型的电子商务网站有哪些,观影楼网站,软件技术方案模板,中国纪检监察报通过之前两篇文章 了解了ES的核心概念和基础使用学习进阶的DSL语法处理复杂的查询 这段时间通过在本企业代码中对ES框架的使用#xff0c;总结了不少经验。主要分为三点 企业封装了ES原生的api#xff0c;需要使用企业项目提供的接口实现 -------简单使用#xff08;本章节目… 通过之前两篇文章 了解了ES的核心概念和基础使用学习进阶的DSL语法处理复杂的查询 这段时间通过在本企业代码中对ES框架的使用总结了不少经验。主要分为三点 企业封装了ES原生的api需要使用企业项目提供的接口实现 -------简单使用本章节目的项目会遇到更复杂的查询需求需要进一步深入对ES的学习 -------复杂使用了解项目如何封装原生的api学习设计思想 --------深入学习 目录 1. Term查询1.1 原生api实现term查询1.2 企业api实现term查询 2. 复合查询__must2.1 原生api实现must查询2.2 企业api实现must查询 3. 复合查询__should4. 复合查询__mustnot5. 分页和排序5.1 原生api实现分页和排序5.2 企业api实现分页和排序 6 聚合查询6.1 原生api实现桶聚合6.2 企业api实现桶聚合 ------------------------------本章节核心目的是梳理出 本企业项目提供的api 和 原生ES提供的api 的使用区别-------------------------------- 本企业将ES的api大致封装成了两个核心类 EsOperater类
方法说明String[] indexes()Integer from()分页Integer size()分页List sort()排序QueryBuilder queryBuilder()普通查询/复合查询EsOperaterBuiler esOperaterBuiler()继承类SearchResponse execute()执行查询CountResponse queryTotal()SearchResponse executeScroll()QueryBuilder buildQueryBuilder()QueryBuilder buildQueryBuilderByQueryType(EsQueryInfoBean queryInfo)根据查询信息bean构造相应的查询器List buildAggBuilder()根据aggMap创建聚合器包括单层聚合和多层聚合AggregationBuilder makeChildAgg(EsAggInfoBean esAggInfo, EsAggInfoBean parentAggInfo)递归创建聚合器EsOperater build()
EsOperaterBuiler类重点关注
方法说明EsOperaterBuiler indexes(String… indexes)设置索引集合EsOperaterBuiler from(Integer from)设置分页参数的查询数量EsOperaterBuiler size(Integer size)设置分页参数的查询数量EsOperaterBuiler sort(String sort)设置排序字段EsOperaterBuiler sortOrder(SortOrder sortOrder)设置排序排序方式升序、降序EsOperaterBuiler queryBuilder(QueryBuilder queryBuilder)设置查询构建器QueryBuilder如果操作构建器EsOperater中buildQueryBuilder()方法构造不出需要的查询构建起Boolean isAliasExists(String indexName)查询别名是否存在
1. Term查询
1.1 原生api实现term查询
Test
void TermQuery(){// 获取client这里默认已经获取// 1. 准备request (参数为索引名称)SearchRequest request new SearchRequest(indexName);// 2. 构建DSL// 2.1 获取建造者SearchSourceBuilder searchSourceBuilder new SearchSourceBuilder();// 2.2 建造者调用DSLsearchSourceBuilder.termQuery(name,zjh);// 2.3 组装request.source(searchSourceBuilder);// 3. 发送请求SearchResponse reponse client.search(request, RequestOptions.ESFAULT);// 4. 解析数据得到_source数据SearchHit[] hits response.getHits().getHits();for (SearchHit hit : hits) {System.out.println(hit.getSourceAsString());}}此时就可以获取到source的数据了。上述写法也可以简化如下
// 此方式常用
Test
void TermQuery(){// 获取client这里默认已经获取// 1. 准备request (参数为索引名称)SearchRequest request new SearchRequest(indexName);// 2. 构建DSL语句request.source().query(QueryBuilders.termQuery(name,zjh));// 3. 发送请求SearchResponse reponse client.search(request, RequestOptions.ESFAULT);// 4. 解析数据得到_source数据SearchHit[] hits response.getHits().getHits();for (SearchHit hit : hits) {System.out.println(hit.getSourceAsString());}}1.2 企业api实现term查询
Test
void TermQuery(){// 构建索引名称String indexName ElasticSearchConst.UNSTRUCTURE_FILE_SCAN_RESULT taskId;// 1. 设置索引集合EsOperater.EsOperaterBuiler builder EsOperater.esOperaterBuiler().indexes(indexName);// 2. 设置查询构建器 准备DSL语句builder.queryBuilder(QueryBuilders.termQuery(name,zjh));// 3. 发送请求SearchResponse response builder.build().execute();// 4. 解析数据得到_source数据SearchHit[] hits response.getHits().getHits();for (SearchHit hit : hits) {System.out.println(hit.getSourceAsString());}}解释
步骤一需要将 索引名 存到 esOperaterBuiler类 的全局变量中以便其他方法调用
步骤二需要将 DSL语句 存到 esOperaterBuiler类 的全局变量中以便其他方法调用
步骤三需要从esOperaterBuiler类 切换到 esOperater类再执行最核心的 execute() 方法这个方法会进行一些列操作将最终的结果返回给 response
2. 复合查询__must
2.1 原生api实现must查询
Test
void MustQuery(){// 获取client这里默认已经获取// 1. 准备request (参数为索引名称)SearchRequest request new SearchRequest(indexName);// 2. 构建DSL语句// 2.1 创建bool查询BoolQueryBuilder boolQuery QueryBuilders.boolQuery();// 2.2 添加must条件boolQuery.must(QueryBuilders.termQuery(name, zjh));// 2.3 构建请求内容request.source().query(boolQuery);// 3. 发送请求SearchResponse reponse client.search(request, RequestOptions.ESFAULT);// 4. 解析数据得到_source数据SearchHit[] hits response.getHits().getHits();for (SearchHit hit : hits) {System.out.println(hit.getSourceAsString());}}2.2 企业api实现must查询
Test
void TermQuery(){// 构建索引名称String indexName ElasticSearchConst.UNSTRUCTURE_FILE_SCAN_RESULT taskId;// 1. 设置索引集合EsOperater.EsOperaterBuiler builder EsOperater.esOperaterBuiler().indexes(indexName);// 2. 设置查询构建器 准备DSL语句// 2.1 创建bool查询BoolQueryBuilder boolQuery QueryBuilders.boolQuery();// 2.2 添加must条件boolQuery.must(QueryBuilders.termQuery(name, zjh));// 此行代码的作用就是将构造的must条件存放到EsOperater类的全局变量builder.queryBuilder(boolQuery);// 3. 发送请求SearchResponse response builder.build().execute();// 4. 解析数据得到_source数据SearchHit[] hits response.getHits().getHits();for (SearchHit hit : hits) {System.out.println(hit.getSourceAsString());}}
解释一下步骤二可能会疑惑为什么不这样写BoolQueryBuilder boolQuery QueryBuilders.boolQuery();BoolQueryBuilder mustQuery boolQuery.must(QueryBuilders.termQuery(name, zjh))builder.queryBuilder(mustQuery);因为must参数底层会将参数传给boolQuery.must的boolQuery对象是递增的逻辑解释
步骤一需要将 索引名 存到 esOperaterBuiler类 的全局变量中以便其他方法调用
步骤二需要将 DSL语句布尔查询 存到 esOperaterBuiler类 的全局变量中以便其他方法调用
步骤三需要从esOperaterBuiler类 切换到 esOperater类再执行最核心的 execute() 方法这个方法会进行一些列操作将最终的结果返回给 response
可以进一步简化
Test
void TermQuery(){// 构建索引名称String indexName ElasticSearchConst.UNSTRUCTURE_FILE_SCAN_RESULT taskId;// DSL语句BoolQueryBuilder boolQuery QueryBuilders.boolQuery();boolQuery.must(QueryBuilders.termQuery(name, zjh));// 使用企业api实现查询EsOperater.EsOperaterBuiler builder EsOperater.esOperaterBuiler();SearchResponse response builder.index(indexName).queryBuilder(boolQuery).build().execute();// 4. 解析数据得到_source数据SearchHit[] hits response.getHits().getHits();for (SearchHit hit : hits) {System.out.println(hit.getSourceAsString());}}3. 复合查询__should
同理
4. 复合查询__mustnot
同理
5. 分页和排序
5.1 原生api实现分页和排序
// 此方式常用
Test
void TermQuery(){// 获取client这里默认已经获取// 1. 准备request (参数为索引名称)SearchRequest request new SearchRequest(indexName);//2.查询__构建DSL语句request.source().query(QueryBuilders.termQuery(name,zjh));// 分页request.source().from.size(5);// 时间排序request.source().sort(“logTime”SortOrder.ASC);// 3. 发送请求SearchResponse reponse client.search(request, RequestOptions.ESFAULT);// 4. 解析数据得到_source数据SearchHit[] hits response.getHits().getHits();for (SearchHit hit : hits) {System.out.println(hit.getSourceAsString());}}5.2 企业api实现分页和排序
Test
void TermQuery(){// 构建索引名称String indexName ElasticSearchConst.UNSTRUCTURE_FILE_SCAN_RESULT taskId;// 1. 设置索引集合EsOperater.EsOperaterBuiler builder EsOperater.esOperaterBuiler().indexes(indexName);// 2. 查询builder.queryBuilder(QueryBuilders.termQuery(name,zjh));// 分页builder.queryBuilder(QueryBuilders.termQuery(name,zjh)).size(5);// 排序builder.queryBuilder(QueryBuilders.termQuery(name,zjh)).sort(logTime).sortOrder(SortOrder.DESC);// 3. 发送请求SearchResponse response builder.build().execute();// 4. 解析数据得到_source数据SearchHit[] hits response.getHits().getHits();for (SearchHit hit : hits) {System.out.println(hit.getSourceAsString());}}6 聚合查询
6.1 原生api实现桶聚合
// 需求实现对城市、品牌的聚合。即用户输入城市、品牌得到搜索结果
Test
void TermQuery(){// 获取client这里默认已经获取// 1. 准备request (参数为索引名称)SearchRequest request new SearchRequest(indexName);//2.查询// CityName自定义桶名 city根据城市聚合AggregationBuilder aggregationBuilder1 AggregationBuilders.terms(CityName).field(city);AggregationBuilder aggregationBuilder2 AggregationBuilders.terms(BrandName).field(brand);request.source().aggregation(aggregationBuilder1);request.source().aggregation(aggregationBuilder2);// 3. 发送请求SearchResponse reponse client.search(request, RequestOptions.ESFAULT);// 4. 解析数据Aggreagtions aggreagtions response.getAggreagtions();List? extends Terms.Bucket buckets1 aggreagtions.get(CityName).getBuckets();for (Terms.Bucket bucket : buckets) {//打印结果是西安 或者 上海System.out.println(bucket.getKeyAsString());}List? extends Terms.Bucket buckets2 aggreagtions.get(BrandName).getBuckets();for (Terms.Bucket bucket : buckets) {//打印结果是星巴克 或者 瑞幸System.out.println(bucket.getKeyAsString());}}6.2 企业api实现桶聚合
// 需求实现对城市、品牌的聚合。即用户输入城市、品牌得到搜索结果
Test
void TermQuery(){// 获取client这里默认已经获取// 1. 准备request (参数为索引名称)SearchRequest request new SearchRequest(indexName);//2.查询ListAggregationBuilder aggregationBuilderList new ArrayList();aggregationBuilderList.add(AggregationBuilders.terms(CityName).field(city));;aggregationBuilderList.add(AggregationBuilders.terms(BrandName).field(brand));// aggBuilderList企业封装的工具将聚合参数赋值到全局变量上builder.aggBuilderList(aggregationBuilderList);// 3. 发送请求SearchResponse response builder.size(1).build().execute();// 4. 解析数据Aggreagtions aggreagtions response.getAggreagtions();// 注意ParsedStringTerms还有ParsedLongTerms、ParsedDoubleTerms...ParsedStringTerms CityName aggreagtions.get(CityName);for (Terms.Bucket bucket : CityName.getBuckets()) {//打印结果是西安 或者 上海System.out.println(bucket.getKeyAsString());}ParsedStringTerms BrandName aggreagtions.get(BrandName);for (Terms.Bucket bucket : BrandName.getBuckets()) {//打印结果是星巴克 或者 瑞幸System.out.println(bucket.getKeyAsString());}}这里需要解释一下步骤四中的 ParsedStringTerms
ES会将聚合结果封装到特定的类中方便你来处理不同类型的聚合结果。 ParsedLongTerms: 这个类用于处理长整型long类型的聚合结果。 ParsedStringTerms: 这个类用于处理字符串String类型的聚合结果。 什么意思呢在ES中对CityName进行聚合。 返回结果中可以看到如下信息表示星巴克有三家西安 key“星巴克” 字符串类型 doc_count : 3 long类型 因此根据key的类型正确选择使用ParsedStringTerms || ParsedLongTerms ||…接收聚合结果否则报错。 示例图