|
@@ -1,286 +0,0 @@
|
|
|
-package com.yonge.cooleshow.search.service.impl;
|
|
|
-
|
|
|
-import com.yonge.cooleshow.search.dao.EsProductDao;
|
|
|
-import com.yonge.cooleshow.search.domain.EsProduct;
|
|
|
-import com.yonge.cooleshow.search.domain.EsProductRelatedInfo;
|
|
|
-import com.yonge.cooleshow.search.repository.EsProductRepository;
|
|
|
-import com.yonge.cooleshow.search.service.EsProductService;
|
|
|
-import org.elasticsearch.common.lucene.search.function.FunctionScoreQuery;
|
|
|
-import org.elasticsearch.index.query.BoolQueryBuilder;
|
|
|
-import org.elasticsearch.index.query.QueryBuilders;
|
|
|
-import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
|
|
|
-import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
|
|
|
-import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
|
|
|
-import org.elasticsearch.search.aggregations.Aggregation;
|
|
|
-import org.elasticsearch.search.aggregations.AggregationBuilders;
|
|
|
-import org.elasticsearch.search.aggregations.bucket.filter.ParsedFilter;
|
|
|
-import org.elasticsearch.search.aggregations.bucket.nested.ParsedNested;
|
|
|
-import org.elasticsearch.search.aggregations.bucket.terms.ParsedLongTerms;
|
|
|
-import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms;
|
|
|
-import org.elasticsearch.search.aggregations.bucket.terms.Terms;
|
|
|
-import org.elasticsearch.search.sort.SortBuilders;
|
|
|
-import org.elasticsearch.search.sort.SortOrder;
|
|
|
-import org.slf4j.Logger;
|
|
|
-import org.slf4j.LoggerFactory;
|
|
|
-import org.springframework.beans.factory.annotation.Autowired;
|
|
|
-import org.springframework.data.domain.Page;
|
|
|
-import org.springframework.data.domain.PageImpl;
|
|
|
-import org.springframework.data.domain.PageRequest;
|
|
|
-import org.springframework.data.domain.Pageable;
|
|
|
-import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
|
|
|
-import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
|
|
|
-import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
|
|
|
-import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
|
|
|
-import org.springframework.stereotype.Service;
|
|
|
-import org.springframework.util.CollectionUtils;
|
|
|
-import org.springframework.util.StringUtils;
|
|
|
-
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.Iterator;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
-
|
|
|
-
|
|
|
-/**
|
|
|
- * 搜索商品管理Service实现类
|
|
|
- * Created by macro on 2018/6/19.
|
|
|
- */
|
|
|
-@Service
|
|
|
-public class EsProductServiceImpl implements EsProductService {
|
|
|
- private static final Logger LOGGER = LoggerFactory.getLogger(EsProductServiceImpl.class);
|
|
|
- @Autowired
|
|
|
- private EsProductDao productDao;
|
|
|
- @Autowired
|
|
|
- private EsProductRepository productRepository;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private ElasticsearchTemplate elasticsearchTemplate;
|
|
|
- @Override
|
|
|
- public int importAll() {
|
|
|
- List<EsProduct> esProductList = productDao.getAllEsProductList(null);
|
|
|
- Iterable<EsProduct> esProductIterable = productRepository.saveAll(esProductList);
|
|
|
- Iterator<EsProduct> iterator = esProductIterable.iterator();
|
|
|
- int result = 0;
|
|
|
- while (iterator.hasNext()) {
|
|
|
- result++;
|
|
|
- iterator.next();
|
|
|
- }
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void delete(Long id) {
|
|
|
- productRepository.deleteById(id);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public EsProduct create(Long id) {
|
|
|
- EsProduct result = null;
|
|
|
- List<EsProduct> esProductList = productDao.getAllEsProductList(id);
|
|
|
- if (esProductList.size() > 0) {
|
|
|
- EsProduct esProduct = esProductList.get(0);
|
|
|
- result = productRepository.save(esProduct);
|
|
|
- }
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void delete(List<Long> ids) {
|
|
|
- if (!CollectionUtils.isEmpty(ids)) {
|
|
|
- List<EsProduct> esProductList = new ArrayList<>();
|
|
|
- for (Long id : ids) {
|
|
|
- EsProduct esProduct = new EsProduct();
|
|
|
- esProduct.setId(id);
|
|
|
- esProductList.add(esProduct);
|
|
|
- }
|
|
|
- productRepository.deleteAll(esProductList);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Page<EsProduct> search(String keyword, Integer pageNum, Integer pageSize) {
|
|
|
- Pageable pageable = PageRequest.of(pageNum, pageSize);
|
|
|
- return productRepository.findByNameOrSubTitleOrKeywords(keyword, keyword, keyword, pageable);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Page<EsProduct> search(String keyword, Long brandId, Long productCategoryId, Integer pageNum, Integer pageSize,Integer sort) {
|
|
|
- Pageable pageable = PageRequest.of(pageNum, pageSize);
|
|
|
- NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
|
|
|
- //分页
|
|
|
- nativeSearchQueryBuilder.withPageable(pageable);
|
|
|
- //过滤
|
|
|
- if (brandId != null || productCategoryId != null) {
|
|
|
- BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
|
|
|
- if (brandId != null) {
|
|
|
- boolQueryBuilder.must(QueryBuilders.termQuery("brandId", brandId));
|
|
|
- }
|
|
|
- if (productCategoryId != null) {
|
|
|
- boolQueryBuilder.must(QueryBuilders.termQuery("productCategoryId", productCategoryId));
|
|
|
- }
|
|
|
- nativeSearchQueryBuilder.withFilter(boolQueryBuilder);
|
|
|
- }
|
|
|
- //搜索
|
|
|
- if (StringUtils.isEmpty(keyword)) {
|
|
|
- nativeSearchQueryBuilder.withQuery(QueryBuilders.matchAllQuery());
|
|
|
- } else {
|
|
|
- List<FunctionScoreQueryBuilder.FilterFunctionBuilder> filterFunctionBuilders = new ArrayList<>();
|
|
|
- filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.matchQuery("name", keyword),
|
|
|
- ScoreFunctionBuilders.weightFactorFunction(10)));
|
|
|
- filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.matchQuery("subTitle", keyword),
|
|
|
- ScoreFunctionBuilders.weightFactorFunction(5)));
|
|
|
- filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.matchQuery("keywords", keyword),
|
|
|
- ScoreFunctionBuilders.weightFactorFunction(2)));
|
|
|
- FunctionScoreQueryBuilder.FilterFunctionBuilder[] builders = new FunctionScoreQueryBuilder.FilterFunctionBuilder[filterFunctionBuilders.size()];
|
|
|
- filterFunctionBuilders.toArray(builders);
|
|
|
- FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(builders)
|
|
|
- .scoreMode(FunctionScoreQuery.ScoreMode.SUM)
|
|
|
- .setMinScore(2);
|
|
|
- nativeSearchQueryBuilder.withQuery(functionScoreQueryBuilder);
|
|
|
- }
|
|
|
- //排序
|
|
|
- if(sort==1){
|
|
|
- //按新品从新到旧
|
|
|
- nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort("id").order(SortOrder.DESC));
|
|
|
- }else if(sort==2){
|
|
|
- //按销量从高到低
|
|
|
- nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort("sale").order(SortOrder.DESC));
|
|
|
- }else if(sort==3){
|
|
|
- //按价格从低到高
|
|
|
- nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.ASC));
|
|
|
- }else if(sort==4){
|
|
|
- //按价格从高到低
|
|
|
- nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.DESC));
|
|
|
- }else{
|
|
|
- //按相关度
|
|
|
- nativeSearchQueryBuilder.withSort(SortBuilders.scoreSort().order(SortOrder.DESC));
|
|
|
- }
|
|
|
- nativeSearchQueryBuilder.withSort(SortBuilders.scoreSort().order(SortOrder.DESC));
|
|
|
- NativeSearchQuery searchQuery = nativeSearchQueryBuilder.build();
|
|
|
- LOGGER.info("DSL:{}", searchQuery.getQuery().toString());
|
|
|
- searchQuery.setPageable(pageable);
|
|
|
- Page<EsProduct> searchHits = productRepository.search(searchQuery);
|
|
|
- if(searchHits.getTotalElements()<=0){
|
|
|
- return new PageImpl<>(null,pageable,0);
|
|
|
- }
|
|
|
- return searchHits;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Page<EsProduct> recommend(Long id, Integer pageNum, Integer pageSize) {
|
|
|
- Pageable pageable = PageRequest.of(pageNum, pageSize);
|
|
|
- List<EsProduct> esProductList = productDao.getAllEsProductList(id);
|
|
|
- if (esProductList.size() > 0) {
|
|
|
- EsProduct esProduct = esProductList.get(0);
|
|
|
- String keyword = esProduct.getName();
|
|
|
- Long brandId = esProduct.getBrandId();
|
|
|
- Long productCategoryId = esProduct.getProductCategoryId();
|
|
|
- //根据商品标题、品牌、分类进行搜索
|
|
|
- List<FunctionScoreQueryBuilder.FilterFunctionBuilder> filterFunctionBuilders = new ArrayList<>();
|
|
|
- filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.matchQuery("name", keyword),
|
|
|
- ScoreFunctionBuilders.weightFactorFunction(8)));
|
|
|
- filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.matchQuery("subTitle", keyword),
|
|
|
- ScoreFunctionBuilders.weightFactorFunction(2)));
|
|
|
- filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.matchQuery("keywords", keyword),
|
|
|
- ScoreFunctionBuilders.weightFactorFunction(2)));
|
|
|
- filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.matchQuery("brandId", brandId),
|
|
|
- ScoreFunctionBuilders.weightFactorFunction(5)));
|
|
|
- filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.matchQuery("productCategoryId", productCategoryId),
|
|
|
- ScoreFunctionBuilders.weightFactorFunction(3)));
|
|
|
- FunctionScoreQueryBuilder.FilterFunctionBuilder[] builders = new FunctionScoreQueryBuilder.FilterFunctionBuilder[filterFunctionBuilders.size()];
|
|
|
- filterFunctionBuilders.toArray(builders);
|
|
|
- FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(builders)
|
|
|
- .scoreMode(FunctionScoreQuery.ScoreMode.SUM)
|
|
|
- .setMinScore(2);
|
|
|
- //用于过滤掉相同的商品
|
|
|
- BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
|
|
|
- boolQueryBuilder.mustNot(QueryBuilders.termQuery("id",id));
|
|
|
- //构建查询条件
|
|
|
- NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
|
|
|
- builder.withQuery(functionScoreQueryBuilder);
|
|
|
- builder.withFilter(boolQueryBuilder);
|
|
|
- builder.withPageable(pageable);
|
|
|
- NativeSearchQuery searchQuery = builder.build();
|
|
|
- LOGGER.info("DSL:{}", searchQuery.getQuery().toString());
|
|
|
- searchQuery.setPageable(pageable);
|
|
|
- Page<EsProduct> searchHits = productRepository.search(searchQuery);
|
|
|
- if(searchHits.getTotalElements()<=0){
|
|
|
- return new PageImpl<>(null,pageable,0);
|
|
|
- }
|
|
|
- return searchHits;
|
|
|
- }
|
|
|
- return new PageImpl<>(null);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public EsProductRelatedInfo searchRelatedInfo(String keyword) {
|
|
|
- NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
|
|
|
- //搜索条件
|
|
|
- if(StringUtils.isEmpty(keyword)){
|
|
|
- builder.withQuery(QueryBuilders.matchAllQuery());
|
|
|
- }else{
|
|
|
- builder.withQuery(QueryBuilders.multiMatchQuery(keyword,"name","subTitle","keywords"));
|
|
|
- }
|
|
|
- //聚合搜索品牌名称
|
|
|
- builder.addAggregation(AggregationBuilders.terms("brandNames").field("brandName"));
|
|
|
- //集合搜索分类名称
|
|
|
- builder.addAggregation(AggregationBuilders.terms("productCategoryNames").field("productCategoryName"));
|
|
|
- //聚合搜索商品属性,去除type=1的属性
|
|
|
- AbstractAggregationBuilder aggregationBuilder = AggregationBuilders.nested("allAttrValues","attrValueList")
|
|
|
- .subAggregation(AggregationBuilders.filter("productAttrs",QueryBuilders.termQuery("attrValueList.type",1))
|
|
|
- .subAggregation(AggregationBuilders.terms("attrIds")
|
|
|
- .field("attrValueList.productAttributeId")
|
|
|
- .subAggregation(AggregationBuilders.terms("attrValues")
|
|
|
- .field("attrValueList.value"))
|
|
|
- .subAggregation(AggregationBuilders.terms("attrNames")
|
|
|
- .field("attrValueList.name"))));
|
|
|
- builder.addAggregation(aggregationBuilder);
|
|
|
- NativeSearchQuery searchQuery = builder.build();
|
|
|
- AggregatedPage<EsProduct> searchHits = elasticsearchTemplate.queryForPage(searchQuery, EsProduct.class);
|
|
|
- return convertProductRelatedInfo(searchHits);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 将返回结果转换为对象
|
|
|
- */
|
|
|
- private EsProductRelatedInfo convertProductRelatedInfo(AggregatedPage<EsProduct> response) {
|
|
|
- EsProductRelatedInfo productRelatedInfo = new EsProductRelatedInfo();
|
|
|
- Map<String, Aggregation> aggregationMap = response.getAggregations().getAsMap();
|
|
|
- //设置品牌
|
|
|
- Aggregation brandNames = aggregationMap.get("brandNames");
|
|
|
- List<String> brandNameList = new ArrayList<>();
|
|
|
- for(int i = 0; i<((Terms) brandNames).getBuckets().size(); i++){
|
|
|
- brandNameList.add(((Terms) brandNames).getBuckets().get(i).getKeyAsString());
|
|
|
- }
|
|
|
- productRelatedInfo.setBrandNames(brandNameList);
|
|
|
- //设置分类
|
|
|
- Aggregation productCategoryNames = aggregationMap.get("productCategoryNames");
|
|
|
- List<String> productCategoryNameList = new ArrayList<>();
|
|
|
- for(int i=0;i<((Terms) productCategoryNames).getBuckets().size();i++){
|
|
|
- productCategoryNameList.add(((Terms) productCategoryNames).getBuckets().get(i).getKeyAsString());
|
|
|
- }
|
|
|
- productRelatedInfo.setProductCategoryNames(productCategoryNameList);
|
|
|
- //设置参数
|
|
|
- Aggregation productAttrs = aggregationMap.get("allAttrValues");
|
|
|
- List<? extends Terms.Bucket> attrIds = ((ParsedLongTerms) ((ParsedFilter) ((ParsedNested) productAttrs).getAggregations().get("productAttrs")).getAggregations().get("attrIds")).getBuckets();
|
|
|
- List<EsProductRelatedInfo.ProductAttr> attrList = new ArrayList<>();
|
|
|
- for (Terms.Bucket attrId : attrIds) {
|
|
|
- EsProductRelatedInfo.ProductAttr attr = new EsProductRelatedInfo.ProductAttr();
|
|
|
- attr.setAttrId((Long) attrId.getKey());
|
|
|
- List<String> attrValueList = new ArrayList<>();
|
|
|
- List<? extends Terms.Bucket> attrValues = ((ParsedStringTerms) attrId.getAggregations().get("attrValues")).getBuckets();
|
|
|
- List<? extends Terms.Bucket> attrNames = ((ParsedStringTerms) attrId.getAggregations().get("attrNames")).getBuckets();
|
|
|
- for (Terms.Bucket attrValue : attrValues) {
|
|
|
- attrValueList.add(attrValue.getKeyAsString());
|
|
|
- }
|
|
|
- attr.setAttrValues(attrValueList);
|
|
|
- if(!CollectionUtils.isEmpty(attrNames)){
|
|
|
- String attrName = attrNames.get(0).getKeyAsString();
|
|
|
- attr.setAttrName(attrName);
|
|
|
- }
|
|
|
- attrList.add(attr);
|
|
|
- }
|
|
|
- productRelatedInfo.setProductAttrs(attrList);
|
|
|
- return productRelatedInfo;
|
|
|
- }
|
|
|
-}
|