Browse Source

物料搜索增加精准搜索模式

wangyc 6 years ago
parent
commit
9e85acff4e

+ 4 - 2
mall-search/src/main/java/com/uas/search/controller/SearchController.java

@@ -51,15 +51,17 @@ public class SearchController {
 	 * @param size  尺寸
 	 * @param enUU 企业UU
 	 * @param type 类型    standard 标准 nStandard 非标  其他为所有
+     * @param unique pcmpcode是否去重
 	 * @param request request
 	 * @return idPage
 	 * @throws IOException 输入异常
 	 */
 	@RequestMapping("/productIds")
 	@ResponseBody
-	public SPage<Long> searchProductIds(String keyword, Integer page, Integer size, Long enUU, String type,
+	public SPage<Long> searchProductIds(String keyword, Integer page, Integer size, Long enUU, String type,@RequestParam(value = "duplicate", defaultValue = "false", required = false) String duplicate,
 												HttpServletRequest request) throws IOException {
-		return searchService.getProductIds(enUU, keyword, page, size, type);
+			boolean duplicateCode = "false".equals(duplicate) ? false : true;
+		return searchService.getProductIds(enUU, keyword, page, size, type, duplicateCode);
 	}
 
 	/**

+ 2 - 1
mall-search/src/main/java/com/uas/search/service/SearchService.java

@@ -620,10 +620,11 @@ public interface SearchService {
 	 * @param page  页码
 	 * @param size  尺寸
 	 * @param type  all 全部  standard 标准   nStandard 非标
+	 * @param duplicate pcmpcode是否去重
 	 * @return idPage
 	 * @throws IOException 输入异常
 	 */
-	SPage<Long> getProductIds(Long enUU, String keyword, Integer page, Integer size, String type) throws IOException;
+	SPage<Long> getProductIds(Long enUU, String keyword, Integer page, Integer size, String type, Boolean duplicate) throws IOException;
 
 	/**
 	 * 查询物料(B2B)

+ 16 - 8
mall-search/src/main/java/com/uas/search/service/impl/SearchServiceImpl.java

@@ -131,9 +131,9 @@ public class SearchServiceImpl implements SearchService {
 	 * @throws IOException 输入异常
 	 */
 	@Override
-	public SPage<Long> getProductIds(Long enUU, String keyword, Integer page, Integer size, String type) throws IOException {
+	public SPage<Long> getProductIds(Long enUU, String keyword, Integer page, Integer size, String type, Boolean duplicate) throws IOException {
 		List<Long> ids = new ArrayList<>();
-		SPage<Document> documents = getProductDocuments(enUU, keyword, page, size, type);
+		SPage<Document> documents = getProductDocuments(enUU, keyword, page, size, type, duplicate);
 		SPage<Long> sPage = new SPage<>(documents.getTotalPage(), documents.getTotalElement(), documents.getPage(),
 				documents.getSize(), documents.isFirst(), documents.isLast());
 		for (Document document : documents.getContent()) {
@@ -526,7 +526,7 @@ public class SearchServiceImpl implements SearchService {
         return result;
     }
 
-    private SPage<Document> getProductDocuments(Long enUU, String keyword, Integer page, Integer size, String type) throws IOException {
+    private SPage<Document> getProductDocuments(Long enUU, String keyword, Integer page, Integer size, String type, Boolean duplicate) throws IOException {
 //		if (SearchUtils.isKeywordInvalid(keyword)) {
 //			throw new IllegalArgumentException("搜索关键词无效:" + keyword);
 //		}
@@ -544,13 +544,21 @@ public class SearchServiceImpl implements SearchService {
 		booleanQuery.add(q1, BooleanClause.Occur.MUST);
 		if (!StringUtils.isEmpty(keyword)) {
 			BooleanQuery q2 = new BooleanQuery();
-			q2.add(createQuery(SearchConstants.PRODUCT_PRIVATE_KIND_FIELD, keyword, true,1), BooleanClause.Occur.SHOULD);
-			q2.add(createQuery(SearchConstants.PRODUCT_PRIVATE_PBRANDEN_FIELD, keyword, true,1), BooleanClause.Occur.SHOULD);
-			q2.add(createQuery(SearchConstants.PRODUCT_PRIVATE_PCMPCODE_FIELD, keyword, true,1), BooleanClause.Occur.SHOULD);
+            if (!duplicate) {
+                q2.add(createQuery(SearchConstants.PRODUCT_PRIVATE_KIND_FIELD, keyword.toLowerCase(), true,1), BooleanClause.Occur.SHOULD);
+                q2.add(createQuery(SearchConstants.PRODUCT_PRIVATE_PBRANDEN_FIELD, keyword.toLowerCase(), true,1), BooleanClause.Occur.SHOULD);
+            }
+			q2.add(createQuery(SearchConstants.PRODUCT_PRIVATE_PCMPCODE_FIELD, keyword.toLowerCase(), true,1), BooleanClause.Occur.SHOULD);
 			booleanQuery.add(q2, BooleanClause.Occur.MUST);
 		}
-		logger.info(booleanQuery.toString());
-		return getDocuments(SearchConstants.PRODUCTS_PRIVATE_TABLE_NAME, booleanQuery, new Sort(sortProduct(keyword)), page, size);
+		if (Boolean.valueOf(duplicate)) {
+            DuplicateFilter duplicateFilter = new DuplicateFilter(SearchConstants.PRODUCT_PRIVATE_PCMPCODE_FIELD);
+            logger.info(booleanQuery.toString());
+            return getDocuments(SearchConstants.PRODUCTS_PRIVATE_TABLE_NAME, booleanQuery, new Sort(sortProduct(keyword)), page, size, duplicateFilter);
+        } else {
+            logger.info(booleanQuery.toString());
+            return getDocuments(SearchConstants.PRODUCTS_PRIVATE_TABLE_NAME, booleanQuery, new Sort(sortProduct(keyword)), page, size);
+        }
 	}
 
 	/**

+ 90 - 0
mall-search/src/main/java/com/uas/search/util/SearchUtils.java

@@ -11,6 +11,7 @@ import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.index.Term;
+import org.apache.lucene.sandbox.queries.DuplicateFilter;
 import org.apache.lucene.search.BooleanClause.Occur;
 import org.apache.lucene.search.*;
 import org.slf4j.Logger;
@@ -371,6 +372,95 @@ public class SearchUtils {
 		return sPage;
 	}
 
+	/**
+	 * 根据查询条件获取指定表的Document列表
+	 *
+	 * @param tableName
+	 *            表名
+	 * @param query
+	 *            查询条件
+	 * @param sort 排序规则
+	 * @param page
+	 *            页码
+	 * @param size
+	 *            页大小
+	 * @return
+	 */
+	public static SPage<Document> getDocuments(String tableName, Query query, Sort sort, Integer page, Integer size, DuplicateFilter duplicateFilter) throws IOException {
+		if (query == null) {
+			throw new IllegalArgumentException("query不能为null");
+		}
+		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);
+
+		TopDocs topDocs;
+
+		try {
+			// 如果页码不为1
+			if (sPage.getPage() > 1) {
+				TopDocs previousTopDocs;
+				previousTopDocs = sort == null ? indexSearcher.search(query, duplicateFilter, (sPage.getPage() - 1) * sPage.getSize()) :
+					indexSearcher.search(query, duplicateFilter, (sPage.getPage() - 1) * sPage.getSize(), sort);
+				int totalHits = previousTopDocs.totalHits;
+				int totalPage = (int) Math.ceil(totalHits / (1.0 * sPage.getSize()));
+				if (totalPage == 0) {
+					sPage.setTotalElement(0);
+					sPage.setTotalPage(0);
+					sPage.setContent(new ArrayList<Document>());
+					return sPage;
+				}
+				if (sPage.getPage() > totalPage) {
+					sPage.setPage(totalPage);
+					if (totalPage == 1) {
+						sPage.setFirst(true);
+						topDocs = previousTopDocs;
+					} else {
+						previousTopDocs = sort == null ? indexSearcher.search(query, duplicateFilter, (sPage.getPage() - 1) * sPage.getSize()) : indexSearcher.search(query, duplicateFilter, (sPage.getPage() - 1) * sPage.getSize(), sort);
+						ScoreDoc[] previousScoreDocs = previousTopDocs.scoreDocs;
+						topDocs = sort == null ? indexSearcher.searchAfter(previousScoreDocs[previousScoreDocs.length - 1], query, duplicateFilter, sPage.getSize()) : indexSearcher.searchAfter(previousScoreDocs[previousScoreDocs.length - 1], query, duplicateFilter, sPage.getSize(), sort);
+					}
+				} else {
+					previousTopDocs = sort == null ? indexSearcher.search(query, duplicateFilter, (sPage.getPage() - 1) * sPage.getSize()) : indexSearcher.search(query, duplicateFilter, (sPage.getPage() - 1) * sPage.getSize(), sort);
+					ScoreDoc[] previousScoreDocs = previousTopDocs.scoreDocs;
+					topDocs = sort == null ? indexSearcher.searchAfter(previousScoreDocs[previousScoreDocs.length - 1], query, duplicateFilter, sPage.getSize()) : indexSearcher.searchAfter(previousScoreDocs[previousScoreDocs.length - 1], query, duplicateFilter, sPage.getSize(), sort);
+				}
+			} else {
+				sPage.setFirst(true);
+				topDocs = sort == null ? indexSearcher.search(query, duplicateFilter, sPage.getSize()) : indexSearcher.search(query, duplicateFilter, sPage.getSize(), sort);
+			}
+
+			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);
+		} finally {
+			releaseIndexSearcher(indexSearcher);
+		}
+		return sPage;
+	}
+
 	/**
 	 * 获取各表索引的id字段名
 	 *