| | |
| | | import cn.lili.base.Result; |
| | | import cn.lili.cache.Cache; |
| | | import cn.lili.cache.CachePrefix; |
| | | import cn.lili.common.enums.PromotionTypeEnum; |
| | | import cn.lili.common.exception.ServiceException; |
| | | import cn.lili.common.security.context.UserContext; |
| | | import cn.lili.common.vo.PageVO; |
| | | import cn.lili.modules.goods.entity.enums.GoodsAuthEnum; |
| | | import cn.lili.modules.goods.entity.enums.GoodsStatusEnum; |
| | | import cn.lili.modules.lmk.domain.query.VideoGoodsEsQuery; |
| | | import cn.lili.modules.promotion.entity.dos.Coupon; |
| | | import cn.lili.modules.promotion.entity.enums.PromotionsScopeTypeEnum; |
| | | import cn.lili.modules.promotion.service.CouponService; |
| | | import cn.lili.modules.search.entity.dos.EsGoodsIndex; |
| | | import cn.lili.modules.search.entity.dos.EsGoodsRelatedInfo; |
| | | import cn.lili.modules.search.entity.dto.EsGoodsSearchDTO; |
| | |
| | | import cn.lili.modules.search.service.EsGoodsSearchService; |
| | | import cn.lili.modules.search.utils.SqlFilter; |
| | | import com.alibaba.druid.util.StringUtils; |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.lucene.search.join.ScoreMode; |
| | |
| | | import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.LocalDate; |
| | | import java.time.ZoneId; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | |
| | | @Autowired |
| | | private Cache<Object> cache; |
| | | |
| | | @Autowired |
| | | private CouponService couponService; |
| | | |
| | | @Override |
| | | public SearchPage<EsGoodsIndex> searchGoods(EsGoodsSearchDTO searchDTO, PageVO pageVo) { |
| | | |
| | |
| | | cache.incrementScore(CachePrefix.HOT_WORD.getPrefix(), searchDTO.getKeyword()); |
| | | } |
| | | NativeSearchQueryBuilder searchQueryBuilder = createSearchQueryBuilder(searchDTO, pageVo); |
| | | // searchQueryBuilder.withCollapseField("goodsId.keyword"); |
| | | if (Objects.nonNull(searchDTO.getCanFilter()) && searchDTO.getCanFilter()) { |
| | | // 使用sn字段排序并在折叠时选择sn最小的记录 |
| | | searchQueryBuilder.withCollapseField("goodsId.keyword"); |
| | | searchQueryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.ASC)); |
| | | } |
| | | NativeSearchQuery searchQuery = searchQueryBuilder.build(); |
| | | searchQuery.setTrackTotalHits(true); |
| | | log.debug("searchGoods DSL:{}", searchQuery.getQuery()); |
| | | log.info("searchGoods DSL:{}", searchQuery.getQuery().toString()); |
| | | log.info("searchGoods sort:{}", searchQuery.getElasticsearchSorts().toString()); |
| | | SearchHits<EsGoodsIndex> search = restTemplate.search(searchQuery, EsGoodsIndex.class); |
| | | return SearchHitSupport.searchPageFor(search, searchQuery.getPageable()); |
| | | } |
| | | |
| | | @Override |
| | | public Page<EsGoodsIndex> searchGoodsByPage(EsGoodsSearchDTO searchDTO, PageVO pageVo) { |
| | | if (PromotionTypeEnum.COUPON.name().equals(searchDTO.getPromotionType())) { |
| | | Coupon coupon = couponService.getById(searchDTO.getPromotionsId()); |
| | | if (coupon != null) { |
| | | if (PromotionsScopeTypeEnum.ALL.name().equals(coupon.getScopeType())) { |
| | | searchDTO.setPromotionType(null); |
| | | searchDTO.setPromotionsId(null); |
| | | } else if (PromotionsScopeTypeEnum.PORTION_GOODS.name().equals(coupon.getScopeType())) { |
| | | String promotionsId = coupon.getScopeId(); |
| | | if (cn.lili.common.utils.StringUtils.isNotBlank(promotionsId)) { |
| | | List<String> skuIds = new ArrayList<>(Arrays.asList(promotionsId.split(","))); |
| | | Page<EsGoodsIndex> resultPage = new Page<>(); |
| | | List<EsGoodsIndex> esGoodsBySkuIds = getEsGoodsBySkuIds(skuIds, pageVo); |
| | | System.err.println(JSON.toJSONString(esGoodsBySkuIds)); |
| | | resultPage.setRecords(esGoodsBySkuIds); |
| | | resultPage.setPages(1); |
| | | resultPage.setCurrent(1); |
| | | resultPage.setSize(1); |
| | | resultPage.setTotal(esGoodsBySkuIds.size()); |
| | | return resultPage; |
| | | } |
| | | } else if (PromotionsScopeTypeEnum.PORTION_SHOP_CATEGORY.name().equals(coupon.getScopeType())) { |
| | | searchDTO.setPromotionType(null); |
| | | searchDTO.setCategoryId(searchDTO.getPromotionsId()); |
| | | searchDTO.setPromotionsId(null); |
| | | } else if (PromotionsScopeTypeEnum.PORTION_GOODS_CATEGORY.name().equals(coupon.getScopeType())) { |
| | | String promotionsId = searchDTO.getPromotionsId(); |
| | | if (cn.lili.common.utils.StringUtils.isNotBlank(promotionsId)) { |
| | | searchDTO.setPromotionType(null); |
| | | searchDTO.setCategoryId(coupon.getScopeId()); |
| | | searchDTO.setPromotionsId(null); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | } |
| | | // 判断商品索引是否存在 |
| | | if (!restTemplate.indexOps(EsGoodsIndex.class).exists()) { |
| | | return null; |
| | |
| | | FunctionScoreQueryBuilder.FilterFunctionBuilder[] builders = new FunctionScoreQueryBuilder.FilterFunctionBuilder[filterFunctionBuilders.size()]; |
| | | filterFunctionBuilders.toArray(builders); |
| | | FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(QueryBuilders.matchAllQuery(), builders) |
| | | .scoreMode(FunctionScoreQuery.ScoreMode.SUM) |
| | | .setMinScore(2); |
| | | .scoreMode(FunctionScoreQuery.ScoreMode.SUM); |
| | | functionScoreQueryBuilder.setMinScore(0); |
| | | // if (CharSequenceUtil.isNotEmpty(searchDTO.getPromotionsId()) && CharSequenceUtil.isNotEmpty(searchDTO.getPromotionType())) { |
| | | // functionScoreQueryBuilder.setMinScore(0); |
| | | // }else if (cn.lili.common.utils.StringUtils.isNotBlank(searchDTO.getCategoryId())){ |
| | | // functionScoreQueryBuilder.setMinScore(0); |
| | | // } |
| | | // else { |
| | | // functionScoreQueryBuilder.setMinScore(2); |
| | | // } |
| | | //聚合搜索则将结果放入过滤条件 |
| | | filterBuilder.must(functionScoreQueryBuilder); |
| | | } else { |
| | |
| | | |
| | | |
| | | if (pageVo != null && CharSequenceUtil.isNotEmpty(pageVo.getOrder()) && CharSequenceUtil.isNotEmpty(pageVo.getSort())) { |
| | | nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(pageVo.getSort()).order(SortOrder.valueOf(pageVo.getOrder().toUpperCase()))); |
| | | nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(pageVo.getSort()).order(SortOrder.valueOf(pageVo.getOrder().toUpperCase())).missing("_last")); |
| | | } else { |
| | | nativeSearchQueryBuilder.withSort(SortBuilders.scoreSort().order(SortOrder.DESC)); |
| | | } |
| | |
| | | if (CharSequenceUtil.isNotEmpty(searchDTO.getPromotionsId()) && CharSequenceUtil.isNotEmpty(searchDTO.getPromotionType())) { |
| | | filterBuilder.must(QueryBuilders.wildcardQuery("promotionMapJson", "*" + searchDTO.getPromotionType() + "-" + searchDTO.getPromotionsId() + "*")); |
| | | } |
| | | |
| | | if (Objects.nonNull(searchDTO.getNeedFilterPre()) && searchDTO.getNeedFilterPre()) { |
| | | // 转换为当天 00:00:00 的时间戳(毫秒) |
| | | long time = LocalDate.now().atStartOfDay(ZoneId.systemDefault()) |
| | | .toInstant() |
| | | .toEpochMilli(); |
| | | // 条件2:预售结束时间 >= 当前时间 OR 结束时间为空 |
| | | filterBuilder.must(QueryBuilders.boolQuery() |
| | | .should(QueryBuilders.rangeQuery("preSaleEndDate").gte(time)) |
| | | .should(QueryBuilders.boolQuery() |
| | | .mustNot(QueryBuilders.existsQuery("preSaleEndDate")))); |
| | | // 条件1:预售开始时间 <= 当前时间 OR 开始时间为空 |
| | | filterBuilder.must(QueryBuilders.boolQuery() |
| | | .should(QueryBuilders.rangeQuery("preSaleBeginDate").lte(time)) |
| | | .should(QueryBuilders.boolQuery() |
| | | .mustNot(QueryBuilders.existsQuery("preSaleBeginDate")))); |
| | | } |
| | | //价格区间判定 |
| | | if (CharSequenceUtil.isNotEmpty(searchDTO.getPrice())) { |
| | | String[] prices = searchDTO.getPrice().split("_"); |
| | |
| | | filterFunctionBuilders.toArray(builders); |
| | | FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(goodsNameMatchQuery, builders) |
| | | .scoreMode(FunctionScoreQuery.ScoreMode.SUM) |
| | | .setMinScore(2); |
| | | .setMinScore(0); |
| | | //聚合搜索则将结果放入过滤条件 |
| | | filterBuilder.must(functionScoreQueryBuilder); |
| | | filterBuilder.should(QueryBuilders.boolQuery().should(QueryBuilders.matchPhraseQuery("goodsName", keyword).boost(10))); |