diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/website/IndexSearchVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/website/IndexSearchVO.java index 1c7ef7568..b573cdd62 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/website/IndexSearchVO.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/website/IndexSearchVO.java @@ -47,5 +47,4 @@ public class IndexSearchVO extends BasePageVO { @ApiModelProperty(value = "排序方式", required = true) private SortOrder order; - } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/WebsiteAPPServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/WebsiteAPPServiceImpl.java index fbec625ec..d53ef4502 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/WebsiteAPPServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/WebsiteAPPServiceImpl.java @@ -1032,11 +1032,40 @@ public class WebsiteAPPServiceImpl implements IWebsiteAPPService { } // 添加 multiMatch 查询 if (StringUtils.isNotBlank(searchDTO.getSearch())) { + BoolQuery.Builder shouldBoolQuery = new BoolQuery.Builder(); + // 1. 多字段匹配(分词) MultiMatchQuery multiMatchQuery = MultiMatchQuery.of(m -> m .query(searchDTO.getSearch()) - .fields("prodArtNum", "storeName", "prodCateName", "parCateName") + .fields("prodArtNum^3", "storeName^2", "prodCateName^2", "parCateName^2") + .type(TextQueryType.BestFields) + .fuzziness("AUTO") ); - boolQuery.must(multiMatchQuery._toQuery()); + shouldBoolQuery.should(multiMatchQuery._toQuery()); + + // 2. 商品编号的精确匹配 + shouldBoolQuery.should(s -> s.wildcard(w -> w + .field("prodArtNum") + .value("*" + searchDTO.getSearch() + "*") + .caseInsensitive(true) + )); + + // 3. 短语匹配(带权重)- 完全匹配的得分更高 + shouldBoolQuery.should(s -> s.matchPhrase(m -> m + .field("storeName") + .query(searchDTO.getSearch()) + .boost(2.0f) // 店铺名称短语匹配权重加倍 + )); + shouldBoolQuery.should(s -> s.matchPhrase(m -> m + .field("prodCateName") + .query(searchDTO.getSearch()) + .boost(1.5f) // 分类名称短语匹配权重增加 + )); + shouldBoolQuery.should(s -> s.matchPhrase(m -> m + .field("parCateName") + .query(searchDTO.getSearch()) + .boost(1.5f) // 父级分类短语匹配权重增加 + )); + boolQuery.must(shouldBoolQuery.build()._toQuery()); } // 档口ID列表 过滤条件 if (CollectionUtils.isNotEmpty(searchDTO.getStoreIdList())) { diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/WebsitePCServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/WebsitePCServiceImpl.java index cb8c625c9..2f34eeda9 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/WebsitePCServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/WebsitePCServiceImpl.java @@ -1927,11 +1927,40 @@ public class WebsitePCServiceImpl implements IWebsitePCService { } // 添加 multiMatch 查询 if (StringUtils.isNotBlank(searchDTO.getSearch())) { + BoolQuery.Builder shouldBoolQuery = new BoolQuery.Builder(); + // 1. 多字段匹配(分词) MultiMatchQuery multiMatchQuery = MultiMatchQuery.of(m -> m .query(searchDTO.getSearch()) - .fields("prodArtNum", "storeName", "prodCateName", "parCateName") + .fields("prodArtNum^3", "storeName^2", "prodCateName^2", "parCateName^2") + .type(TextQueryType.BestFields) + .fuzziness("AUTO") ); - boolQuery.must(multiMatchQuery._toQuery()); + shouldBoolQuery.should(multiMatchQuery._toQuery()); + + // 2. 商品编号的精确匹配 + shouldBoolQuery.should(s -> s.wildcard(w -> w + .field("prodArtNum") + .value("*" + searchDTO.getSearch() + "*") + .caseInsensitive(true) + )); + + // 3. 短语匹配(带权重)- 完全匹配的得分更高 + shouldBoolQuery.should(s -> s.matchPhrase(m -> m + .field("storeName") + .query(searchDTO.getSearch()) + .boost(2.0f) // 店铺名称短语匹配权重加倍 + )); + shouldBoolQuery.should(s -> s.matchPhrase(m -> m + .field("prodCateName") + .query(searchDTO.getSearch()) + .boost(1.5f) // 分类名称短语匹配权重增加 + )); + shouldBoolQuery.should(s -> s.matchPhrase(m -> m + .field("parCateName") + .query(searchDTO.getSearch()) + .boost(1.5f) // 父级分类短语匹配权重增加 + )); + boolQuery.must(shouldBoolQuery.build()._toQuery()); } // 档口ID 过滤条件 if (CollectionUtils.isNotEmpty(searchDTO.getStoreIdList())) {