SearchController.java 13 KB

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