Browse Source

搜索批次时,先精确匹配品牌

sunyj 8 years ago
parent
commit
5ccfbae49d

+ 102 - 32
search-console/src/main/java/com/uas/search/console/service/impl/SearchServiceImpl.java

@@ -48,6 +48,7 @@ import com.uas.search.grouping.GoodsGroupCollector;
 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;
 import com.uas.search.service.SearchService;
 import com.uas.search.sort.SimilarValuesFieldComparatorSource;
 
@@ -355,29 +356,6 @@ public class SearchServiceImpl implements SearchService, InnerSearchService {
 		return booleanQuery;
 	}
 
-	/**
-	 * 同时搜索器件、类目、品牌,并设置boost
-	 * 
-	 * @param keyword
-	 * @return
-	 */
-	private Query setGoodsBoost(String keyword) {
-		BooleanQuery booleanQuery = new BooleanQuery();
-		BooleanQuery componentCodeQuery = SearchUtils.getBooleanQuery(SearchConstants.GOODS_CMP_CODE_FIELD, keyword);
-		componentCodeQuery.setBoost(100);
-		booleanQuery.add(componentCodeQuery, BooleanClause.Occur.SHOULD);
-		BooleanQuery brandNameCnQuery = SearchUtils.getBooleanQuery(SearchConstants.GOODS_BR_NAME_CN_FIELD, keyword);
-		brandNameCnQuery.setBoost(10);
-		booleanQuery.add(brandNameCnQuery, BooleanClause.Occur.SHOULD);
-		BooleanQuery brandNameEnQuery = SearchUtils.getBooleanQuery(SearchConstants.GOODS_BR_NAME_EN_FIELD, keyword);
-		brandNameEnQuery.setBoost(10);
-		booleanQuery.add(brandNameEnQuery, BooleanClause.Occur.SHOULD);
-		BooleanQuery kindNameQuery = SearchUtils.getBooleanQuery(SearchConstants.GOODS_KI_NAME_CN_FIELD, keyword);
-		kindNameQuery.setBoost(1);
-		booleanQuery.add(kindNameQuery, BooleanClause.Occur.SHOULD);
-		return booleanQuery;
-	}
-
 	@Override
 	public Set<Long> getKindIdsBySearchComponent(String keyword, String brandId) {
 		if (SearchUtils.isKeywordInvalid(keyword)) {
@@ -843,6 +821,29 @@ public class SearchServiceImpl implements SearchService, InnerSearchService {
 
 	@Override
 	public Map<String, Object> getGoodsIds(String keyword, PageParams pageParams) throws SearchException {
+		List<String> keywordFields = new ArrayList<>();
+		keywordFields.add(SearchConstants.GOODS_BR_NAME_CN_UNTOKENIZED_FIELD);
+		keywordFields.add(SearchConstants.GOODS_BR_NAME_EN_UNTOKENIZED_FIELD);
+		Map<String, Object> goodsIds = getGoodsIds(keyword, keywordFields, false, pageParams);
+		if (CollectionUtils.isEmpty(goodsIds)
+				|| JSONObject.parseArray(goodsIds.get("componentIds").toString()).isEmpty()) {
+			goodsIds = getGoodsIds(keyword, null, true, pageParams);
+		}
+		return goodsIds;
+	}
+
+	/**
+	 * @param keyword
+	 * @param keywordFields
+	 *            要查询的字段
+	 * @param tokenized
+	 *            是否分词
+	 * @param pageParams
+	 * @return
+	 * @throws SearchException
+	 */
+	private Map<String, Object> getGoodsIds(String keyword, List<String> keywordFields, Boolean tokenized,
+			PageParams pageParams) throws SearchException {
 		// 因为器件、属性值的数据量远比类目、品牌大得多,而且器件搜索可能还需进行分页,
 		// 所以涉及器件、属性值的搜索,大都不能像类目和品牌一样直接利用SearchUtils.getDocuments方法
 		IndexSearcher indexSearcher = SearchUtils.getIndexSearcher(SearchConstants.GOODS_TABLE_NAME);
@@ -859,11 +860,7 @@ public class SearchServiceImpl implements SearchService, InnerSearchService {
 		List<Long> cmpIds = new ArrayList<>();
 		List<Long> goIds = new ArrayList<>();
 		try {
-			BooleanQuery booleanQuery = new BooleanQuery();
-			if (!SearchUtils.isKeywordInvalid(keyword)) {
-				booleanQuery.add(setGoodsBoost(keyword), BooleanClause.Occur.MUST);
-			}
-
+			BooleanQuery booleanQuery = queryGoods(keyword, keywordFields, tokenized);
 			Map<FilterField, Object> filters = pageParams.getFilters();
 			if (!CollectionUtils.isEmpty(filters)) {
 				// 筛选类目
@@ -1007,6 +1004,29 @@ public class SearchServiceImpl implements SearchService, InnerSearchService {
 	@Override
 	public List<Map<String, Object>> collectBySearchGoods(String keyword, CollectField collectedField,
 			Map<FilterField, Object> filters) {
+		List<String> keywordFields = new ArrayList<>();
+		keywordFields.add(SearchConstants.GOODS_BR_NAME_CN_UNTOKENIZED_FIELD);
+		keywordFields.add(SearchConstants.GOODS_BR_NAME_EN_UNTOKENIZED_FIELD);
+		List<Map<String, Object>> result = collectBySearchGoods(keyword, keywordFields, false, collectedField, filters);
+		if (CollectionUtils.isEmpty(result)) {
+			result = collectBySearchGoods(keyword, null, true, collectedField, filters);
+		}
+		return result;
+
+	}
+
+	/**
+	 * @param keyword
+	 * @param keywordFields
+	 *            要查询的字段
+	 * @param tokenized
+	 *            是否分词
+	 * @param collectedField
+	 * @param filters
+	 * @return
+	 */
+	private List<Map<String, Object>> collectBySearchGoods(String keyword, List<String> keywordFields,
+			Boolean tokenized, CollectField collectedField, Map<FilterField, Object> filters) {
 		if (collectedField == null && CollectionUtils.isEmpty(filters)) {
 			throw new SearchException("参数不合法:collectedField=" + collectedField + ", filter=" + filters);
 		}
@@ -1014,10 +1034,7 @@ public class SearchServiceImpl implements SearchService, InnerSearchService {
 
 		List<Map<String, Object>> result = new ArrayList<>();
 		try {
-			BooleanQuery booleanQuery = new BooleanQuery();
-			if (!SearchUtils.isKeywordInvalid(keyword)) {
-				booleanQuery.add(setGoodsBoost(keyword), BooleanClause.Occur.MUST);
-			}
+			BooleanQuery booleanQuery = queryGoods(keyword, keywordFields, tokenized);
 			// 过滤
 			Set<Entry<FilterField, Object>> entrySet = filters.entrySet();
 			for (Entry<FilterField, Object> entry : entrySet) {
@@ -1076,7 +1093,60 @@ public class SearchServiceImpl implements SearchService, InnerSearchService {
 			SearchUtils.releaseIndexSearcher(indexSearcher);
 		}
 		return result;
+	}
+
+	/**
+	 * 获取查询批次的query
+	 * 
+	 * @param keyword
+	 * @param keywordFields
+	 * @param tokenized
+	 * @return
+	 */
+	private BooleanQuery queryGoods(String keyword, List<String> keywordFields, Boolean tokenized) {
+		BooleanQuery booleanQuery = new BooleanQuery();
+		if (!SearchUtils.isKeywordInvalid(keyword)) {
+			// 未指定搜索的字段,则采用默认搜索逻辑
+			if (CollectionUtils.isEmpty(keywordFields)) {
+				booleanQuery.add(setGoodsBoost(keyword), BooleanClause.Occur.MUST);
+			} else {
+				BooleanQuery booleanQuery2 = new BooleanQuery();
+				for (String keywordField : keywordFields) {
+					// 是否分词
+					if (tokenized == null || !tokenized.booleanValue()) {
+						booleanQuery2.add(new TermQuery(new Term(keywordField, keyword)), BooleanClause.Occur.SHOULD);
+					} else {
+						booleanQuery2.add(SearchUtils.getBooleanQuery(keywordField, keyword),
+								BooleanClause.Occur.SHOULD);
+					}
+				}
+				booleanQuery.add(booleanQuery2, BooleanClause.Occur.MUST);
+			}
+		}
+		return booleanQuery;
+	}
 
+	/**
+	 * 同时搜索器件、类目、品牌,并设置boost
+	 * 
+	 * @param keyword
+	 * @return
+	 */
+	private Query setGoodsBoost(String keyword) {
+		BooleanQuery booleanQuery = new BooleanQuery();
+		BooleanQuery componentCodeQuery = SearchUtils.getBooleanQuery(SearchConstants.GOODS_CMP_CODE_FIELD, keyword);
+		componentCodeQuery.setBoost(100);
+		booleanQuery.add(componentCodeQuery, BooleanClause.Occur.SHOULD);
+		BooleanQuery brandNameCnQuery = SearchUtils.getBooleanQuery(SearchConstants.GOODS_BR_NAME_CN_FIELD, keyword);
+		brandNameCnQuery.setBoost(10);
+		booleanQuery.add(brandNameCnQuery, BooleanClause.Occur.SHOULD);
+		BooleanQuery brandNameEnQuery = SearchUtils.getBooleanQuery(SearchConstants.GOODS_BR_NAME_EN_FIELD, keyword);
+		brandNameEnQuery.setBoost(10);
+		booleanQuery.add(brandNameEnQuery, BooleanClause.Occur.SHOULD);
+		BooleanQuery kindNameQuery = SearchUtils.getBooleanQuery(SearchConstants.GOODS_KI_NAME_CN_FIELD, keyword);
+		kindNameQuery.setBoost(1);
+		booleanQuery.add(kindNameQuery, BooleanClause.Occur.SHOULD);
+		return booleanQuery;
 	}
 
 	/**

+ 4 - 0
search-console/src/main/java/com/uas/search/console/util/ObjectToDocumentUtils.java

@@ -255,9 +255,13 @@ public class ObjectToDocumentUtils {
 		}
 		if (brand.getNameCn() != null) {
 			document.add(new TextField(SearchConstants.GOODS_BR_NAME_CN_FIELD, brand.getNameCn(), Store.YES));
+			document.add(
+					new StringField(SearchConstants.GOODS_BR_NAME_CN_UNTOKENIZED_FIELD, brand.getNameCn(), Store.YES));
 		}
 		if (brand.getNameEn() != null) {
 			document.add(new TextField(SearchConstants.GOODS_BR_NAME_EN_FIELD, brand.getNameEn(), Store.YES));
+			document.add(
+					new StringField(SearchConstants.GOODS_BR_NAME_EN_UNTOKENIZED_FIELD, brand.getNameEn(), Store.YES));
 		}
 		if (brand.getUuid() != null) {
 			document.add(new StringField(SearchConstants.GOODS_BR_UUID_FIELD, brand.getUuid(), Store.YES));

+ 2 - 0
search-console/src/main/java/com/uas/search/console/util/SearchConstants.java

@@ -123,6 +123,8 @@ public class SearchConstants {
 	public static final String GOODS_BR_ID_FIELD = "br_id";
 	public static final String GOODS_BR_NAME_CN_FIELD = "br_name_cn";
 	public static final String GOODS_BR_NAME_EN_FIELD = "br_name_en";
+	public static final String GOODS_BR_NAME_CN_UNTOKENIZED_FIELD = "br_name_cn_untokenized";
+	public static final String GOODS_BR_NAME_EN_UNTOKENIZED_FIELD = "br_name_en_untokenized";
 	public static final String GOODS_BR_UUID_FIELD = "br_uuid";
 
 	// 商城销售订单索引字段的key