Przeglądaj źródła

Specify the size of similar keywords

sunyj 8 lat temu
rodzic
commit
ad4a98a083

+ 28 - 36
src/main/java/com/uas/search/controller/SearchController.java

@@ -1,29 +1,5 @@
 package com.uas.search.controller;
 
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import javax.servlet.http.HttpServletRequest;
-
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Controller;
-import org.springframework.util.CollectionUtils;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.ResponseBody;
-
 import com.alibaba.druid.util.StringUtils;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
@@ -43,6 +19,22 @@ import com.uas.search.service.SearchService;
 import com.uas.search.service.impl.IndexServiceImpl;
 import com.uas.search.util.FileUtils;
 import com.uas.search.util.SearchUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.PrintWriter;
+import java.util.*;
+import java.util.Map.Entry;
 
 /**
  * 搜索请求
@@ -179,39 +171,39 @@ public class SearchController {
 
 	@RequestMapping("/similarKeywords/{keyword}")
 	@ResponseBody
-	public List<String> getSimilarKeywords(@PathVariable String keyword, HttpServletRequest request) {
-		return searchService.getSimilarKeywords(keyword);
+	public List<String> getSimilarKeywords(@PathVariable String keyword, Integer size, HttpServletRequest request) {
+		return searchService.getSimilarKeywords(keyword, size);
 	}
 
 	@RequestMapping("/similarComponents/{componentCode}")
 	@ResponseBody
-	public List<Map<String, Object>> getSimilarComponents(@PathVariable String componentCode,
+	public List<Map<String, Object>> getSimilarComponents(@PathVariable String componentCode, Integer size,
 														  HttpServletRequest request) {
-		return searchService.getSimilarComponents(componentCode);
+		return searchService.getSimilarComponents(componentCode, size);
 	}
 
 	@RequestMapping("/similarBrands/{brandName}")
 	@ResponseBody
-	public List<Map<String, Object>> getSimilarBrands(@PathVariable String brandName, HttpServletRequest request) {
-		return searchService.getSimilarBrands(brandName);
+	public List<Map<String, Object>> getSimilarBrands(@PathVariable String brandName, Integer size, HttpServletRequest request) {
+		return searchService.getSimilarBrands(brandName, size);
 	}
 
 	@RequestMapping("/similarKinds/{kindName}")
 	@ResponseBody
-	public List<Map<String, Object>> getSimilarKinds(@PathVariable String kindName, HttpServletRequest request) {
-		return searchService.getSimilarKinds(kindName);
+	public List<Map<String, Object>> getSimilarKinds(@PathVariable String kindName, Integer size, HttpServletRequest request) {
+		return searchService.getSimilarKinds(kindName, size);
 	}
 
 	@RequestMapping("/similarLeafKinds/{kindName}")
 	@ResponseBody
-	public List<Map<String, Object>> getSimilarLeafKinds(@PathVariable String kindName, HttpServletRequest request) {
-		return searchService.getSimilarLeafKinds(kindName);
+	public List<Map<String, Object>> getSimilarLeafKinds(@PathVariable String kindName, Integer size, HttpServletRequest request) {
+		return searchService.getSimilarLeafKinds(kindName, size);
 	}
 
 	@RequestMapping("/similarKindsByLevel")
 	@ResponseBody
-	public List<Map<String, Object>> getSimilarKindsByLevel(String kindName, Short level, HttpServletRequest request) {
-		return searchService.getSimilarKindsByLevel(kindName, level);
+	public List<Map<String, Object>> getSimilarKindsByLevel(String kindName, Short level, Integer size, HttpServletRequest request) {
+		return searchService.getSimilarKindsByLevel(kindName, level, size);
 	}
 
 	@RequestMapping("/similarPropertyValues")

+ 17 - 11
src/main/java/com/uas/search/service/SearchService.java

@@ -1,20 +1,20 @@
 package com.uas.search.service;
 
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 import com.uas.search.annotation.NotEmpty;
 import com.uas.search.constant.model.CollectField;
 import com.uas.search.constant.model.PageParams;
-import com.uas.search.constant.model.SPage;
 import com.uas.search.constant.model.PageParams.FilterField;
+import com.uas.search.constant.model.SPage;
 import com.uas.search.exception.SearchException;
 import com.uas.search.model.Brand;
 import com.uas.search.model.Component;
 import com.uas.search.model.Goods;
 import com.uas.search.model.Kind;
 
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 /**
  * 搜索服务的接口
  * 
@@ -181,56 +181,62 @@ public interface SearchService {
 	 * 根据输入获取联想词(包括器件、类目、品牌,按顺序获取,数量不足,才会获取下一个)
 	 * 
 	 * @param keyword
+	 * @param size 指定的联想词数目
 	 * @return
 	 * @throws SearchException
 	 */
