SearchController.java 13 KB

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