package com.uas.search.console.controller; import com.uas.search.util.StringUtils; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.uas.search.console.core.util.ContextUtils; import com.uas.search.console.dao.ComponentSimpleInfoDao; import com.uas.search.console.model.BrandSimpleInfo; import com.uas.search.console.model.ComponentSimpleInfo; import com.uas.search.console.model.GoodsSimpleInfo; import com.uas.search.console.model.KindSimpleInfo; import com.uas.search.console.service.InnerSearchService; import com.uas.search.console.service.impl.IndexServiceImpl; import com.uas.search.console.util.FileUtils; import com.uas.search.console.util.SearchUtils; import com.uas.search.exception.SearchException; import com.uas.search.model.CollectField; import com.uas.search.model.PageParams; import com.uas.search.model.PageParams.FilterField; import com.uas.search.model.SPage; import com.uas.search.model.Sort; import com.uas.search.model.Sort.Field; import com.uas.search.service.SearchService; import com.uas.search.util.CollectionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; 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 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 InnerSearchService innerSearchService = ContextUtils.getApplicationContext().getBean("searchServiceImpl", InnerSearchService.class); private Logger logger = LoggerFactory.getLogger(getClass()); @RequestMapping("/kindIds/{keyword}") @ResponseBody public SPage seachKindIds(@PathVariable String keyword, Integer page, Integer size) { return searchService.getKindIds(keyword, page, size); } @RequestMapping("/kinds/{keyword}") @ResponseBody public SPage> seachKinds(@PathVariable String keyword, Integer page, Integer size) { return searchService.getKinds(keyword, page, size); } @RequestMapping("/brandIds/{keyword}") @ResponseBody public SPage searchBrandIds(@PathVariable String keyword, Integer page, Integer size) { return searchService.getBrandIds(keyword, page, size); } @RequestMapping("/brands/{keyword}") @ResponseBody public SPage> searchBrand(@PathVariable String keyword, Integer page, Integer size) { return searchService.getBrands(keyword, page, size); } @RequestMapping("/componentIds") @ResponseBody public Map searchComponentIds(String keyword, Integer page, Integer size, String filters) { PageParams pageParams = new PageParams(); if (page != null) { pageParams.setPage(page); } if (size != null) { pageParams.setSize(size); } 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().toUpperCase()); filtersMap.put(field, entry.getValue()); } } pageParams.setFilters(filtersMap); return searchService.getComponentIds(keyword, pageParams); } @Autowired private ComponentSimpleInfoDao componentDao; @RequestMapping("/components") @ResponseBody public List searchComponents(String keyword, Integer page, Integer size, String filters) { @SuppressWarnings("unchecked") List ids = (List) searchComponentIds(keyword, page, size, filters).get("componentIds"); 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) { return searchService.getKindIdsBySearchComponent(keyword, brandId); } @RequestMapping("/kindsByComponent") @ResponseBody public List> searchKindsBySearchComponent(String keyword, String brandId) { return searchService.getKindsBySearchComponent(keyword, brandId); } @RequestMapping("/brandIdsByComponent") @ResponseBody public Set searchBrandIdsBySearchComponent(String keyword, String kindId) { return searchService.getBrandIdsBySearchComponent(keyword, kindId); } @RequestMapping("/brandsByComponent") @ResponseBody public List> searchBrandsBySearchComponent(String keyword, String kindId) { return searchService.getBrandsBySearchComponent(keyword, kindId); } @RequestMapping("/similarKeywords/{keyword}") @ResponseBody public List getSimilarKeywords(@PathVariable String keyword) { return searchService.getSimilarKeywords(keyword); } @RequestMapping("/similarComponents/{componentCode}") @ResponseBody public List> getSimilarComponents(@PathVariable String componentCode) { return searchService.getSimilarComponents(componentCode); } @RequestMapping("/similarBrands/{brandName}") @ResponseBody public List> getSimilarBrands(@PathVariable String brandName) { return searchService.getSimilarBrands(brandName); } @RequestMapping("/similarKinds/{kindName}") @ResponseBody public List> getSimilarKinds(@PathVariable String kindName) { return searchService.getSimilarKinds(kindName); } @RequestMapping("/similarLeafKinds/{kindName}") @ResponseBody public List> getSimilarLeafKinds(@PathVariable String kindName) { return searchService.getSimilarLeafKinds(kindName); } @RequestMapping("/similarKindsByLevel") @ResponseBody public List> getSimilarKindsByLevel(String kindName, Short level) { return searchService.getSimilarKindsByLevel(kindName, level); } @RequestMapping("/similarPropertyValues") @ResponseBody public List> getSimilarPropertyValues(Long kindId, Long propertyId, String keyword, Long topNum) { return searchService.getSimilarPropertyValues(kindId, propertyId, keyword, topNum); } @RequestMapping("/goodsIds") @ResponseBody public Map getGoodsIds(String keyword, Integer page, Integer size, String filters, String sort) { PageParams pageParams = new PageParams(); if (page != null) { pageParams.setPage(page); } if (size != null) { pageParams.setSize(size); } 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()); 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); } filtersMap.put(field, values); break; default: filtersMap.put(field, value); } } } pageParams.setFilters(filtersMap); if (!StringUtils.isEmpty(sort)) { JSONArray jsonArray = JSONObject.parseArray(sort); List sorts = new ArrayList<>(); for (Object object : jsonArray) { if (object instanceof JSONObject) { JSONObject jsonObject = (JSONObject) object; Field field = Field.valueOf(jsonObject.getString("field")); boolean reverse = jsonObject.getBooleanValue("reverse"); sorts.add(new Sort(field, reverse)); } else { throw new IllegalArgumentException("排序参数并非json格式"); } } pageParams.setSort(sorts); } return searchService.getGoodsIds(keyword, pageParams); } @RequestMapping("/collectBySearchGoods") @ResponseBody public List> collectBySearchGoods(String keyword, String collectedField, String filters) { 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()); 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); } filtersMap.put(field, values); break; default: filtersMap.put(field, value); } } } return searchService.collectBySearchGoods(keyword, CollectField.valueOf(collectedField.toUpperCase()), filtersMap); } @RequestMapping("/kind/{id}") @ResponseBody public KindSimpleInfo getKind(@PathVariable Long id) { return innerSearchService.getKind(id); } @RequestMapping("/brand/{id}") @ResponseBody public BrandSimpleInfo getBrand(@PathVariable Long id) { return innerSearchService.getBrand(id); } @RequestMapping("/component/{id}") @ResponseBody public ComponentSimpleInfo getComponent(@PathVariable Long id) { return innerSearchService.getComponent(id); } @RequestMapping("/goods/{id}") @ResponseBody public GoodsSimpleInfo getGoods(@PathVariable String id) { return innerSearchService.getGoods(id); } @RequestMapping("/objects") @ResponseBody public SPage getObjects(@RequestParam(required = true) String tableName, String keyword, String field, Boolean tokenized, Integer page, Integer size) { return innerSearchService.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) { int page = 1; int size = 1000; // 不能边更新索引边分页获取索引中的数据,因为索引更新后,分页顺序可能也会变化, // 所以要先把数据保存到本地,等待全部获取之后重建索引 Long startTime = new Date().getTime(); // 先删除旧的文件 FileUtils.deleteSubFiles(new File(SearchUtils.getDataPath(tableName))); SPage sPage = innerSearchService.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 = innerSearchService.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; } }