-	public List<String> getSimilarKeywords(String keyword) throws SearchException;
+	public List<String> getSimilarKeywords(String keyword, Integer size) throws SearchException;
 
 	/**
 	 * 根据输入的原厂型号获取联想词
 	 * 
 	 * @param componentCode
+	 * @param size 指定的联想词数目
 	 * @return 包括id、uuid、code
 	 * @throws SearchException
 	 */
-	public List<Map<String, Object>> getSimilarComponents(String componentCode) throws SearchException;
+	public List<Map<String, Object>> getSimilarComponents(String componentCode, Integer size) throws SearchException;
 
 	/**
 	 * 根据输入的品牌获取联想词
 	 * 
 	 * @param brandName
+	 * @param size 指定的联想词数目
 	 * @return 包括id、uuid、nameCn、nameEn
 	 * @throws SearchException
 	 */
-	public List<Map<String, Object>> getSimilarBrands(String brandName) throws SearchException;
+	public List<Map<String, Object>> getSimilarBrands(String brandName, Integer size) throws SearchException;
 
 	/**
 	 * 根据输入的类目名获取联想词
 	 * 
 	 * @param kindName
+	 * @param size 指定的联想词数目
 	 * @return 包括id、nameCn、level、isLeaf
 	 * @throws SearchException
 	 */
-	public List<Map<String, Object>> getSimilarKinds(String kindName) throws SearchException;
+	public List<Map<String, Object>> getSimilarKinds(String kindName, Integer size) throws SearchException;
 
 	/**
 	 * 根据输入的类目名获取末级类目联想词
 	 * 
 	 * @param kindName
+	 * @param size 指定的联想词数目
 	 * @return 包括id、nameCn、level、isLeaf
 	 * @throws SearchException
 	 */
-	public List<Map<String, Object>> getSimilarLeafKinds(String kindName) throws SearchException;
+	public List<Map<String, Object>> getSimilarLeafKinds(String kindName, Integer size) throws SearchException;
 
 	/**
 	 * 根据输入的类目名和指定的类目级别获取联想词
 	 * 
 	 * @param kindName
 	 * @param level
+	 * @param size 指定的联想词数目
 	 * @return 包括id、nameCn、level、isLeaf
 	 * @throws SearchException
 	 */
