SearchController.java 16 KB

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