Commit dcc6aa0c74abac9a5f8c76c279fa412fb1244c9e
Merge remote-tracking branch 'origin/master'
Showing
1 changed file
with
71 additions
and
20 deletions
shop/src/main/java/com/canrd/shop/service/impl/ProductServiceImpl.java
... | ... | @@ -460,54 +460,105 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, ProductDO> im |
460 | 460 | Set<String> productIds = null; |
461 | 461 | Map<String,List<TicketTypeDO>> pId2ttDOsMap = null; |
462 | 462 | boolean needLikeMatch = false; |
463 | - if(StringUtils.isNotBlank(productQueryVO.getKeyword())){ | |
464 | - List<TicketTypeDO> tickeyTypeDOList = ticketTypeService.lambdaQuery().like(TicketTypeDO::getRank, productQueryVO.getKeyword()).list(); | |
463 | +// if(StringUtils.isNotBlank(productQueryVO.getKeyword())){ | |
464 | +// List<TicketTypeDO> tickeyTypeDOList = ticketTypeService.lambdaQuery().like(TicketTypeDO::getRank, productQueryVO.getKeyword()).list(); | |
465 | +// productIds = tickeyTypeDOList.stream().map(TicketTypeDO::getProductId).collect(Collectors.toSet()); | |
466 | +// needLikeMatch = true; | |
467 | +// pId2ttDOsMap = new HashMap<>(); | |
468 | +// for (TicketTypeDO ticketTypeDO : tickeyTypeDOList) { | |
469 | +// pId2ttDOsMap.computeIfAbsent(ticketTypeDO.getProductId(), k -> new ArrayList<>()); | |
470 | +// pId2ttDOsMap.get(ticketTypeDO.getProductId()).add(ticketTypeDO); | |
471 | +// } | |
472 | +// Set<String> finalProductIds = productIds; | |
473 | +// queryWapper.and(subQueryWapper -> { | |
474 | +// subQueryWapper.like("p.name", productQueryVO.getKeyword()).or().in(CollUtil.isNotEmpty(finalProductIds),"p.id", finalProductIds); | |
475 | +// }); | |
476 | +// } | |
477 | + String keyword = productQueryVO.getKeyword().trim(); | |
478 | + if (StringUtils.isNotBlank(productQueryVO.getKeyword())) { | |
479 | +// String keyword = productQueryVO.getKeyword().trim(); | |
480 | + | |
481 | + // 先精确匹配完整的关键字 | |
482 | + List<TicketTypeDO> tickeyTypeDOList = ticketTypeService.lambdaQuery() | |
483 | + .like(TicketTypeDO::getRank, keyword) | |
484 | + .list(); | |
485 | + | |
465 | 486 | productIds = tickeyTypeDOList.stream().map(TicketTypeDO::getProductId).collect(Collectors.toSet()); |
466 | 487 | needLikeMatch = true; |
467 | 488 | pId2ttDOsMap = new HashMap<>(); |
489 | + | |
468 | 490 | for (TicketTypeDO ticketTypeDO : tickeyTypeDOList) { |
469 | 491 | pId2ttDOsMap.computeIfAbsent(ticketTypeDO.getProductId(), k -> new ArrayList<>()); |
470 | 492 | pId2ttDOsMap.get(ticketTypeDO.getProductId()).add(ticketTypeDO); |
471 | 493 | } |
472 | - Set<String> finalProductIds = productIds; | |
473 | - queryWapper.and(subQueryWapper -> { | |
474 | - subQueryWapper.like("p.name", productQueryVO.getKeyword()).or().in(CollUtil.isNotEmpty(finalProductIds),"p.id", finalProductIds); | |
475 | - }); | |
494 | + | |
495 | + if (productIds.isEmpty()) { | |
496 | + // 如果没有匹配到,分词处理 | |
497 | + String[] keywords = keyword.split("\\s+"); | |
498 | + | |
499 | + queryWapper.and(subQueryWapper -> { | |
500 | + // 查询包含所有分词的记录 | |
501 | + for (String key : keywords) { | |
502 | + subQueryWapper.like("p.name", key).or(); | |
503 | + } | |
504 | + }); | |
505 | + } else { | |
506 | + Set<String> finalProductIds = productIds; | |
507 | + | |
508 | + queryWapper.and(subQueryWapper -> { | |
509 | + subQueryWapper.like("p.name", keyword).or().in(CollUtil.isNotEmpty(finalProductIds), "p.id", finalProductIds); | |
510 | + }); | |
511 | + } | |
476 | 512 | } |
477 | 513 | List<ProductDO> productDOS = this.baseMapper.queryList(queryWapper); |
514 | + // Split the keyword into individual words | |
515 | + String[] keywords = keyword.split("\\s+"); | |
516 | + Map<ProductDO, Integer> collect = productDOS.stream().collect(Collectors.toMap(Function.identity(), productDO -> { | |
517 | + int matchCount = 0; | |
518 | + for (String key : keywords) { | |
519 | + if (productDO.getName().toLowerCase().contains(key.toLowerCase())) { | |
520 | + matchCount++; | |
521 | + } | |
522 | + } | |
523 | + return matchCount; | |
524 | + })); | |
525 | + productDOS.sort((product1, product2) -> { | |
526 | + int matchCount1 = collect.get(product1); | |
527 | + int matchCount2 = collect.get(product2); | |
528 | + // Return the comparison result: higher match count comes first | |
529 | + return Integer.compare(matchCount2, matchCount1); | |
530 | + }); | |
478 | 531 | List<ProductDO> accurateProducts = Lists.newArrayList(); |
479 | 532 | Set<String> accurateProductIdSet = Sets.newHashSet(); |
480 | 533 | //区分大小写 |
481 | 534 | productDOS.forEach(x -> { |
482 | - if(x.getName().trim().contains(productQueryVO.getKeyword().trim())){ | |
483 | - accurateProducts.add(x); | |
484 | - accurateProductIdSet.add(x.getId()); | |
485 | - } | |
535 | + accurateProducts.add(x); | |
536 | + accurateProductIdSet.add(x.getId()); | |
486 | 537 | }); |
487 | 538 | List<ProductDO> similarProductList = Lists.newArrayList(); |
488 | - for(ProductDO product:productDOS){ | |
489 | - if(accurateProductIdSet.contains(product.getId())){ | |
539 | + for (ProductDO product : productDOS) { | |
540 | + if (accurateProductIdSet.contains(product.getId())) { | |
490 | 541 | continue; |
491 | 542 | } |
492 | 543 | String name = product.getName(); |
493 | - int similar = LevenshteinDistanceService.LevenshteinDistancePercent(productQueryVO.getKeyword(),name); | |
494 | - if(similar>=0) {//模糊匹配 | |
544 | + int similar = LevenshteinDistanceService.LevenshteinDistancePercent(productQueryVO.getKeyword(), name); | |
545 | + if (similar >= 0) {//模糊匹配 | |
495 | 546 | similarProductList.add(product); |
496 | 547 | product.setSimilar(similar); |
497 | 548 | } |
498 | - if(needLikeMatch&&productIds.contains(product.getId())){ | |
549 | + if (needLikeMatch && productIds.contains(product.getId())) { | |
499 | 550 | pId2ttDOsMap.get(product.getId()).forEach(x -> { |
500 | - int ttSimilar = LevenshteinDistanceService.LevenshteinDistancePercent(productQueryVO.getKeyword(),x.getRank()); | |
551 | + int ttSimilar = LevenshteinDistanceService.LevenshteinDistancePercent(productQueryVO.getKeyword(), x.getRank()); | |
501 | 552 | product.setTtsTotalSimilar(product.getTtsTotalSimilar() + ttSimilar); |
502 | 553 | }); |
503 | 554 | } |
504 | 555 | } |
505 | 556 | Collections.sort(similarProductList, (o1, o2) -> |
506 | 557 | { |
507 | - if (o2.getSimilar()-o1.getSimilar()!=0) { | |
508 | - return o2.getSimilar()-o1.getSimilar(); | |
509 | - }else { | |
510 | - return o2.getTtsTotalSimilar()-o1.getTtsTotalSimilar(); | |
558 | + if (o2.getSimilar() - o1.getSimilar() != 0) { | |
559 | + return o2.getSimilar() - o1.getSimilar(); | |
560 | + } else { | |
561 | + return o2.getTtsTotalSimilar() - o1.getTtsTotalSimilar(); | |
511 | 562 | } |
512 | 563 | } |
513 | 564 | ); | ... | ... |