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,54 +460,105 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, ProductDO> im | ||
460 | Set<String> productIds = null; | 460 | Set<String> productIds = null; |
461 | Map<String,List<TicketTypeDO>> pId2ttDOsMap = null; | 461 | Map<String,List<TicketTypeDO>> pId2ttDOsMap = null; |
462 | boolean needLikeMatch = false; | 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 | productIds = tickeyTypeDOList.stream().map(TicketTypeDO::getProductId).collect(Collectors.toSet()); | 486 | productIds = tickeyTypeDOList.stream().map(TicketTypeDO::getProductId).collect(Collectors.toSet()); |
466 | needLikeMatch = true; | 487 | needLikeMatch = true; |
467 | pId2ttDOsMap = new HashMap<>(); | 488 | pId2ttDOsMap = new HashMap<>(); |
489 | + | ||
468 | for (TicketTypeDO ticketTypeDO : tickeyTypeDOList) { | 490 | for (TicketTypeDO ticketTypeDO : tickeyTypeDOList) { |
469 | pId2ttDOsMap.computeIfAbsent(ticketTypeDO.getProductId(), k -> new ArrayList<>()); | 491 | pId2ttDOsMap.computeIfAbsent(ticketTypeDO.getProductId(), k -> new ArrayList<>()); |
470 | pId2ttDOsMap.get(ticketTypeDO.getProductId()).add(ticketTypeDO); | 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 | List<ProductDO> productDOS = this.baseMapper.queryList(queryWapper); | 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 | List<ProductDO> accurateProducts = Lists.newArrayList(); | 531 | List<ProductDO> accurateProducts = Lists.newArrayList(); |
479 | Set<String> accurateProductIdSet = Sets.newHashSet(); | 532 | Set<String> accurateProductIdSet = Sets.newHashSet(); |
480 | //区分大小写 | 533 | //区分大小写 |
481 | productDOS.forEach(x -> { | 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 | List<ProductDO> similarProductList = Lists.newArrayList(); | 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 | continue; | 541 | continue; |
491 | } | 542 | } |
492 | String name = product.getName(); | 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 | similarProductList.add(product); | 546 | similarProductList.add(product); |
496 | product.setSimilar(similar); | 547 | product.setSimilar(similar); |
497 | } | 548 | } |
498 | - if(needLikeMatch&&productIds.contains(product.getId())){ | 549 | + if (needLikeMatch && productIds.contains(product.getId())) { |
499 | pId2ttDOsMap.get(product.getId()).forEach(x -> { | 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 | product.setTtsTotalSimilar(product.getTtsTotalSimilar() + ttSimilar); | 552 | product.setTtsTotalSimilar(product.getTtsTotalSimilar() + ttSimilar); |
502 | }); | 553 | }); |
503 | } | 554 | } |
504 | } | 555 | } |
505 | Collections.sort(similarProductList, (o1, o2) -> | 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 | ); |