From 25badf41ec0434cede0dd9a3e60aa401d6294346 Mon Sep 17 00:00:00 2001 From: zhh Date: Thu, 21 Jun 2018 10:06:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=BB=BC=E5=90=88=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/EsProductController.java | 69 +++++++++- .../macro/mall/search/dao/EsProductDao.java | 3 +- .../mall/search/domain/CommonResult.java | 81 ++++++++++++ .../macro/mall/search/domain/EsProduct.java | 31 ++--- .../repository/EsProductRepository.java | 17 ++- .../mall/search/service/EsProductService.java | 32 ++++- .../service/impl/EsProductServiceImpl.java | 122 +++++++++++++++++- .../src/main/resources/application.properties | 2 + .../src/main/resources/dao/EsProductDao.xml | 7 +- .../search/MallSearchApplicationTests.java | 2 +- 10 files changed, 331 insertions(+), 35 deletions(-) create mode 100644 mall-search/src/main/java/com/macro/mall/search/domain/CommonResult.java diff --git a/mall-search/src/main/java/com/macro/mall/search/controller/EsProductController.java b/mall-search/src/main/java/com/macro/mall/search/controller/EsProductController.java index 8a3e3b7..d737867 100644 --- a/mall-search/src/main/java/com/macro/mall/search/controller/EsProductController.java +++ b/mall-search/src/main/java/com/macro/mall/search/controller/EsProductController.java @@ -1,13 +1,17 @@ package com.macro.mall.search.controller; +import com.macro.mall.search.domain.CommonResult; +import com.macro.mall.search.domain.EsProduct; import com.macro.mall.search.service.EsProductService; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.*; + +import java.util.List; /** * 搜索商品管理Controller @@ -15,14 +19,69 @@ import org.springframework.web.bind.annotation.ResponseBody; */ @Controller @Api(tags = "EsProductController", description = "搜索商品管理") -@RequestMapping("/search/product") +@RequestMapping("/esProduct") public class EsProductController { @Autowired private EsProductService esProductService; + @ApiOperation(value = "导入所有数据库中商品到ES") @RequestMapping(value = "/importAll", method = RequestMethod.POST) @ResponseBody public Object importAllList() { - return esProductService.importAll(); + int count = esProductService.importAll(); + return new CommonResult().success(count); + } + + @ApiOperation(value = "根据id删除商品") + @RequestMapping(value = "/delete/{id}", method = RequestMethod.GET) + @ResponseBody + public Object delete(@PathVariable Long id) { + esProductService.delete(id); + return new CommonResult().success(null); + } + + @ApiOperation(value = "根据id批量删除商品") + @RequestMapping(value = "/delete/batch", method = RequestMethod.POST) + @ResponseBody + public Object delete(@RequestParam("ids") List ids) { + esProductService.delete(ids); + return new CommonResult().success(null); + } + + @ApiOperation(value = "根据id创建商品") + @RequestMapping(value = "/create/{id}", method = RequestMethod.POST) + @ResponseBody + public Object create(@PathVariable Long id) { + EsProduct esProduct = esProductService.create(id); + if (esProduct != null) { + return new CommonResult().success(esProduct); + } else { + return new CommonResult().failed(); + } + } + + @ApiOperation(value = "简单搜索") + @RequestMapping(value = "/search/simple", method = RequestMethod.GET) + @ResponseBody + public Object search(@RequestParam(required = false) String keyword, + @RequestParam(required = false, defaultValue = "0") Integer pageNum, + @RequestParam(required = false, defaultValue = "5") Integer pageSize) { + Page esProductPage = esProductService.search(keyword, pageNum, pageSize); + return new CommonResult().pageSuccess(esProductPage); + } + + @ApiOperation(value = "综合搜索、筛选、排序") + @ApiImplicitParam(name = "sort", value = "排序字段:0->按相关度;1->按新品;2->按销量;3->价格从低到高;4->价格从高到低", + defaultValue = "0", allowableValues = "0,1,2,3,4", paramType = "query", dataType = "integer") + @RequestMapping(value = "/search", method = RequestMethod.GET) + @ResponseBody + public Object search(@RequestParam(required = false) String keyword, + @RequestParam(required = false) Long brandId, + @RequestParam(required = false) Long productCategoryId, + @RequestParam(required = false, defaultValue = "0") Integer pageNum, + @RequestParam(required = false, defaultValue = "5") Integer pageSize, + @RequestParam(required = false, defaultValue = "0") Integer sort) { + Page esProductPage = esProductService.search(keyword, brandId, productCategoryId, pageNum, pageSize, sort); + return new CommonResult().pageSuccess(esProductPage); } } diff --git a/mall-search/src/main/java/com/macro/mall/search/dao/EsProductDao.java b/mall-search/src/main/java/com/macro/mall/search/dao/EsProductDao.java index d460e46..ef34cb3 100644 --- a/mall-search/src/main/java/com/macro/mall/search/dao/EsProductDao.java +++ b/mall-search/src/main/java/com/macro/mall/search/dao/EsProductDao.java @@ -1,6 +1,7 @@ package com.macro.mall.search.dao; import com.macro.mall.search.domain.EsProduct; +import org.apache.ibatis.annotations.Param; import java.util.List; @@ -9,5 +10,5 @@ import java.util.List; * Created by macro on 2018/6/19. */ public interface EsProductDao { - List getAllEsProductList(); + List getAllEsProductList(@Param("id") Long id); } diff --git a/mall-search/src/main/java/com/macro/mall/search/domain/CommonResult.java b/mall-search/src/main/java/com/macro/mall/search/domain/CommonResult.java new file mode 100644 index 0000000..88a366c --- /dev/null +++ b/mall-search/src/main/java/com/macro/mall/search/domain/CommonResult.java @@ -0,0 +1,81 @@ +package com.macro.mall.search.domain; + +import org.springframework.data.domain.Page; + +import java.util.HashMap; +import java.util.Map; + +/** + * 通用返回对象 + * Created by macro on 2018/4/26. + */ +public class CommonResult { + //操作成功 + public static final int SUCCESS = 200; + //操作失败 + public static final int FAILED = 500; + private int code; + private String message; + private Object data; + + /** + * 普通成功返回 + * + * @param data 获取的数据 + */ + public CommonResult success(Object data) { + this.code = SUCCESS; + this.message = "操作成功"; + this.data = data; + return this; + } + + /** + * 返回分页成功数据 + */ + public CommonResult pageSuccess(Page pageInfo) { + Map result = new HashMap<>(); + result.put("pageSize", pageInfo.getSize()); + result.put("totalPage", pageInfo.getTotalPages()); + result.put("total", pageInfo.getTotalElements()); + result.put("pageNum", pageInfo.getNumber()); + result.put("list", pageInfo.getContent()); + this.code = SUCCESS; + this.message = "操作成功"; + this.data = result; + return this; + } + + /** + * 普通失败提示信息 + */ + public CommonResult failed() { + this.code = FAILED; + this.message = "操作失败"; + return this; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public Object getData() { + return data; + } + + public void setData(Object data) { + this.data = data; + } +} diff --git a/mall-search/src/main/java/com/macro/mall/search/domain/EsProduct.java b/mall-search/src/main/java/com/macro/mall/search/domain/EsProduct.java index cb51212..f2ab49b 100644 --- a/mall-search/src/main/java/com/macro/mall/search/domain/EsProduct.java +++ b/mall-search/src/main/java/com/macro/mall/search/domain/EsProduct.java @@ -1,5 +1,6 @@ package com.macro.mall.search.domain; +import com.macro.mall.model.PmsProductAttributeValue; import org.springframework.data.elasticsearch.annotations.Document; import java.io.Serializable; @@ -22,6 +23,7 @@ public class EsProduct implements Serializable { private String pic; private String name; private String subTitle; + private String keywords; private BigDecimal price; private Integer sale; private Integer newStatus; @@ -29,7 +31,7 @@ public class EsProduct implements Serializable { private Integer stock; private Integer promotionType; private Integer sort; - private List attrValueList; + private List attrValueList; public Long getId() { return id; @@ -159,32 +161,19 @@ public class EsProduct implements Serializable { this.sort = sort; } - public List getAttrValueList() { + public List getAttrValueList() { return attrValueList; } - public void setAttrValueList(List attrValueList) { + public void setAttrValueList(List attrValueList) { this.attrValueList = attrValueList; } - static class EsProductAttrValue { - private Long id; - private String value; + public String getKeywords() { + return keywords; + } - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } + public void setKeywords(String keywords) { + this.keywords = keywords; } } diff --git a/mall-search/src/main/java/com/macro/mall/search/repository/EsProductRepository.java b/mall-search/src/main/java/com/macro/mall/search/repository/EsProductRepository.java index 9db35ba..9417cce 100644 --- a/mall-search/src/main/java/com/macro/mall/search/repository/EsProductRepository.java +++ b/mall-search/src/main/java/com/macro/mall/search/repository/EsProductRepository.java @@ -1,11 +1,24 @@ package com.macro.mall.search.repository; import com.macro.mall.search.domain.EsProduct; -import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; /** * 商品ES操作类 * Created by macro on 2018/6/19. */ -public interface EsProductRepository extends ElasticsearchCrudRepository { +public interface EsProductRepository extends ElasticsearchRepository { + /** + * 搜索查询 + * + * @param name 商品名称 + * @param subTitle 商品标题 + * @param keywords 商品关键字 + * @param page 分页信息 + * @return + */ + Page findByNameOrSubTitleOrKeywords(String name, String subTitle, String keywords,Pageable page); + } diff --git a/mall-search/src/main/java/com/macro/mall/search/service/EsProductService.java b/mall-search/src/main/java/com/macro/mall/search/service/EsProductService.java index 0ae3694..7e01826 100644 --- a/mall-search/src/main/java/com/macro/mall/search/service/EsProductService.java +++ b/mall-search/src/main/java/com/macro/mall/search/service/EsProductService.java @@ -1,5 +1,10 @@ package com.macro.mall.search.service; +import com.macro.mall.search.domain.EsProduct; +import org.springframework.data.domain.Page; + +import java.util.List; + /** * 商品搜索管理Service * Created by macro on 2018/6/19. @@ -8,5 +13,30 @@ public interface EsProductService { /** * 从数据库中导入所有商品到ES */ - Object importAll(); + int importAll(); + + /** + * 根据id删除商品 + */ + void delete(Long id); + + /** + * 根据id创建商品 + */ + EsProduct create(Long id); + + /** + * 批量删除商品 + */ + void delete(List ids); + + /** + * 根据关键字搜索名称或者副标题 + */ + Page search(String keyword, Integer pageNum, Integer pageSize); + + /** + * 根据关键字搜索名称或者副标题复合查询 + */ + Page search(String keyword, Long brandId, Long productCategoryId, Integer pageNum, Integer pageSize,Integer sort); } diff --git a/mall-search/src/main/java/com/macro/mall/search/service/impl/EsProductServiceImpl.java b/mall-search/src/main/java/com/macro/mall/search/service/impl/EsProductServiceImpl.java index c27ec58..ae254be 100644 --- a/mall-search/src/main/java/com/macro/mall/search/service/impl/EsProductServiceImpl.java +++ b/mall-search/src/main/java/com/macro/mall/search/service/impl/EsProductServiceImpl.java @@ -4,11 +4,30 @@ import com.macro.mall.search.dao.EsProductDao; import com.macro.mall.search.domain.EsProduct; import com.macro.mall.search.repository.EsProductRepository; import com.macro.mall.search.service.EsProductService; +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.sort.SortBuilder; +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.PageRequest; +import org.springframework.data.domain.Pageable; +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; + /** * 商品搜索管理Service实现类 * Created by macro on 2018/6/19. @@ -19,10 +38,107 @@ public class EsProductServiceImpl implements EsProductService { private EsProductDao productDao; @Autowired private EsProductRepository productRepository; + private static final Logger LOGGER = LoggerFactory.getLogger(EsProductServiceImpl.class); @Override - public Object importAll() { - List esProductList = productDao.getAllEsProductList(); + public int importAll() { + List esProductList = productDao.getAllEsProductList(null); Iterable esProductIterable = productRepository.save(esProductList); - return esProductIterable; + Iterator iterator = esProductIterable.iterator(); + int result = 0; + while (iterator.hasNext()) { + result++; + iterator.next(); + } + return result; + } + + @Override + public void delete(Long id) { + productRepository.delete(id); + } + + @Override + public EsProduct create(Long id) { + EsProduct result = null; + List esProductList = productDao.getAllEsProductList(id); + if (esProductList.size() > 0) { + EsProduct esProduct = esProductList.get(0); + result = productRepository.save(esProduct); + } + return result; + } + + @Override + public void delete(List ids) { + if (!CollectionUtils.isEmpty(ids)) { + List esProductList = new ArrayList<>(); + for (Long id : ids) { + EsProduct esProduct = new EsProduct(); + esProduct.setId(id); + esProductList.add(esProduct); + } + productRepository.delete(esProductList); + } + } + + @Override + public Page search(String keyword, Integer pageNum, Integer pageSize) { + Pageable pageable = new PageRequest(pageNum, pageSize); + return productRepository.findByNameOrSubTitleOrKeywords(keyword, keyword, keyword, pageable); + } + + @Override + public Page search(String keyword, Long brandId, Long productCategoryId, Integer pageNum, Integer pageSize,Integer sort) { + Pageable pageable = new PageRequest(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); + } + //搜索 + FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery() + .add(QueryBuilders.matchPhraseQuery("name", keyword), + ScoreFunctionBuilders.weightFactorFunction(1000)) + .add(QueryBuilders.matchPhraseQuery("subTitle", keyword), + ScoreFunctionBuilders.weightFactorFunction(500)) + .add(QueryBuilders.matchPhraseQuery("keywords", keyword), + ScoreFunctionBuilders.weightFactorFunction(200)) + .scoreMode("sum").setMinScore(10f); + if (StringUtils.isEmpty(keyword)) { + nativeSearchQueryBuilder.withQuery(QueryBuilders.matchAllQuery()); + } else { + 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)); + nativeSearchQueryBuilder.withSort(SortBuilders.scoreSort().order(SortOrder.DESC)); + NativeSearchQuery searchQuery = nativeSearchQueryBuilder.build(); +// LOGGER.info("DSL:{}", searchQuery.getQuery().toString()); + return productRepository.search(searchQuery); } } diff --git a/mall-search/src/main/resources/application.properties b/mall-search/src/main/resources/application.properties index 4d68062..8b3fcb5 100644 --- a/mall-search/src/main/resources/application.properties +++ b/mall-search/src/main/resources/application.properties @@ -2,6 +2,8 @@ server.port=8081 #===server end=== +logging.level.root=info + #===datasource start=== spring.datasource.url=jdbc:mysql://localhost:3306/mall spring.datasource.username=root diff --git a/mall-search/src/main/resources/dao/EsProductDao.xml b/mall-search/src/main/resources/dao/EsProductDao.xml index fe82fba..fe35e2e 100644 --- a/mall-search/src/main/resources/dao/EsProductDao.xml +++ b/mall-search/src/main/resources/dao/EsProductDao.xml @@ -23,11 +23,16 @@ p.recommand_status recommandStatus, p.stock stock, p.promotion_type promotionType, + P.keywords keywords p.sort sort, a.id attr_id, - a.value attr_value + a.value attr_value, + a.product_attribute_id attr_product_attribute_id from pms_product p left join pms_product_attribute_value a on p.id = a.product_id where delete_status = 0 and publish_status = 1 + + and p.id=#{id} + \ No newline at end of file diff --git a/mall-search/src/test/java/com/macro/mall/search/MallSearchApplicationTests.java b/mall-search/src/test/java/com/macro/mall/search/MallSearchApplicationTests.java index 5852032..6b48439 100644 --- a/mall-search/src/test/java/com/macro/mall/search/MallSearchApplicationTests.java +++ b/mall-search/src/test/java/com/macro/mall/search/MallSearchApplicationTests.java @@ -20,7 +20,7 @@ public class MallSearchApplicationTests { } @Test public void testGetAllEsProductList(){ - List esProductList = productDao.getAllEsProductList(); + List esProductList = productDao.getAllEsProductList(null); System.out.print(esProductList); }