-	public List<Map<String, Object>> getSimilarKindsByLevel(String kindName, Short level) throws SearchException;
+	public List<Map<String, Object>> getSimilarKindsByLevel(String kindName, Short level, Integer size) throws SearchException;
 
 	/**
 	 * 根据类目id、属性id、属性值获取联想词

+ 58 - 63
src/main/java/com/uas/search/service/impl/SearchServiceImpl.java

@@ -1,39 +1,7 @@
 package com.uas.search.service.impl;
 
-import java.io.IOException;
-import java.net.URLDecoder;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import com.uas.search.annotation.NotEmpty;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.search.BooleanClause;
-import org.apache.lucene.search.BooleanClause.Occur;
-import org.apache.lucene.search.BooleanQuery;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.NumericRangeQuery;
-import org.apache.lucene.search.PrefixQuery;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.ScoreDoc;
-import org.apache.lucene.search.Sort;
-import org.apache.lucene.search.SortField;
-import org.apache.lucene.search.SortField.Type;
-import org.apache.lucene.search.TermQuery;
-import org.apache.lucene.search.TopDocs;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Service;
-import org.springframework.util.CollectionUtils;
-import org.springframework.util.StringUtils;
-
 import com.alibaba.fastjson.JSONObject;
+import com.uas.search.annotation.NotEmpty;
 import com.uas.search.constant.SearchConstants;
 import com.uas.search.constant.model.CollectField;
 import com.uas.search.constant.model.PageParams;
@@ -50,6 +18,21 @@ import com.uas.search.service.SearchService;
 import com.uas.search.sort.SimilarValuesFieldComparatorSource;
 import com.uas.search.util.DocumentToObjectUtils;
 import com.uas.search.util.SearchUtils;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.*;
+import org.apache.lucene.search.BooleanClause.Occur;
+import org.apache.lucene.search.SortField.Type;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import java.io.IOException;
+import java.net.URLDecoder;
+import java.util.*;
+import java.util.Map.Entry;
 
 /**
  * 搜索索引
@@ -462,36 +445,37 @@ public class SearchServiceImpl implements SearchService {
 	}
 
 	@Override
-	public List<String> getSimilarKeywords(String keyword) {
+	public List<String> getSimilarKeywords(String keyword, Integer size) {
+		size = size == null || size < 1 ? SIMILAR_NUM : size;
 		List<String> result = new ArrayList<>();
 
 		// 相似的器件原厂型号数量足够,直接返回
-		List<String> componentCodes = getSimilarComponentCodes(keyword);
+		List<String> componentCodes = getSimilarComponentCodes(keyword, size);
 		result.addAll(componentCodes);
 		removeDuplicate(result);
-		if (result.size() == SIMILAR_NUM) {
+		if (result.size() == size) {
 			return result;
 		}
 
 		// 获取相似类目
-		List<String> kindNames = getSimilarKindNames(keyword);
+		List<String> kindNames = getSimilarKindNames(keyword, size);
 		if (!CollectionUtils.isEmpty(kindNames)) {
 			result.addAll(kindNames);
 			removeDuplicate(result);
 			// 如果总的数量超出SIMILAR_NUM,去除多余的元素
-			if (result.size() > SIMILAR_NUM) {
-				removeElements(result, SIMILAR_NUM);
+			if (result.size() > size) {
+				removeElements(result, size);
 				return result;
 			}
 		}
 
 		// 获取相似品牌
-		List<String> brandNames = getSimilarBrandNames(keyword);
+		List<String> brandNames = getSimilarBrandNames(keyword, size);
 		if (!CollectionUtils.isEmpty(brandNames)) {
 			result.addAll(brandNames);
 			removeDuplicate(result);
-			if (result.size() > SIMILAR_NUM) {
-				removeElements(result, SIMILAR_NUM);
+			if (result.size() > size) {
+				removeElements(result, size);
 				return result;
 			}
 		}
@@ -500,7 +484,8 @@ public class SearchServiceImpl implements SearchService {
 	}
 
 	@Override
-	public List<Map<String, Object>> getSimilarComponents(String componentCode) {
+	public List<Map<String, Object>> getSimilarComponents(String componentCode, Integer size) {
+		size = size == null || size < 1 ? SIMILAR_NUM : size;
 		if (SearchUtils.isKeywordInvalid(componentCode)) {
 			throw new SearchException("输入无效:" + componentCode);
 		}
@@ -511,7 +496,7 @@ public class SearchServiceImpl implements SearchService {
 			PrefixQuery prefixQuery = new PrefixQuery(
 					new Term(SearchConstants.COMPONENT_CODE_FIELD, componentCode.toLowerCase()));
 			logger.info(prefixQuery.toString());
-			TopDocs hits = indexSearcher.search(prefixQuery, SIMILAR_NUM);
+			TopDocs hits = indexSearcher.search(prefixQuery, size);
 			ScoreDoc[] scoreDocs = hits.scoreDocs;
 			for (ScoreDoc scoreDoc : scoreDocs) {
 				Set<String> fieldsToLoad = new HashSet<>();
@@ -534,7 +519,8 @@ public class SearchServiceImpl implements SearchService {
 	}
 
 	@Override
-	public List<Map<String, Object>> getSimilarBrands(String brandName) {
+	public List<Map<String, Object>> getSimilarBrands(String brandName, Integer size) {
+		size = size == null || size < 1 ? SIMILAR_NUM : size;
 		if (SearchUtils.isKeywordInvalid(brandName)) {
 			throw new SearchException("输入无效:" + brandName);
 		}
@@ -552,7 +538,7 @@ public class SearchServiceImpl implements SearchService {
 		}
 		logger.info(booleanQuery.toString());
 
-		List<Document> documents = SearchUtils.getDocuments(SearchConstants.BRAND_TABLE_NAME, booleanQuery)
+		List<Document> documents = SearchUtils.getDocuments(SearchConstants.BRAND_TABLE_NAME, booleanQuery, null, size)
 				.getContent();
 		for (Document document : documents) {
 			Map<String, Object> brand = new HashMap<>();
@@ -566,18 +552,21 @@ public class SearchServiceImpl implements SearchService {
 	}
 
 	@Override
-	public List<Map<String, Object>> getSimilarKinds(String kindName) {
-		return getSimilarKinds(kindName, null, null);
+	public List<Map<String, Object>> getSimilarKinds(String kindName, Integer size) {
+		size = size == null || size < 1 ? SIMILAR_NUM : size;
+		return getSimilarKinds(kindName, null, null, size);
 	}
 
 	@Override
-	public List<Map<String, Object>> getSimilarLeafKinds(String kindName) {
-		return getSimilarKinds(kindName, (short) 1, null);
+	public List<Map<String, Object>> getSimilarLeafKinds(String kindName, Integer size) {
+		size = size == null || size < 1 ? SIMILAR_NUM : size;
+		return getSimilarKinds(kindName, (short) 1, null, size);
 	}
 
 	@Override
-	public List<Map<String, Object>> getSimilarKindsByLevel(String kindName, Short level) {
-		return getSimilarKinds(kindName, null, level);
+	public List<Map<String, Object>> getSimilarKindsByLevel(String kindName, Short level, Integer size) {
+		size = size == null || size < 1 ? SIMILAR_NUM : size;
+		return getSimilarKinds(kindName, null, level, size);
 	}
 
 	/**
@@ -589,9 +578,11 @@ public class SearchServiceImpl implements SearchService {
 	 *            是否只获取末级类目
 	 * @param level
 	 *            指定的类目级别
+	 * @param size 指定的联想词数目
 	 * @return
 	 */
