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. css换行

    1. word-break:break-all;只对英文起作用,以字母作为换行依据 2. word-wrap:break-word; 只对英文起作用,以单词作为换行依据 3. white-space: ...

  2. 反汇编Dis解析

    目录 反汇编dis解析 COMM段BSS段 注释段 Bl指令 title: 反汇编Dis解析 tags: ARM date: 2018-10-21 18:02:58 --- 反汇编dis解析 关于段, ...

  3. python操作execl学习笔记(一)

    本节只记录关于execl的读操作: execl 内容及格式 python3 #!/usr/bin/env python #-*- coding:utf-8 -*- import xlrd import ...

  4. 运维监控-使用Zabbix Server 添加自定义 item

    运维监控-使用Zabbix Server 监控自定义 item  作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客就直接开门见山如何使用Zabbix Server 监控自定义 ...

  5. 安装FreeIPA以及应用时报错汇总

    安装FreeIPA以及应用时报错汇总 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.ERROR DNS zone yinzhengjie.org.cn already exis ...

  6. NGINX X-Forwarded-For / XFF / xforword

    s https://en.wikipedia.org/wiki/X-Forwarded-For http://www.cnblogs.com/yihang/archive/2010/12/19/191 ...

  7. [Android] Android 使用 Greendao 操作 db sqlite

    Android 使用 Greendao 操作 db sqlite GreenDAO是一个开源的安卓ORM框架,能够使SQLite数据库的开发再次变得有趣.它减轻开发人员处理低级数据库需求,同时节省开发 ...

  8. Greendao 缓存问题

    GreenDao在使用过程中如果查询数据后,修改数据,再次查询的话,使用的是刚才修改后的数据,为了避免这个问题,要清除缓存,清除缓存有两种方法 1.daoSession.clear(); 2.dao. ...

  9. WeUI0.6.0有一个Calendar在浏览器下无法直接打开问题

    主要原因是判断浏览器不支持导致.修改isPopover相关部分代码即可.

  10. windows eclipse安装lombok插件

    1.下载lombok.jar,lombok.jar官方下载地址:https://projectlombok.org/download 2.双击下载好的lombak.jar,安装步骤如下: 2-1.关闭 ...