SearchController.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. package com.uas.search.controller;
  2. import com.uas.search.util.StringUtils;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.uas.search.constant.model.CollectField;
  5. import com.uas.search.constant.model.PageParams;
  6. import com.uas.search.constant.model.PageParams.FilterField;
  7. import com.uas.search.constant.model.SPage;
  8. import com.uas.search.dao.ComponentDao;
  9. import com.uas.search.exception.SearchException;
  10. import com.uas.search.model.Brand;
  11. import com.uas.search.model.Component;
  12. import com.uas.search.model.Goods;
  13. import com.uas.search.model.Kind;
  14. import com.uas.search.service.SearchService;
  15. import com.uas.search.service.impl.IndexServiceImpl;
  16. import com.uas.search.util.FileUtils;
  17. import com.uas.search.util.SearchUtils;
  18. import org.slf4j.Logger;
  19. import org.slf4j.LoggerFactory;
  20. import org.springframework.beans.factory.annotation.Autowired;
  21. import org.springframework.stereotype.Controller;
  22. import com.uas.search.util.CollectionUtils;
  23. import org.springframework.web.bind.annotation.PathVariable;
  24. import org.springframework.web.bind.annotation.RequestMapping;
  25. import org.springframework.web.bind.annotation.RequestParam;
  26. import org.springframework.web.bind.annotation.ResponseBody;
  27. import javax.servlet.http.HttpServletRequest;
  28. import java.io.File;
  29. import java.io.FileNotFoundException;
  30. import java.io.PrintWriter;
  31. import java.util.*;
  32. import java.util.Map.Entry;
  33. /**
  34. * 搜索请求
  35. *
  36. * @author suntg
  37. * @since 2016年8月1日上午9:18:05
  38. */
  39. @Controller
  40. @RequestMapping("/search")
  41. public class SearchController {
  42. @Autowired
  43. private SearchService searchService;
  44. private Logger logger = LoggerFactory.getLogger(getClass());
  45. @RequestMapping("/kindIds/{keyword}")
  46. @ResponseBody
  47. public SPage<Long> seachKindIds(@PathVariable String keyword, Integer page, Integer size,
  48. HttpServletRequest request) {
  49. return searchService.getKindIds(keyword, page, size);
  50. }
  51. @RequestMapping("/kinds/{keyword}")
  52. @ResponseBody
  53. public SPage<Map<String, Object>> seachKinds(@PathVariable String keyword, Integer page, Integer size,
  54. HttpServletRequest request) {
  55. return searchService.getKinds(keyword, page, size);
  56. }
  57. @RequestMapping("/brandIds/{keyword}")
  58. @ResponseBody
  59. public SPage<Long> searchBrandIds(@PathVariable String keyword, Integer page, Integer size,
  60. HttpServletRequest request) {
  61. return searchService.getBrandIds(keyword, page, size);
  62. }
  63. @RequestMapping("/brands/{keyword}")
  64. @ResponseBody
  65. public SPage<Map<String, Object>> searchBrand(@PathVariable String keyword, Integer page, Integer size,
  66. HttpServletRequest request) {
  67. return searchService.getBrands(keyword, page, size);
  68. }
  69. @RequestMapping("/componentIds")
  70. @ResponseBody
  71. public Map<String, Object> searchComponentIds(String keyword, String params, HttpServletRequest request) {
  72. PageParams pageParams = params==null?null:JSONObject.parseObject(params, PageParams.class);
  73. return searchService.getComponentIds(keyword, pageParams);
  74. }
  75. @Autowired
  76. private ComponentDao componentDao;
  77. @RequestMapping("/components")
  78. @ResponseBody
  79. public List<Component> searchComponents(String keyword, String params, HttpServletRequest request) {
  80. @SuppressWarnings("unchecked")
  81. List<Long> ids = (List<Long>) searchComponentIds(keyword, params, request).get("componentIds");
  82. return findComponents(ids);
  83. }
  84. private List<Component> findComponents(List<Long> ids){
  85. if (CollectionUtils.isEmpty(ids)) {
  86. return new ArrayList<Component>();
  87. }
  88. Long[] idsLong = new Long[ids.size()];
  89. int i = 0;
  90. for (Long id : ids) {
  91. idsLong[i++] = id;
  92. }
  93. return componentDao.findAll(ids);
  94. }
  95. @RequestMapping("/kindIdsByComponent")
  96. @ResponseBody
  97. public Set<Long> searchKindIdsBySearchComponent(String keyword, String brandId, HttpServletRequest request) {
  98. return searchService.getKindIdsBySearchComponent(keyword, brandId);
  99. }
  100. @RequestMapping("/kindsByComponent")
  101. @ResponseBody
  102. public Set<Map<String, Object>> searchKindsBySearchComponent(String keyword, String brandId,
  103. HttpServletRequest request) {
  104. return searchService.getKindsBySearchComponent(keyword, brandId);
  105. }
  106. @RequestMapping("/brandIdsByComponent")
  107. @ResponseBody
  108. public Set<Long> searchBrandIdsBySearchComponent(String keyword, String kindId, HttpServletRequest request) {
  109. return searchService.getBrandIdsBySearchComponent(keyword, kindId);
  110. }
  111. @RequestMapping("/brandsByComponent")
  112. @ResponseBody
  113. public Set<Map<String, Object>> searchBrandsBySearchComponent(String keyword, String kindId,
  114. HttpServletRequest request) {
  115. return searchService.getBrandsBySearchComponent(keyword, kindId);
  116. }
  117. @RequestMapping("/similarKeywords/{keyword}")
  118. @ResponseBody
  119. public List<String> getSimilarKeywords(@PathVariable String keyword, Integer size, HttpServletRequest request) {
  120. return searchService.getSimilarKeywords(keyword, size);
  121. }
  122. @RequestMapping("/similarComponents/{componentCode}")
  123. @ResponseBody
  124. public List<Map<String, Object>> getSimilarComponents(@PathVariable String componentCode, Integer size,
  125. HttpServletRequest request) {
  126. return searchService.getSimilarComponents(componentCode, size);
  127. }
  128. @RequestMapping("/similarBrands/{brandName}")
  129. @ResponseBody
  130. public List<Map<String, Object>> getSimilarBrands(@PathVariable String brandName, Integer size, HttpServletRequest request) {
  131. return searchService.getSimilarBrands(brandName, size);
  132. }
  133. @RequestMapping("/similarKinds/{kindName}")
  134. @ResponseBody
  135. public List<Map<String, Object>> getSimilarKinds(@PathVariable String kindName, Integer size, HttpServletRequest request) {
  136. return searchService.getSimilarKinds(kindName, size);
  137. }
  138. @RequestMapping("/similarLeafKinds/{kindName}")
  139. @ResponseBody
  140. public List<Map<String, Object>> getSimilarLeafKinds(@PathVariable String kindName, Integer size, HttpServletRequest request) {
  141. return searchService.getSimilarLeafKinds(kindName, size);
  142. }
  143. @RequestMapping("/similarKindsByLevel")
  144. @ResponseBody
  145. public List<Map<String, Object>> getSimilarKindsByLevel(String kindName, Short level, Integer size, HttpServletRequest request) {
  146. return searchService.getSimilarKindsByLevel(kindName, level, size);
  147. }
  148. @RequestMapping("/similarPropertyValues")
  149. @ResponseBody
  150. public List<Map<String, String>> getSimilarPropertyValues(Long kindId, Long propertyId, String keyword, Long topNum,
  151. HttpServletRequest request) {
  152. return searchService.getSimilarPropertyValues(kindId, propertyId, keyword, topNum);
  153. }
  154. public Map<FilterField, Object> parseFilters(JSONObject json){
  155. Map<FilterField, Object> filters = new HashMap<>();
  156. if(json!=null){
  157. Set<Entry<String, Object>> entrySet = json.entrySet();
  158. for (Entry<String, Object> entry : entrySet) {
  159. FilterField field = FilterField.valueOf(entry.getKey());
  160. String value = entry.getValue().toString();
  161. switch (field) {
  162. case GOODS_KINDID:
  163. case GOODS_BRANDID:
  164. case GOODS_STORE_TYPE:
  165. case GOODS_CRNAME:
  166. String[] strs = value.split(",");
  167. List<Object> values = new ArrayList<>();
  168. for (String str : strs) {
  169. values.add(str);
  170. }
  171. filters.put(field, values);
  172. break;
  173. default:
  174. filters.put(field, value);
  175. }
  176. }
  177. }
  178. return filters;
  179. }
  180. @RequestMapping("/goodsIds")
  181. @ResponseBody
  182. public Map<String, Object> getGoodsIds(String keyword, String params, HttpServletRequest request) {
  183. PageParams pageParams = params==null?null:JSONObject.parseObject(params, PageParams.class);
  184. return searchService.getGoodsIds(keyword, pageParams);
  185. }
  186. @RequestMapping("/collectBySearchGoods")
  187. @ResponseBody
  188. public List<Map<String, Object>> collectBySearchGoods(String keyword, @RequestParam String collectedField, String filters, HttpServletRequest request) {
  189. Map<FilterField, Object> filtersMap = new HashMap<>();
  190. if(!StringUtils.isEmpty(filters)){
  191. JSONObject json = JSONObject.parseObject(filters);
  192. Set<Entry<String, Object>> entrySet = json.entrySet();
  193. for (Entry<String, Object> entry : entrySet) {
  194. FilterField field = FilterField.valueOf(entry.getKey());
  195. switch (field) {
  196. case GOODS_KINDID:
  197. case GOODS_BRANDID:
  198. case GOODS_STORE_TYPE:
  199. case GOODS_CRNAME:
  200. filtersMap.put(field, entry.getValue());
  201. break;
  202. }
  203. }
  204. }
  205. return searchService.collectBySearchGoods(keyword, CollectField.valueOf(collectedField.toUpperCase()),
  206. filtersMap);
  207. }
  208. @RequestMapping("/kind/{id}")
  209. @ResponseBody
  210. public Kind getKind(@PathVariable Long id, HttpServletRequest request) {
  211. return searchService.getKind(id);
  212. }
  213. @RequestMapping("/brand/{id}")
  214. @ResponseBody
  215. public Brand getBrand(@PathVariable Long id, HttpServletRequest request) {
  216. return searchService.getBrand(id);
  217. }
  218. @RequestMapping("/component/{id}")
  219. @ResponseBody
  220. public Component getComponent(@PathVariable Long id, HttpServletRequest request) {
  221. return searchService.getComponent(id);
  222. }
  223. @RequestMapping("/goods/{id}")
  224. @ResponseBody
  225. public Goods getGoods(@PathVariable String id, HttpServletRequest request) {
  226. return searchService.getGoods(id);
  227. }
  228. @RequestMapping("/objects")
  229. @ResponseBody
  230. public SPage<Object> getObjects(@RequestParam(required = true) String tableName, String keyword, String field,
  231. Boolean tokenized, Integer page, Integer size, HttpServletRequest request) {
  232. return searchService.getObjects(tableName.toLowerCase(), keyword, field, tokenized, page == null ? 0 : page,
  233. size == null ? 0 : size);
  234. }
  235. @RequestMapping("/allObjectsToFiles")
  236. @ResponseBody
  237. public String writeAllObjectsToFiles(@RequestParam(required = true) String tableName, HttpServletRequest request) {
  238. int page = 1;
  239. int size = 1000;
  240. // 不能边更新索引边分页获取索引中的数据,因为索引更新后,分页顺序可能也会变化,
  241. // 所以要先把数据保存到本地,等待全部获取之后重建索引
  242. Long startTime = new Date().getTime();
  243. // 先删除旧的文件
  244. FileUtils.deleteSubFiles(new File(SearchUtils.getDataPath(tableName)));
  245. SPage<Object> sPage = searchService.getObjects(tableName.toLowerCase(), null, null, null, page, size);
  246. // 索引中数据的总数目
  247. long totalElements = sPage.getTotalElement();
  248. logger.info("发现数据:" + totalElements + "条");
  249. int fileIndex = 1;
  250. PrintWriter printWriter = null;
  251. int count = 0;
  252. try {
  253. File file = new File(SearchUtils.getDataPath(tableName));
  254. if (!file.exists()) {
  255. file.mkdirs();
  256. }
  257. printWriter = new PrintWriter(SearchUtils.getDataPath(tableName) + "/" + fileIndex + ".txt");
  258. while (true) {
  259. // 一个文件存放100000条数据,一旦超过,写入新的文件
  260. if (count > IndexServiceImpl.SINGLE_FILE_MAX_SIZE) {
  261. count = 1;
  262. printWriter.flush();
  263. printWriter.close();
  264. fileIndex++;
  265. printWriter = new PrintWriter(SearchUtils.getDataPath(tableName) + "/" + fileIndex + ".txt");
  266. }
  267. List<Object> content = sPage.getContent();
  268. for (Object element : content) {
  269. printWriter.println(JSONObject.toJSONString(element));
  270. count++;
  271. }
  272. logger.info(String.format(tableName + "...................%.2f%%",
  273. ((page - 1) * size + content.size()) * 100.0 / totalElements));
  274. if (++page > sPage.getTotalPage()) {
  275. break;
  276. }
  277. sPage = searchService.getObjects(tableName.toLowerCase(), null, null, null, page, size);
  278. }
  279. printWriter.flush();
  280. printWriter.close();
  281. } catch (FileNotFoundException | SecurityException | IllegalArgumentException e) {
  282. throw new SearchException(e).setDetailedMessage(e);
  283. }
  284. Long endTime = new Date().getTime();
  285. String message = String.format("写入数据%s条,耗时%.2fs\n ", totalElements, (endTime - startTime) / 1000.0);
  286. logger.info(message);
  287. return message;
  288. }
  289. }