-	private List<Map<String, Object>> getSimilarKinds(String kindName, Short isLeaf, Short level) {
+	private List<Map<String, Object>> getSimilarKinds(String kindName, Short isLeaf, Short level, Integer size) {
+		size = size == null || size < 1 ? SIMILAR_NUM : size;
 		if (SearchUtils.isKeywordInvalid(kindName)) {
 			throw new SearchException("输入无效:" + kindName);
 		}
@@ -610,7 +601,7 @@ public class SearchServiceImpl implements SearchService {
 			}
 		}
 		logger.info(booleanQuery.toString());
-		List<Document> documents = SearchUtils.getDocuments(SearchConstants.KIND_TABLE_NAME, booleanQuery).getContent();
+		List<Document> documents = SearchUtils.getDocuments(SearchConstants.KIND_TABLE_NAME, booleanQuery, null, size).getContent();
 		for (Document document : documents) {
 			Map<String, Object> map = new HashMap<>();
 			map.put("id", Long.parseLong(document.get(SearchConstants.KIND_ID_FIELD)));
@@ -685,23 +676,25 @@ public class SearchServiceImpl implements SearchService {
 	 * 根据输入获取相似的器件原厂型号
 	 * 
 	 * @param componentCode
+	 * @param size 指定的联想词数目
 	 * @return
 	 */
-	private List<String> getSimilarComponentCodes(String componentCode) {
+	private List<String> getSimilarComponentCodes(String componentCode, Integer size) {
 		return getSimilarValues(SearchConstants.COMPONENT_TABLE_NAME, SearchConstants.COMPONENT_CODE_FIELD,
-				componentCode.toLowerCase(), QueryType.PREFIX_QUERY);
+				componentCode.toLowerCase(), QueryType.PREFIX_QUERY, size);
 	}
 
 	/**
 	 * 根据输入获取相似的品牌名称
 	 * 
 	 * @param brandName
+	 * @param size 指定的联想词数目
 	 * @return
 	 */
-	private List<String> getSimilarBrandNames(String brandName) {
+	private List<String> getSimilarBrandNames(String brandName, Integer size) {
 		// 获取相似的中文品牌
 		List<String> nameCns = getSimilarValues(SearchConstants.BRAND_TABLE_NAME, SearchConstants.BRAND_NAMECN_FIELD,
-				brandName, QueryType.BOOLEAN_QUERY);
+				brandName, QueryType.BOOLEAN_QUERY, size);
 		// 相似的中文品牌数量足够,直接返回
 		if (nameCns != null && nameCns.size() == SIMILAR_NUM) {
 			return nameCns;
@@ -710,7 +703,7 @@ public class SearchServiceImpl implements SearchService {
 		List<String> names = nameCns;
 		// 获取相似的英文品牌
 		List<String> nameEns = getSimilarValues(SearchConstants.BRAND_TABLE_NAME, SearchConstants.BRAND_NAMEEN_FIELD,
-				brandName, QueryType.BOOLEAN_QUERY);
+				brandName, QueryType.BOOLEAN_QUERY, size);
 		names.addAll(nameEns);
 		return names;
 	}
@@ -719,11 +712,12 @@ public class SearchServiceImpl implements SearchService {
 	 * 根据输入获取相似的类目名称
 	 * 
 	 * @param kindName
+	 * @param size 指定的联想词数目
 	 * @return
 	 */
-	private List<String> getSimilarKindNames(String kindName) {
+	private List<String> getSimilarKindNames(String kindName, Integer size) {
 		return getSimilarValues(SearchConstants.KIND_TABLE_NAME, SearchConstants.KIND_NAMECN_FIELD, kindName,
-				QueryType.BOOLEAN_QUERY);
+				QueryType.BOOLEAN_QUERY, size);
 	}
 
 	private enum QueryType {
@@ -736,9 +730,10 @@ public class SearchServiceImpl implements SearchService {
 	 * @param tableName
 	 * @param field
 	 * @param keyword
+	 * @param size 指定的联想词数目
 	 * @return
 	 */
-	private List<String> getSimilarValues(String tableName, String field, String keyword, QueryType queryType) {
+	private List<String> getSimilarValues(String tableName, String field, String keyword, QueryType queryType, Integer size) {
 		if (SearchUtils.isKeywordInvalid(keyword)) {
 			throw new SearchException("输入无效:" + keyword);
 		}
@@ -757,7 +752,7 @@ public class SearchServiceImpl implements SearchService {
 			}
 			logger.info(query.toString());
 			Sort sort = new Sort(new SortField(field, new SimilarValuesFieldComparatorSource()));
-			TopDocs hits = indexSearcher.search(query, SIMILAR_NUM, sort, true, false);
+			TopDocs hits = indexSearcher.search(query, size, sort, true, false);
 			ScoreDoc[] scoreDocs = hits.scoreDocs;
 			for (ScoreDoc scoreDoc : scoreDocs) {
 				Set<String> fieldsToLoad = new HashSet<>();