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调用:搜索的更多相关文章

  1. Elasticsearch 5.4.3实战--Java API调用:索引mapping创建

    因为项目开发使用的是Java语言, 项目的开发架构是Spring MVC+ maven的jar包管理,  所以今天重点说说ES 5.4.3 的Java API的源码实战 1. pom.xml文件增加依 ...

  2. Elasticsearch 5.4.3实战--Java API调用:搜索建议

    通常的搜索引擎,都会根据用户的输入,实时给予匹配的提示. 那么这个功能在elasticsearch中如何实现呢? Elasticsearch里设计了4种类别的Suggester,分别是: Term S ...

  3. Elasticsearch 5.4.3实战--Java API调用:批量写入数据

    这个其实比较简单,直接上代码. 注意部分逻辑可以换成你自己的逻辑 package com.cs99lzzs.elasticsearch.service.imp; import java.sql.Tim ...

  4. Elasticsearch java api 基本搜索部分详解

    文档是结合几个博客整理出来的,内容大部分为转载内容.在使用过程中,对一些疑问点进行了整理与解析. Elasticsearch java api 基本搜索部分详解 ElasticSearch 常用的查询 ...

  5. elasticsearch(一):JAVA api操作

    1.创建一个mavan项目,项目的以来配置如下. <?xml version="1.0" encoding="UTF-8"?> <projec ...

  6. ElasticSearch入门-增删改查(java api)

    1.增加Index PutMappingRequest mapping = Requests.putMappingRequest(indices).type(mappingType).source(g ...

  7. JAVA Api 调用Hbase报错锦集

    1. 报错 java.lang.NoClassDefFoundError: org/apache/hadoop/hbase/protobuf/generated/MasterProtos$Master ...

  8. java api 调用es集群(1.7版本)

    public static void main(String[] args) { Settings settings = ImmutableSettings.settingsBuilder() // ...

  9. Zookeeper Java API调用

    引入zookeeper-3.4.11.jar public class ZooKeeperTest implements Watcher{ //public final static String z ...

随机推荐

  1. 将 数据库中的结果集转换为json格式(三)

    从数据库中得到结果集 public String list() throws Exception { Connection con = null; PageBean pageBean = new Pa ...

  2. org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].Standard

    Caused by: java.lang.NoSuchMethodError: javax.servlet.ServletContext.getVirtualServerName()Ljava/lan ...

  3. springboot下整合各种配置文件

    本博是在springboot下整合其他中间件,比如,mq,redis,durid,日志...等等  以后遇到再更.springboot真是太便捷了,让我们赶紧涌入到springboot的怀抱吧. ap ...

  4. async+await处理异步问题

    在编写网页的时候我们常常会遇到异步问题,async+await是es6提出的解决异步的方法,下面我们来看看这个方法怎么实现解决异步的, 大家都知道,setTimeout是一个定时器.他是一个异步执行的 ...

  5. 解决 Ubuntu 经常 卡死

    ubuntu 的卡死可能与显卡驱动不兼容有关. 这里提供2种方式, 1.禁用原来自带的nouveau显卡驱动sudo gedit /etc/modprobe.d/blacklist.conf在最后一行 ...

  6. HDU 1031(服装打分 **)

    题意是有 n 个人要对 m 件服装打分,按总分从高到低排序,再将总分排在前 k 名的服装按编号的从高到低输出,结构体排序. 代码如下: #include <bits/stdc++.h> u ...

  7. HDU 3371(城市联通 最小生成树-Kruskal)

    题意是求将所有点联通所花费的最小金额,如不能完全联通,输出 -1 直接Kruskal,本题带来的一点教训是 rank 是algorithm头文件里的,直接做变量名会导致编译错误.没查到 rank 的具 ...

  8. 056、macvlan网络结构分析(2019-03-25 周一)

    参考https://www.cnblogs.com/CloudMan6/p/7383919.html   macvlan不依赖linux bridge   brctl show 可以确认没有创建新的b ...

  9. git多人协作式开发时分支管理策略

    什么是 git-flow? Git Flow是一套使用Git进行源代码管理时的一套行为规范 主分支Master 首先,代码库应该有一个.且仅有一个主分支.所有提供给用户使用的正式版本,都在这个主分支上 ...

  10. springboot(十四):springboot整合mybatis

    org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'multipart/form-data;bounda ...