添加综合搜索功能
This commit is contained in:
parent
d1e687da73
commit
25badf41ec
@ -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<Long> 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<EsProduct> 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<EsProduct> esProductPage = esProductService.search(keyword, brandId, productCategoryId, pageNum, pageSize, sort);
|
||||
return new CommonResult().pageSuccess(esProductPage);
|
||||
}
|
||||
}
|
||||
|
@ -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<EsProduct> getAllEsProductList();
|
||||
List<EsProduct> getAllEsProductList(@Param("id") Long id);
|
||||
}
|
||||
|
@ -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<String, Object> 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;
|
||||
}
|
||||
}
|
@ -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<EsProductAttrValue> attrValueList;
|
||||
private List<PmsProductAttributeValue> attrValueList;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
@ -159,32 +161,19 @@ public class EsProduct implements Serializable {
|
||||
this.sort = sort;
|
||||
}
|
||||
|
||||
public List<EsProductAttrValue> getAttrValueList() {
|
||||
public List<PmsProductAttributeValue> getAttrValueList() {
|
||||
return attrValueList;
|
||||
}
|
||||
|
||||
public void setAttrValueList(List<EsProductAttrValue> attrValueList) {
|
||||
public void setAttrValueList(List<PmsProductAttributeValue> 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;
|
||||
}
|
||||
}
|
||||
|
@ -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<EsProduct,Long> {
|
||||
public interface EsProductRepository extends ElasticsearchRepository<EsProduct, Long> {
|
||||
/**
|
||||
* 搜索查询
|
||||
*
|
||||
* @param name 商品名称
|
||||
* @param subTitle 商品标题
|
||||
* @param keywords 商品关键字
|
||||
* @param page 分页信息
|
||||
* @return
|
||||
*/
|
||||
Page<EsProduct> findByNameOrSubTitleOrKeywords(String name, String subTitle, String keywords,Pageable page);
|
||||
|
||||
}
|
||||
|
@ -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<Long> ids);
|
||||
|
||||
/**
|
||||
* 根据关键字搜索名称或者副标题
|
||||
*/
|
||||
Page<EsProduct> search(String keyword, Integer pageNum, Integer pageSize);
|
||||
|
||||
/**
|
||||
* 根据关键字搜索名称或者副标题复合查询
|
||||
*/
|
||||
Page<EsProduct> search(String keyword, Long brandId, Long productCategoryId, Integer pageNum, Integer pageSize,Integer sort);
|
||||
}
|
||||
|
@ -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<EsProduct> esProductList = productDao.getAllEsProductList();
|
||||
public int importAll() {
|
||||
List<EsProduct> esProductList = productDao.getAllEsProductList(null);
|
||||
Iterable<EsProduct> esProductIterable = productRepository.save(esProductList);
|
||||
return esProductIterable;
|
||||
Iterator<EsProduct> 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<EsProduct> esProductList = productDao.getAllEsProductList(id);
|
||||
if (esProductList.size() > 0) {
|
||||
EsProduct esProduct = esProductList.get(0);
|
||||
result = productRepository.save(esProduct);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(List<Long> ids) {
|
||||
if (!CollectionUtils.isEmpty(ids)) {
|
||||
List<EsProduct> esProductList = new ArrayList<>();
|
||||
for (Long id : ids) {
|
||||
EsProduct esProduct = new EsProduct();
|
||||
esProduct.setId(id);
|
||||
esProductList.add(esProduct);
|
||||
}
|
||||
productRepository.delete(esProductList);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<EsProduct> search(String keyword, Integer pageNum, Integer pageSize) {
|
||||
Pageable pageable = new PageRequest(pageNum, pageSize);
|
||||
return productRepository.findByNameOrSubTitleOrKeywords(keyword, keyword, keyword, pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<EsProduct> 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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
<if test="id!=null">
|
||||
and p.id=#{id}
|
||||
</if>
|
||||
</select>
|
||||
</mapper>
|
@ -20,7 +20,7 @@ public class MallSearchApplicationTests {
|
||||
}
|
||||
@Test
|
||||
public void testGetAllEsProductList(){
|
||||
List<EsProduct> esProductList = productDao.getAllEsProductList();
|
||||
List<EsProduct> esProductList = productDao.getAllEsProductList(null);
|
||||
System.out.print(esProductList);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user