package com.uas.search.controller; import com.uas.search.util.StringUtils; import com.alibaba.fastjson.JSONObject; import com.uas.search.constant.model.CollectField; import com.uas.search.constant.model.PageParams; import com.uas.search.constant.model.PageParams.FilterField; import com.uas.search.constant.model.SPage; import com.uas.search.dao.ComponentDao; import com.uas.search.exception.SearchException; import com.uas.search.model.Brand; import com.uas.search.model.Component; import com.uas.search.model.Goods; import com.uas.search.model.Kind; import com.uas.search.service.SearchService; import com.uas.search.service.impl.IndexServiceImpl; import com.uas.search.util.FileUtils; import com.uas.search.util.SearchUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import com.uas.search.util.CollectionUtils; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; import java.io.File; import java.io.FileNotFoundException; import java.io.PrintWriter; import java.util.*; import java.util.Map.Entry; /** * 搜索请求 * * @author suntg * @since 2016年8月1日上午9:18:05 */ @Controller @RequestMapping("/search") public class SearchController { @Autowired private SearchService searchService; private Logger logger = LoggerFactory.getLogger(getClass()); @RequestMapping("/kindIds/{keyword}") @ResponseBody public SPage seachKindIds(@PathVariable String keyword, Integer page, Integer size, HttpServletRequest request) { return searchService.getKindIds(keyword, page, size); } @RequestMapping("/kinds/{keyword}") @ResponseBody public SPage> seachKinds(@PathVariable String keyword, Integer page, Integer size, HttpServletRequest request) { return searchService.getKinds(keyword, page, size); } @RequestMapping("/brandIds/{keyword}") @ResponseBody public SPage searchBrandIds(@PathVariable String keyword, Integer page, Integer size, HttpServletRequest request) { return searchService.getBrandIds(keyword, page, size); } @RequestMapping("/brands/{keyword}") @ResponseBody public SPage> searchBrand(@PathVariable String keyword, Integer page, Integer size, HttpServletRequest request) { return searchService.getBrands(keyword, page, size); } @RequestMapping("/componentIds") @ResponseBody public Map searchComponentIds(String keyword, String params, HttpServletRequest request) { PageParams pageParams = params==null?null:JSONObject.parseObject(params, PageParams.class); return searchService.getComponentIds(keyword, pageParams); } @Autowired private ComponentDao componentDao; @RequestMapping("/components") @ResponseBody public List searchComponents(String keyword, String params, HttpServletRequest request) { @SuppressWarnings("unchecked") List ids = (List) searchComponentIds(keyword, params, request).get("componentIds"); return findComponents(ids); } private List findComponents(List ids){ if (CollectionUtils.isEmpty(ids)) { return new ArrayList(); } Long[] idsLong = new Long[ids.size()]; int i = 0; for (Long id : ids) { idsLong[i++] = id; } return componentDao.findAll(ids); } @RequestMapping("/kindIdsByComponent") @ResponseBody public Set searchKindIdsBySearchComponent(String keyword, String brandId, HttpServletRequest request) { return searchService.getKindIdsBySearchComponent(keyword, brandId); } @RequestMapping("/kindsByComponent") @ResponseBody public Set> searchKindsBySearchComponent(String keyword, String brandId, HttpServletRequest request) { return searchService.getKindsBySearchComponent(keyword, brandId); } @RequestMapping("/brandIdsByComponent") @ResponseBody public Set searchBrandIdsBySearchComponent(String keyword, String kindId, HttpServletRequest request) { return searchService.getBrandIdsBySearchComponent(keyword, kindId); } @RequestMapping("/brandsByComponent") @ResponseBody public Set> searchBrandsBySearchComponent(String keyword, String kindId, HttpServletRequest request) { return searchService.getBrandsBySearchComponent(keyword, kindId); } @RequestMapping("/similarKeywords/{keyword}") @ResponseBody public List getSimilarKeywords(@PathVariable String keyword, Integer size, HttpServletRequest request) { return searchService.getSimilarKeywords(keyword, size); } @RequestMapping("/similarComponents/{componentCode}") @ResponseBody public List> getSimilarComponents(@PathVariable String componentCode, Integer size, HttpServletRequest request) { return searchService.getSimilarComponents(componentCode, size); } @RequestMapping("/similarBrands/{brandName}") @ResponseBody public List> getSimilarBrands(@PathVariable String brandName, Integer size, HttpServletRequest request) { return searchService.getSimilarBrands(brandName, size); } @RequestMapping("/similarKinds/{kindName}") @ResponseBody public List> getSimilarKinds(@PathVariable String kindName, Integer size, HttpServletRequest request) { return searchService.getSimilarKinds(kindName, size); } @RequestMapping("/similarLeafKinds/{kindName}") @ResponseBody public List> getSimilarLeafKinds(@PathVariable String kindName, Integer size, HttpServletRequest request) { return searchService.getSimilarLeafKinds(kindName, size); } @RequestMapping("/similarKindsByLevel") @ResponseBody public List> getSimilarKindsByLevel(String kindName, Short level, Integer size, HttpServletRequest request) { return searchService.getSimilarKindsByLevel(kindName, level, size); } @RequestMapping("/similarPropertyValues") @ResponseBody public List> getSimilarPropertyValues(Long kindId, Long propertyId, String keyword, Long topNum, HttpServletRequest request) { return searchService.getSimilarPropertyValues(kindId, propertyId, keyword, topNum); } public Map parseFilters(JSONObject json){ Map filters = new HashMap<>(); if(json!=null){ Set> entrySet = json.entrySet(); for (Entry entry : entrySet) { FilterField field = FilterField.valueOf(entry.getKey()); String value = entry.getValue().toString(); switch (field) { case GOODS_KINDID: case GOODS_BRANDID: case GOODS_STORE_TYPE: case GOODS_CRNAME: String[] strs = value.split(","); List values = new ArrayList<>(); for (String str : strs) { values.add(str); } filters.put(field, values); break; default: filters.put(field, value); } } } return filters; } @RequestMapping("/goodsIds") @ResponseBody public Map getGoodsIds(String keyword, String params, HttpServletRequest request) { PageParams pageParams = params==null?null:JSONObject.parseObject(params, PageParams.class); return searchService.getGoodsIds(keyword, pageParams); } @RequestMapping("/collectBySearchGoods") @ResponseBody public List> collectBySearchGoods(String keyword, @RequestParam String collectedField, String filters, HttpServletRequest request) { Map filtersMap = new HashMap<>(); if(!StringUtils.isEmpty(filters)){ JSONObject json = JSONObject.parseObject(filters); Set> entrySet = json.entrySet(); for (Entry entry : entrySet) { FilterField field = FilterField.valueOf(entry.getKey()); switch (field) { case GOODS_KINDID: case GOODS_BRANDID: case GOODS_STORE_TYPE: case GOODS_CRNAME: filtersMap.put(field, entry.getValue()); break; } } } return searchService.collectBySearchGoods(keyword, CollectField.valueOf(collectedField.toUpperCase()), filtersMap); } @RequestMapping("/kind/{id}") @ResponseBody public Kind getKind(@PathVariable Long id, HttpServletRequest request) { return searchService.getKind(id); } @RequestMapping("/brand/{id}") @ResponseBody public Brand getBrand(@PathVariable Long id, HttpServletRequest request) { return searchService.getBrand(id); } @RequestMapping("/component/{id}") @ResponseBody public Component getComponent(@PathVariable Long id, HttpServletRequest request) { return searchService.getComponent(id); } @RequestMapping("/goods/{id}") @ResponseBody public Goods getGoods(@PathVariable String id, HttpServletRequest request) { return searchService.getGoods(id); } @RequestMapping("/objects") @ResponseBody public SPage getObjects(@RequestParam(required = true) String tableName, String keyword, String field, Boolean tokenized, Integer page, Integer size, HttpServletRequest request) { return searchService.getObjects(tableName.toLowerCase(), keyword, field, tokenized, page == null ? 0 : page, size == null ? 0 : size); } @RequestMapping("/allObjectsToFiles") @ResponseBody public String writeAllObjectsToFiles(@RequestParam(required = true) String tableName, HttpServletRequest request) { int page = 1; int size = 1000; // 不能边更新索引边分页获取索引中的数据,因为索引更新后,分页顺序可能也会变化, // 所以要先把数据保存到本地,等待全部获取之后重建索引 Long startTime = new Date().getTime(); // 先删除旧的文件 FileUtils.deleteSubFiles(new File(SearchUtils.getDataPath(tableName))); SPage sPage = searchService.getObjects(tableName.toLowerCase(), null, null, null, page, size); // 索引中数据的总数目 long totalElements = sPage.getTotalElement(); logger.info("发现数据:" + totalElements + "条"); int fileIndex = 1; PrintWriter printWriter = null; int count = 0; try { File file = new File(SearchUtils.getDataPath(tableName)); if (!file.exists()) { file.mkdirs(); } printWriter = new PrintWriter(SearchUtils.getDataPath(tableName) + "/" + fileIndex + ".txt"); while (true) { // 一个文件存放100000条数据,一旦超过,写入新的文件 if (count > IndexServiceImpl.SINGLE_FILE_MAX_SIZE) { count = 1; printWriter.flush(); printWriter.close(); fileIndex++; printWriter = new PrintWriter(SearchUtils.getDataPath(tableName) + "/" + fileIndex + ".txt"); } List content = sPage.getContent(); for (Object element : content) { printWriter.println(JSONObject.toJSONString(element)); count++; } logger.info(String.format(tableName + "...................%.2f%%", ((page - 1) * size + content.size()) * 100.0 / totalElements)); if (++page > sPage.getTotalPage()) { break; } sPage = searchService.getObjects(tableName.toLowerCase(), null, null, null, page, size); } printWriter.flush(); printWriter.close(); } catch (FileNotFoundException | SecurityException | IllegalArgumentException e) { throw new SearchException(e).setDetailedMessage(e); } Long endTime = new Date().getTime(); String message = String.format("写入数据%s条,耗时%.2fs\n ", totalElements, (endTime - startTime) / 1000.0); logger.info(message); return message; } }