Эх сурвалжийг харах

类目、品牌搜索做分页

sunyj 8 жил өмнө
parent
commit
27de4db868

+ 24 - 5
search-api/src/main/java/com/uas/search/service/SearchService.java

@@ -8,6 +8,7 @@ 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;
 
 /**
  * 搜索服务的接口
@@ -22,38 +23,56 @@ public interface SearchService {
 	 * 
 	 * @param keyword
 	 *            关键词
+	 * @param page
+	 *            页码
+	 * @param size
+	 *            页大小
 	 * @return 符合条件的类目id
 	 * @throws SearchException
 	 */
-	public List<Long> getKindIds(String keyword) throws SearchException;
+	public SPage<Long> getKindIds(String keyword, Integer page, Integer size) throws SearchException;
 
 	/**
 	 * 根据关键词搜索产品类目
 	 * 
 	 * @param keyword
+	 *            关键词
+	 * @param page
+	 *            页码
+	 * @param size
+	 *            页大小
 	 * @return
 	 * @throws SearchException
 	 */
-	public List<Map<String, Object>> getKinds(String keyword) throws SearchException;
+	public SPage<Map<String, Object>> getKinds(String keyword, Integer page, Integer size) throws SearchException;
 
 	/**
 	 * 根据关键词搜索产品品牌id
 	 * 
 	 * @param keyword
 	 *            关键词
+	 * @param page
+	 *            页码
+	 * @param size
+	 *            页大小
 	 * @return 符合条件的品牌id
 	 * @throws SearchException
 	 */
-	public List<Long> getBrandIds(String keyword) throws SearchException;
+	public SPage<Long> getBrandIds(String keyword, Integer page, Integer size) throws SearchException;
 
 	/**
 	 * 根据关键词搜索产品品牌
 	 * 
 	 * @param keyword
-	 * @return
+	 *            关键词
+	 * @param page
+	 *            页码
+	 * @param size
+	 *            页大小
+	 * @return 符合条件的品牌
 	 * @throws SearchException
 	 */
