Elasticsearch 5.4.3实战--Java API调用:搜索
ES有多种查询方式,我自己的业务是需要对多个字段进行查询,具体实现类代码如下。
package com.cs99lzzs.elasticsearch.service.imp; import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map; import javax.annotation.Resource; import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.client.Client;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms.Bucket;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.search.suggest.Suggest;
import org.elasticsearch.search.suggest.SuggestBuilder;
import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import com.alibaba.fastjson.JSON;
import com.cs99lzzs.elasticsearch.service.ProductSearchService;
import com.cs99lzzs.search.ElasticseachSku;
import com.cs99lzzs.search.EsProductQuery;
import com.cs99lzzs.search.EsResultingSku;
import com.cs99lzzs.search.vo.FacetVO;
import com.cs99lzzs.search.vo.SearchResultVO; @Service("productSearchService")
public class ProductSearchServiceImp implements ProductSearchService { private static Logger logger = Logger.getLogger(ProductSearchService.class); private static String aggrationBrandName = "brand_count"; private static String suggestZhName = "suggestName"; @Resource(name="esClient")
Client esClient; @Value("${elasticsearch.index}")
private String CLUSTER_INDEX; @Value("${elasticsearch.type}")
private String CLUSTER_TYPE; /**
* @return
*/
@SuppressWarnings("rawtypes")
@Override
public SearchResultVO get(EsProductQuery esProductQuery) {
if (esProductQuery == null ||
(StringUtils.isEmpty(esProductQuery.getKeyword())
&& StringUtils.isEmpty(esProductQuery.getCateName())
&& StringUtils.isEmpty(esProductQuery.getBrandName()))) {
return null;
}
//生成搜索条件
QueryBuilder boolQuery = generateBoolQuery(esProductQuery, null); //浅度分页,越到后面,反应越慢,还有可能导致es崩溃
SearchRequestBuilder srb = esClient.prepareSearch(CLUSTER_INDEX)
.setTypes(CLUSTER_TYPE)
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
.setQuery(boolQuery)
// .setPostFilter(QueryBuilders.rangeQuery("age").from(12).to(18))
.setExplain(true) //explain为true表示根据数据相关度排序,和关键字匹配最高的排在前面
.setFrom((esProductQuery.getPage() - 1) * esProductQuery.getPageSize())
.setSize(esProductQuery.getPageSize()); //获取排序规则
SortBuilder sortBuilder = getSortBuilder(esProductQuery);
if (sortBuilder != null) {
srb.addSort(sortBuilder);
} //按品牌名聚合
TermsAggregationBuilder termAgg = AggregationBuilders.terms(aggrationBrandName).field("brandName");
srb.addAggregation(termAgg); //执行搜索
SearchResponse actionGet = srb.execute().actionGet(); //深度分页,推荐实现
// SearchScrollRequestBuilder ssrb = esClient.prepareSearchScroll(actionGet.getScrollId())
// .setScroll(TimeValue.timeValueMinutes(8));
//获取查询结果,生成返回对象
List<EsResultingSku> skuList = new ArrayList<EsResultingSku>();
DecimalFormat priceFormat = new DecimalFormat("#0.00");
DecimalFormat discountFormat = new DecimalFormat("#0.0"); SearchHit[] hitArray = actionGet.getHits().getHits();
for (SearchHit searchHit : hitArray) {
ElasticseachSku eSku = JSON.parseObject(searchHit.getSourceAsString(), ElasticseachSku.class);
if (eSku != null) {
skuList.add(new EsResultingSku(eSku, discountFormat, priceFormat));
}
} SearchResultVO resultVO = new SearchResultVO();
resultVO.setSkus(skuList);
//总页数
long totalPage = actionGet.getHits().totalHits/esProductQuery.getPageSize();
if ((actionGet.getHits().totalHits % esProductQuery.getPageSize()) != 0) {
totalPage ++;
}
resultVO.setTotalPages(totalPage);
resultVO.setHits(actionGet.getHits().totalHits);
if (skuList.size() > 1) {
setFacetVOs(actionGet, resultVO);
} return resultVO;
}
/**
* @return
*/
@Override
public SearchResultVO get(String keyword, int page, int pageSize) {
if (StringUtils.isEmpty(keyword)) {
return null;
} //生成搜索条件
QueryBuilder boolQuery = generateBoolQuery(null, keyword); //浅度分页,越到后面,反应越慢,还有可能导致es崩溃
SearchRequestBuilder srb = esClient.prepareSearch(CLUSTER_INDEX)
.setTypes(CLUSTER_TYPE)
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
.setQuery(boolQuery)
// .setPostFilter(QueryBuilders.rangeQuery("age").from(12).to(18))
.setExplain(true) //explain为true表示根据数据相关度排序,和关键字匹配最高的排在前面
.setFrom((page - 1) * pageSize)
.setSize(pageSize); //按品牌名聚合
TermsAggregationBuilder termAgg = AggregationBuilders.terms(aggrationBrandName).field("brandName");
srb.addAggregation(termAgg); //执行搜索
SearchResponse actionGet = srb.execute().actionGet(); //深度分页,推荐实现
// SearchScrollRequestBuilder ssrb = esClient.prepareSearchScroll(actionGet.getScrollId())
// .setScroll(TimeValue.timeValueMinutes(8));
//获取查询结果,生成返回对象
List<EsResultingSku> skuList = new ArrayList<EsResultingSku>();
DecimalFormat priceFormat = new DecimalFormat("#0.00");
DecimalFormat discountFormat = new DecimalFormat("#0.0"); SearchHit[] hitArray = actionGet.getHits().getHits();
for (SearchHit searchHit : hitArray) {
ElasticseachSku eSku = JSON.parseObject(searchHit.getSourceAsString(), ElasticseachSku.class);
if (eSku != null) {
skuList.add(new EsResultingSku(eSku, discountFormat, priceFormat));
}
} SearchResultVO resultVO = new SearchResultVO();
resultVO.setSkus(skuList);
//总页数
long totalPage = actionGet.getHits().totalHits/pageSize;
if ((actionGet.getHits().totalHits % pageSize) != 0) {
totalPage ++;
}
resultVO.setTotalPages(totalPage);
resultVO.setHits(actionGet.getHits().totalHits); return resultVO;
} /**
* @param esProductQuery
* @param keyword
* @return
*/
private QueryBuilder generateBoolQuery(EsProductQuery esProductQuery, String key) { String keyword = null;
if (esProductQuery != null && esProductQuery.getKeyword() != null) {
keyword = QueryParser.escape(esProductQuery.getKeyword());
}
if (StringUtils.isNotEmpty(key)) {
keyword = QueryParser.escape(key);
} logger.info("filtered keyword is : " + keyword); //其他搜索条件
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
if (esProductQuery != null) {
if (esProductQuery.getIsDelete() == 1) {
boolQueryBuilder.must(QueryBuilders.termQuery("isDelete", true));
} else if (esProductQuery.getIsDelete() == -1) {
boolQueryBuilder.must(QueryBuilders.termQuery("isDelete", false));
}
if (esProductQuery.getSearchable() == 1) {
boolQueryBuilder.must(QueryBuilders.termQuery("searchable", true));
} else if (esProductQuery.getIsDelete() == -1) {
boolQueryBuilder.must(QueryBuilders.termQuery("searchable", false));
}
if (StringUtils.isNotEmpty(esProductQuery.getBrandName())) {
boolQueryBuilder.must(QueryBuilders.termQuery("brandName", QueryParser.escape(esProductQuery.getBrandName())));
}
if (StringUtils.isNotEmpty(esProductQuery.getCateName())) {
boolQueryBuilder.must(QueryBuilders.termQuery("cateName", QueryParser.escape(esProductQuery.getCateName())));
}
} else {
boolQueryBuilder.must(QueryBuilders.termQuery("isDelete", false));
boolQueryBuilder.must(QueryBuilders.termQuery("searchable", true));
} QueryBuilder multiMatchQuery = null;
if (StringUtils.isNotEmpty(keyword)) {
multiMatchQuery = QueryBuilders.multiMatchQuery(keyword,
"enName", "zhName","brandZhName", "brandEnName", "aliases", "brandAliases");
} if (multiMatchQuery == null) {
return boolQueryBuilder;
} else {
return boolQueryBuilder.must(multiMatchQuery);
}
}
/**
* @param sortByPrice
* @param sortByCommission
* @param sortBySalesVolume
* @return
*/
@SuppressWarnings("rawtypes")
private SortBuilder getSortBuilder(EsProductQuery esProductQuery) {
switch (esProductQuery.getSortByPrice()) {
case -1:
return SortBuilders.fieldSort("price").order(SortOrder.DESC);
case 1:
return SortBuilders.fieldSort("price").order(SortOrder.ASC);
default:
break;
} switch (esProductQuery.getSortByCommission()) {
case -1:
return SortBuilders.fieldSort("commission").order(SortOrder.DESC);
case 1:
return SortBuilders.fieldSort("commission").order(SortOrder.ASC);
default:
break;
} switch (esProductQuery.getSortByCommission()) {
case -1:
return SortBuilders.fieldSort("salesVolume").order(SortOrder.DESC);
case 1:
return SortBuilders.fieldSort("salesVolume").order(SortOrder.ASC);
default:
break;
}
return null;
} }
有什么问题我们可以好好讨论
Elasticsearch 5.4.3实战--Java API调用:搜索的更多相关文章
- Elasticsearch 5.4.3实战--Java API调用:索引mapping创建
因为项目开发使用的是Java语言, 项目的开发架构是Spring MVC+ maven的jar包管理, 所以今天重点说说ES 5.4.3 的Java API的源码实战 1. pom.xml文件增加依 ...
- Elasticsearch 5.4.3实战--Java API调用:搜索建议
通常的搜索引擎,都会根据用户的输入,实时给予匹配的提示. 那么这个功能在elasticsearch中如何实现呢? Elasticsearch里设计了4种类别的Suggester,分别是: Term S ...
- Elasticsearch 5.4.3实战--Java API调用:批量写入数据
这个其实比较简单,直接上代码. 注意部分逻辑可以换成你自己的逻辑 package com.cs99lzzs.elasticsearch.service.imp; import java.sql.Tim ...
- Elasticsearch java api 基本搜索部分详解
文档是结合几个博客整理出来的,内容大部分为转载内容.在使用过程中,对一些疑问点进行了整理与解析. Elasticsearch java api 基本搜索部分详解 ElasticSearch 常用的查询 ...
- elasticsearch(一):JAVA api操作
1.创建一个mavan项目,项目的以来配置如下. <?xml version="1.0" encoding="UTF-8"?> <projec ...
- ElasticSearch入门-增删改查(java api)
1.增加Index PutMappingRequest mapping = Requests.putMappingRequest(indices).type(mappingType).source(g ...
- JAVA Api 调用Hbase报错锦集
1. 报错 java.lang.NoClassDefFoundError: org/apache/hadoop/hbase/protobuf/generated/MasterProtos$Master ...
- java api 调用es集群(1.7版本)
public static void main(String[] args) { Settings settings = ImmutableSettings.settingsBuilder() // ...
- Zookeeper Java API调用
引入zookeeper-3.4.11.jar public class ZooKeeperTest implements Watcher{ //public final static String z ...
随机推荐
- [报错]Could not get a resource from the pool
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool解决:开启 ...
- POJ3662 SPFA//二分 + 双端队列最短路
https://cn.vjudge.net/problem/12427/origin 题意:求1到N第K + 1大条边权最小的路径 首先想到dp递推,dp[x][y]表示到x这个点经过y条免费边的最小 ...
- 剑指Offer_编程题_10
题目描述 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形.请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? class Solution { public: int r ...
- Windows Dll Injection、Process Injection、API Hook、DLL后门/恶意程序入侵技术
catalogue 1. 引言2. 使用注册表注入DLL3. 使用Windows挂钩来注入DLL4. 使用远程线程来注入DLL5. 使用木马DLL来注入DLL6. 把DLL作为调试器来注入7. 使用c ...
- hadoop mapreduce 基础实例一记词
mapreduce实现一个简单的单词计数的功能. 一,准备工作:eclipse 安装hadoop 插件: 下载相关版本的hadoop-eclipse-plugin-2.2.0.jar到eclipse/ ...
- weblogic创建控制台启动脚本以及创建服务器
一.创建控制台脚本 二.创建认证文件 通过上面创建的脚本进行启动的时候,会因为密码问题导致起不来,因为在startWebLogic.sh文件中,没有配置用户名和密码.而且通过上面创建的脚本,启动的时候 ...
- STM32学习笔记:【001】常见数据查阅
了方便开发学习,现整理在学习过程中经常查阅的资料 (注意,以下资料都可以在ST给出官方手册中查到) 本人所持型号:STM32F429ZI-DISCOVERY, 芯片内核 :Cortex - ...
- HDU 1018(阶乘位数 数学)
题意是求 n 的阶乘的位数. 直接求 n 的阶乘再求其位数是不行的,开始时思路很扯淡,想直接用一个数组存每个数阶乘的位数,用变量 tmp 去存 n 与 n - 1 的阶乘的最高位的数的乘积,那么 n ...
- tomcat cluster session同步时保存map数据遇到的问题
Tomcat Cluster官网:https://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html(tomcat7.0) 场景: tomcat1 ...
- Mac 开发使用中的小技巧收集
1. mac 下ssh连接到 linux 服务器管理,同putty,无需第三方 Mac 下打开终端,输入: ssh 登录用户名@ip地址 如: ssh root@142.138.1.89 如有询问是否 ...