-	public List<Map<String, Object>> getBrands(String keyword) throws SearchException;
+	public SPage<Map<String, Object>> getBrands(String keyword, Integer page, Integer size) throws SearchException;
 
 	/**
 	 * 根据关键词搜索产品(关键词可能是器件、类目、品牌,甚至可能是类目、品牌的混合)

+ 8 - 8
search-console/src/main/java/com/uas/search/console/controller/SearchController.java

@@ -63,26 +63,26 @@ public class SearchController {
 
 	@RequestMapping("/kindIds/{keyword}")
 	@ResponseBody
-	public List<Long> seachKindIds(@PathVariable String keyword) {
-		return searchService.getKindIds(keyword);
+	public SPage<Long> seachKindIds(@PathVariable String keyword, Integer page, Integer size) {
+		return searchService.getKindIds(keyword, page, size);
 	}
 
 	@RequestMapping("/kinds/{keyword}")
 	@ResponseBody
-	public List<Map<String, Object>> seachKinds(@PathVariable String keyword) {
-		return searchService.getKinds(keyword);
+	public SPage<Map<String, Object>> seachKinds(@PathVariable String keyword, Integer page, Integer size) {
+		return searchService.getKinds(keyword, page, size);
 	}
 
 	@RequestMapping("/brandIds/{keyword}")
 	@ResponseBody
-	public List<Long> searchBrandIds(@PathVariable String keyword) {
-		return searchService.getBrandIds(keyword);
+	public SPage<Long> searchBrandIds(@PathVariable String keyword, Integer page, Integer size) {
+		return searchService.getBrandIds(keyword, page, size);
 	}
 
 	@RequestMapping("/brands/{keyword}")
 	@ResponseBody
-	public List<Map<String, Object>> searchBrand(@PathVariable String keyword) {
-		return searchService.getBrands(keyword);
+	public SPage<Map<String, Object>> searchBrand(@PathVariable String keyword, Integer page, Integer size) {
+		return searchService.getBrands(keyword, page, size);
 	}
 
 	@RequestMapping("/componentIds")

+ 41 - 48
search-console/src/main/java/com/uas/search/console/service/impl/SearchServiceImpl.java

@@ -69,83 +69,70 @@ public class SearchServiceImpl implements SearchService, InnerSearchService {
 	private static Logger logger = LoggerFactory.getLogger(SearchServiceImpl.class);
 
 	@Override
-	public List<Long> getKindIds(String keyword) {
-		return getKindIds(keyword, Occur.MUST);
-	}
-
-	/**
-	 * 根据关键字搜索产品类目id
-	 * 
-	 * @param keyword
-	 *            关键词
-	 * @param occur
-	 * @return 符合条件的类目id
-	 */
-	private List<Long> getKindIds(String keyword, Occur occur) {
+	public SPage<Long> getKindIds(String keyword, Integer page, Integer size) {
 		if (SearchUtils.isKeywordInvalid(keyword)) {
 			throw new SearchException("搜索关键词无效:" + keyword);
 		}
 		List<Long> ids = new ArrayList<Long>();
-		BooleanQuery booleanQuery = SearchUtils.getBooleanQuery(SearchConstants.KIND_NAMECN_FIELD, keyword, occur);
+		BooleanQuery booleanQuery = SearchUtils.getBooleanQuery(SearchConstants.KIND_NAMECN_FIELD, keyword);
 		logger.info(booleanQuery.toString());
-		List<Document> documents = SearchUtils.getDocuments(SearchConstants.KIND_TABLE_NAME, booleanQuery);
-		for (Document document : documents) {
+		SPage<Document> documents = SearchUtils.getDocuments(SearchConstants.KIND_TABLE_NAME, booleanQuery, page, size);
+		SPage<Long> sPage = new SPage<Long>(documents.getTotalPage(), documents.getTotalElement(), documents.getPage(),
+				documents.getSize(), documents.isFirst(), documents.isLast());
+		for (Document document : documents.getContent()) {
 			ids.add(Long.parseLong(document.get(SearchConstants.KIND_ID_FIELD)));
 		}
-		return ids;
+		sPage.setContent(ids);
+		return sPage;
 	}
 
 	@Override
-	public List<Map<String, Object>> getKinds(String keyword) {
+	public SPage<Map<String, Object>> getKinds(String keyword, Integer page, Integer size) {
 		if (SearchUtils.isKeywordInvalid(keyword)) {
 			throw new SearchException("搜索关键词无效:" + keyword);
 		}
 		List<Map<String, Object>> kinds = new ArrayList<Map<String, Object>>();
 		BooleanQuery booleanQuery = SearchUtils.getBooleanQuery(SearchConstants.KIND_NAMECN_FIELD, keyword);
 		logger.info(booleanQuery.toString());
-		List<Document> documents = SearchUtils.getDocuments(SearchConstants.KIND_TABLE_NAME, booleanQuery);
-		for (Document document : documents) {
+		SPage<Document> documents = SearchUtils.getDocuments(SearchConstants.KIND_TABLE_NAME, booleanQuery, page, size);
+		SPage<Map<String, Object>> sPage = new SPage<Map<String, Object>>(documents.getTotalPage(),
+				documents.getTotalElement(), documents.getPage(), documents.getSize(), documents.isFirst(),
+				documents.isLast());
+		for (Document document : documents.getContent()) {
 			Map<String, Object> kind = new HashMap<String, Object>();
 			kind.put("id", Long.parseLong(document.get(SearchConstants.KIND_ID_FIELD)));
 			kind.put("nameCn", document.get(SearchConstants.KIND_NAMECN_FIELD));
 			kinds.add(kind);
 		}
-		return kinds;
+		sPage.setContent(kinds);
+		return sPage;
 	}
 
 	@Override
-	public List<Long> getBrandIds(String keyword) {
-		return getBrandIds(keyword, Occur.MUST);
-	}
-
-	/**
-	 * 根据关键字搜索产品品牌id
-	 * 
-	 * @param keyword
-	 *            关键词
-	 * @param occur
-	 * @return 符合条件的品牌id
-	 */
-	private List<Long> getBrandIds(String keyword, Occur occur) {
+	public SPage<Long> getBrandIds(String keyword, Integer page, Integer size) {
 		if (SearchUtils.isKeywordInvalid(keyword)) {
 			throw new SearchException("搜索关键词无效:" + keyword);
 		}
 		List<Long> ids = new ArrayList<Long>();
 		BooleanQuery booleanQuery = new BooleanQuery();
-		booleanQuery.add(SearchUtils.getBooleanQuery(SearchConstants.BRAND_NAMECN_FIELD, keyword, occur),
+		booleanQuery.add(SearchUtils.getBooleanQuery(SearchConstants.BRAND_NAMECN_FIELD, keyword),
 				BooleanClause.Occur.SHOULD);
-		booleanQuery.add(SearchUtils.getBooleanQuery(SearchConstants.BRAND_NAMEEN_FIELD, keyword, occur),
+		booleanQuery.add(SearchUtils.getBooleanQuery(SearchConstants.BRAND_NAMEEN_FIELD, keyword),
 				BooleanClause.Occur.SHOULD);
 		logger.info(booleanQuery.toString());
-		List<Document> documents = SearchUtils.getDocuments(SearchConstants.BRAND_TABLE_NAME, booleanQuery);
-		for (Document document : documents) {
+		SPage<Document> documents = SearchUtils.getDocuments(SearchConstants.BRAND_TABLE_NAME, booleanQuery, page,
+				size);
+		SPage<Long> sPage = new SPage<Long>(documents.getTotalPage(), documents.getTotalElement(), documents.getPage(),
+				documents.getSize(), documents.isFirst(), documents.isLast());
+		for (Document document : documents.getContent()) {
 			ids.add(Long.parseLong(document.get(SearchConstants.BRAND_ID_FIELD)));
 		}
-		return ids;
+		sPage.setContent(ids);
+		return sPage;
 	}
 
 	@Override
-	public List<Map<String, Object>> getBrands(String keyword) {
+	public SPage<Map<String, Object>> getBrands(String keyword, Integer page, Integer size) {
 		if (SearchUtils.isKeywordInvalid(keyword)) {
 			throw new SearchException("搜索关键词无效:" + keyword);
 		}
@@ -156,8 +143,12 @@ public class SearchServiceImpl implements SearchService, InnerSearchService {
 		booleanQuery.add(SearchUtils.getBooleanQuery(SearchConstants.BRAND_NAMEEN_FIELD, keyword),
 				BooleanClause.Occur.SHOULD);
 		logger.info(booleanQuery.toString());
-		List<Document> documents = SearchUtils.getDocuments(SearchConstants.BRAND_TABLE_NAME, booleanQuery);
-		for (Document document : documents) {
+		SPage<Document> documents = SearchUtils.getDocuments(SearchConstants.BRAND_TABLE_NAME, booleanQuery, page,
+				size);
+		SPage<Map<String, Object>> sPage = new SPage<Map<String, Object>>(documents.getTotalPage(),
+				documents.getTotalElement(), documents.getPage(), documents.getSize(), documents.isFirst(),
+				documents.isLast());
+		for (Document document : documents.getContent()) {
 			Map<String, Object> brand = new HashMap<String, Object>();
 			brand.put("id", Long.parseLong(document.get(SearchConstants.BRAND_ID_FIELD)));
 			brand.put("uuid", document.get(SearchConstants.BRAND_UUID_FIELD));
@@ -165,7 +156,8 @@ public class SearchServiceImpl implements SearchService, InnerSearchService {
 			brand.put("nameEn", document.get(SearchConstants.BRAND_NAMEEN_FIELD));
 			brands.add(brand);
 		}
-		return brands;
+		sPage.setContent(brands);
+		return sPage;
 	}
 
 	@Override
@@ -402,7 +394,7 @@ public class SearchServiceImpl implements SearchService, InnerSearchService {
 			booleanQuery.add(new TermQuery(new Term(SearchConstants.KIND_ID_FIELD, String.valueOf(kindId))),
 					BooleanClause.Occur.SHOULD);
 		}
-		List<Document> documents = SearchUtils.getDocuments(SearchConstants.KIND_TABLE_NAME, booleanQuery);
+		List<Document> documents = SearchUtils.getDocuments(SearchConstants.KIND_TABLE_NAME, booleanQuery).getContent();
 		for (Document document : documents) {
 			Map<String, Object> kind = new HashMap<String, Object>();
 			kind.put("id", Long.parseLong(document.get(SearchConstants.KIND_ID_FIELD)));
@@ -458,7 +450,8 @@ public class SearchServiceImpl implements SearchService, InnerSearchService {
 			booleanQuery.add(new TermQuery(new Term(SearchConstants.BRAND_ID_FIELD, String.valueOf(brandId))),
 					BooleanClause.Occur.SHOULD);
 		}
-		List<Document> documents = SearchUtils.getDocuments(SearchConstants.BRAND_TABLE_NAME, booleanQuery);
+		List<Document> documents = SearchUtils.getDocuments(SearchConstants.BRAND_TABLE_NAME, booleanQuery)
+				.getContent();
 		for (Document document : documents) {
 			Map<String, Object> brand = new HashMap<String, Object>();
 			brand.put("id", Long.parseLong(document.get(SearchConstants.BRAND_ID_FIELD)));
@@ -560,8 +553,8 @@ public class SearchServiceImpl implements SearchService, InnerSearchService {
 		}
 		logger.info(booleanQuery.toString());
 
-		List<Document> documents = SearchUtils.getDocuments(SearchConstants.BRAND_TABLE_NAME, booleanQuery,
-				SIMILAR_NUM);
+		List<Document> documents = SearchUtils.getDocuments(SearchConstants.BRAND_TABLE_NAME, booleanQuery)
+				.getContent();
 		for (Document document : documents) {
 			Map<String, Object> brand = new HashMap<>();
 			brand.put("id", Long.parseLong(document.get(SearchConstants.BRAND_ID_FIELD)));
@@ -618,7 +611,7 @@ public class SearchServiceImpl implements SearchService, InnerSearchService {
 			}
 		}
 		logger.info(booleanQuery.toString());
-		List<Document> documents = SearchUtils.getDocuments(SearchConstants.KIND_TABLE_NAME, booleanQuery, SIMILAR_NUM);
+		List<Document> documents = SearchUtils.getDocuments(SearchConstants.KIND_TABLE_NAME, booleanQuery).getContent();
 		for (Document document : documents) {
 			Map<String, Object> map = new HashMap<>();
 			map.put("id", Long.parseLong(document.get(SearchConstants.KIND_ID_FIELD)));

+ 66 - 52
search-console/src/main/java/com/uas/search/console/util/SearchUtils.java

@@ -36,6 +36,7 @@ import com.uas.search.console.model.PurchaseInvoiceSimpleInfo;
 import com.uas.search.console.model.PurchaseSimpleInfo;
 import com.uas.search.console.support.IndexSearcherManager;
 import com.uas.search.exception.SearchException;
+import com.uas.search.model.SPage;
 
 /**
  * 搜索相关的工具类
@@ -45,6 +46,16 @@ import com.uas.search.exception.SearchException;
  */
 public class SearchUtils {
 
+	/**
+	 * 默认的页码
+	 */
+	private static final int PAGE_INDEX = 1;
+
+	/**
+	 * 默认每页的大小
+	 */
+	private static final int PAGE_SIZE = 20;
+
 	private static Logger logger = LoggerFactory.getLogger(SearchUtils.class);
 
 	/**
@@ -186,10 +197,11 @@ public class SearchUtils {
 	 * @return Document
 	 */
 	public static Document getDocumentById(String tableName, String field, String id) {
-		if (id == null) {
-			throw new SearchException("输入无效:" + id);
+		if (StringUtils.isEmpty(field) || StringUtils.isEmpty(id)) {
+			throw new SearchException("搜索的域和搜索词不能为空");
 		}
-		List<Document> documents = getDocuments(tableName, field, id);
+		TermQuery termQuery = new TermQuery(new Term(field, id));
+		List<Document> documents = getDocuments(tableName, termQuery).getContent();
 		if (CollectionUtils.isEmpty(documents)) {
 			return null;
 		} else if (documents.size() > 1) {
@@ -198,42 +210,6 @@ public class SearchUtils {
 		return documents.get(0);
 	}
 
-	/**
-	 * 根据域和搜索词获取指定表的Document列表
-	 * 
-	 * @param tableName
-	 *            表名
-	 * @param field
-	 *            搜索域
-	 * @param keyword
-	 *            搜索词
-	 * @return Document列表
-	 */
-	public static List<Document> getDocuments(String tableName, String field, String keyword) {
-		return getDocuments(tableName, field, keyword, SearchConstants.TOP_NUM);
-	}
-
-	/**
-	 * 根据域和搜索词获取指定数目的指定表的Document列表
-	 * 
-	 * @param tableName
-	 *            表名
-	 * @param field
-	 *            搜索域
-	 * @param keyword
-	 *            搜索词
-	 * @param topNum
-	 *            指定的数目(数目最多为该数目)
-	 * @return
-	 */
-	public static List<Document> getDocuments(String tableName, String field, String keyword, int topNum) {
-		if (StringUtils.isEmpty(field) || StringUtils.isEmpty(keyword)) {
-			throw new SearchException("搜索的域和搜索词不能为空");
-		}
-		TermQuery termQuery = new TermQuery(new Term(field, keyword));
-		return getDocuments(tableName, termQuery, topNum);
-	}
-
 	/**
 	 * 根据查询条件获取指定表的Document列表
 	 * 
@@ -243,42 +219,80 @@ public class SearchUtils {
 	 *            查询条件
 	 * @return
 	 */
-	public static List<Document> getDocuments(String tableName, Query query) {
-		return getDocuments(tableName, query, SearchConstants.TOP_NUM);
+	public static SPage<Document> getDocuments(String tableName, Query query) {
+		return getDocuments(tableName, query, null, null);
 	}
 
 	/**
-	 * 根据查询条件获取指定数目的指定表的Document列表
+	 * 根据查询条件获取指定表的Document列表
 	 * 
 	 * @param tableName
 	 *            表名
 	 * @param query
 	 *            查询条件
-	 * @param topNum
-	 *            指定的数目(数目最多为该数目)
+	 * @param page
+	 *            页码
+	 * @param size
+	 *            页大小
 	 * @return
 	 */
-	public static List<Document> getDocuments(String tableName, Query query, int topNum) {
+	public static SPage<Document> getDocuments(String tableName, Query query, Integer page, Integer size) {
 		if (query == null) {
 			throw new SearchException("query不能为null");
 		}
-		if (topNum < 1) {
-			throw new SearchException("查询的数目topNum不能小于1");
+		SPage<Document> sPage = new SPage<>();
+		if (page != null && page > 0) {
+			sPage.setPage(page);
+		} else {
+			sPage.setPage(PAGE_INDEX);
+			sPage.setFirst(true);
+		}
+		if (size != null && size > 0) {
+			sPage.setSize(size);
+		} else {
+			sPage.setSize(PAGE_SIZE);
 		}
 		IndexSearcher indexSearcher = getIndexSearcher(tableName);
-		List<Document> documents = new ArrayList<>();
+
+		TopDocs topDocs;
 		try {
-			TopDocs topDocs = indexSearcher.search(query, topNum);
-			ScoreDoc[] scoreDocs = topDocs.scoreDocs;
-			for (ScoreDoc scoreDoc : scoreDocs) {
+			// 如果页码不为1
+			if (sPage.getPage() > 1) {
+				TopDocs previousTopDocs = null;
+				previousTopDocs = indexSearcher.search(query, (sPage.getPage() - 1) * sPage.getSize());
+				int totalHits = previousTopDocs.totalHits;
+				ScoreDoc[] previousScoreDocs = previousTopDocs.scoreDocs;
+				if ((sPage.getPage() - 1) * sPage.getSize() >= totalHits) {
+					throw new SearchException("页码过大:元素总数量为" + totalHits);
+				}
+				topDocs = indexSearcher.searchAfter(previousScoreDocs[previousScoreDocs.length - 1], query,
+						sPage.getSize());
+			} else {
+				sPage.setFirst(true);
+				topDocs = indexSearcher.search(query, sPage.getSize());
+			}
+
+			int totalHits = topDocs.totalHits;
+			// 设置总元素个数、页数等信息
+			sPage.setTotalElement(totalHits);
+			int totalPage = (int) Math.ceil(totalHits / (1.0 * sPage.getSize()));
+			sPage.setTotalPage(totalPage);
+			if (totalPage == sPage.getPage()) {
+				sPage.setLast(true);
+			}
+
+			List<Document> documents = new ArrayList<>();
+			for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
 				documents.add(indexSearcher.doc(scoreDoc.doc));
 			}
+
+			sPage.setContent(documents);
 		} catch (IOException e) {
 			throw new SearchException(e).setDetailedMessage(e);
 		} finally {
 			releaseIndexSearcher(indexSearcher);
 		}
-		return documents;
+		return sPage;
 	}
 
 	/**

+ 4 - 4
search-console/src/main/webapp/WEB-INF/views/console.html

@@ -12,10 +12,10 @@
 			<ol>
 				<strong><li class="title">搜索</li></strong>
 				<ol>
-					<li><a target="_blank">search/kindIds/电阻</a></li>
-					<li><a target="_blank">search/kinds/电阻</a></li>
-					<li><a target="_blank">search/brandIds/Panasonic</a></li>
-					<li><a target="_blank">search/brands/Panasonic</a></li>
+					<li><a target="_blank">search/kindIds/电阻?page=1&size=10</a></li>
+					<li><a target="_blank">search/kinds/电阻?page=1&size=10</a></li>
+					<li><a target="_blank">search/brandIds/Panasonic?page=1&size=10</a></li>
+					<li><a target="_blank">search/brands/Panasonic?page=1&size=10</a></li>
 					<li>search/componentIds?keyword=a&page=1&size=5&filters={"COMPONENT_KINDID":401,"COMPONENT_BRANDID":45,"COMPONENT_HAS_RESERVE":true,"COMPONENT_HAS_SAMPLE":true,"COMPONENT_HAS_ORIGINAL":true,"COMPONENT_HAS_INACTION_STOCK":true,"COMPONENT_PROPERTIES":{"275":"92%20dB","781":"Tube"}}</li>
 					<li><a target="_blank">search/componentIds?keyword=aaa</a></li>
 					<li><a target="_blank">search/components?keyword=aaa</a></li>