|
|
@@ -1,5 +1,10 @@
|
|
|
package com.uas.search.service.impl;
|
|
|
|
|
|
+import static com.uas.search.constant.model.Sort.Field.PRICE;
|
|
|
+import static com.uas.search.constant.model.Sort.Field.RESERVE;
|
|
|
+import static com.uas.search.util.SearchUtils.getDocuments;
|
|
|
+import static com.uas.search.util.SearchUtils.releaseIndexSearcher;
|
|
|
+
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import com.uas.search.annotation.NotEmpty;
|
|
|
import com.uas.search.constant.SearchConstants;
|
|
|
@@ -23,8 +28,18 @@ import com.uas.search.util.DocumentToObjectUtils;
|
|
|
import com.uas.search.util.ObjectToDocumentUtils;
|
|
|
import com.uas.search.util.SearchUtils;
|
|
|
import com.uas.search.util.StringUtils;
|
|
|
+import java.io.IOException;
|
|
|
+import java.net.URLDecoder;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.HashSet;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Set;
|
|
|
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;
|
|
|
import org.apache.lucene.search.BooleanClause.Occur;
|
|
|
import org.apache.lucene.search.BooleanQuery;
|
|
|
@@ -43,19 +58,6 @@ import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
-import java.io.IOException;
|
|
|
-import java.net.URLDecoder;
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.Arrays;
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.HashSet;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
-import java.util.Set;
|
|
|
-
|
|
|
-import static com.uas.search.constant.model.Sort.Field.PRICE;
|
|
|
-import static com.uas.search.constant.model.Sort.Field.RESERVE;
|
|
|
-
|
|
|
/**
|
|
|
* 搜索索引
|
|
|
*
|
|
|
@@ -90,6 +92,16 @@ public class SearchServiceImpl implements SearchService {
|
|
|
*/
|
|
|
private static final String NONSTANDARD_PRODUCTS = "nStandard";
|
|
|
|
|
|
+ /**
|
|
|
+ * 默认的页码
|
|
|
+ */
|
|
|
+ private static final int PAGE_INDEX = 1;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 默认每页的大小
|
|
|
+ */
|
|
|
+ private static final int PAGE_SIZE = 20;
|
|
|
+
|
|
|
private static Logger logger = LoggerFactory.getLogger(SearchServiceImpl.class);
|
|
|
|
|
|
/**
|
|
|
@@ -140,7 +152,7 @@ public class SearchServiceImpl implements SearchService {
|
|
|
booleanQuery.add(q2, BooleanClause.Occur.MUST);
|
|
|
}
|
|
|
logger.info(booleanQuery.toString());
|
|
|
- return SearchUtils.getDocuments(SearchConstants.PRODUCTS_PRIVATE_TABLE_NAME, booleanQuery, new Sort(sortProduct(keyword)), page, size);
|
|
|
+ return getDocuments(SearchConstants.PRODUCTS_PRIVATE_TABLE_NAME, booleanQuery, new Sort(sortProduct(keyword)), page, size);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -187,7 +199,7 @@ public class SearchServiceImpl implements SearchService {
|
|
|
}
|
|
|
BooleanQuery booleanQuery = SearchUtils.getBooleanQuery(SearchConstants.KIND_NAMECN_FIELD, keyword);
|
|
|
logger.info(booleanQuery.toString());
|
|
|
- return SearchUtils.getDocuments(SearchConstants.KIND_TABLE_NAME, booleanQuery, new Sort(sortKind(keyword)), page, size);
|
|
|
+ return getDocuments(SearchConstants.KIND_TABLE_NAME, booleanQuery, new Sort(sortKind(keyword)), page, size);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -250,17 +262,120 @@ public class SearchServiceImpl implements SearchService {
|
|
|
return sPage;
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public SPage<Map<String, Object>> getBrandsAndSellers(String keyword, Integer page, Integer size)
|
|
|
+ throws IOException {
|
|
|
+ List<Map<String, Object>> content = new ArrayList<>();
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ List<Long> brandIds = new ArrayList<>();
|
|
|
+ SPage<Object> stock = null;
|
|
|
+ SPage<Object> futures = null;
|
|
|
+
|
|
|
+ // 精准匹配
|
|
|
+ SPage<Long> documents = getBrandIds(keyword, page, size, false);
|
|
|
+ SPage<Map<String, Object>> sPage = new SPage<>(1, 1, 1, documents.getSize(), true, true);
|
|
|
+ // 精准匹配成功
|
|
|
+ if (!CollectionUtils.isEmpty(documents.getContent())) {
|
|
|
+ List<String> keywordFeilds = new ArrayList<>();
|
|
|
+ keywordFeilds.add(SearchConstants.GOODS_PR_PBRAND_EN_UNTOKENIZED_FIELD);
|
|
|
+ keywordFeilds.add(SearchConstants.GOODS_PR_PBRAND_CN_UNTOKENIZED_FIELD);
|
|
|
+
|
|
|
+ brandIds.add(documents.getContent().get(0));
|
|
|
+ // 获取卖家信息
|
|
|
+ Map<String, SPage<Object>> sellers = querySellers(keyword, keywordFeilds, page, size, false, SearchConstants.BRAND);
|
|
|
+ stock = sellers.get("stock");
|
|
|
+ futures = sellers.get("futures");
|
|
|
+
|
|
|
+ map.put("stock", stock);
|
|
|
+ map.put("futures", futures);
|
|
|
+ // 模糊匹配
|
|
|
+ } else {
|
|
|
+ SPage<Long> brandPage = getBrandIds(keyword, page, size, true);
|
|
|
+ brandIds = brandPage.getContent();
|
|
|
+ sPage = new SPage<>(brandPage.getTotalPage(), brandPage.getTotalElement(), brandPage.getPage(), brandPage.getSize(), brandPage.isFirst(), brandPage.isLast());
|
|
|
+ }
|
|
|
+
|
|
|
+ map.put("brandIds", brandIds);
|
|
|
+ content.add(map);
|
|
|
+ sPage.setContent(content);
|
|
|
+ return sPage;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> getSellersWithKind(String keyword, Integer page, Integer size)
|
|
|
+ throws IOException {
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ SPage<Object> stock = null;
|
|
|
+ SPage<Object> futures = null;
|
|
|
+ List<String> keywordFeilds = new ArrayList<>();
|
|
|
+ keywordFeilds.add(SearchConstants.GOODS_PR_KIND_FIELD);
|
|
|
+ Map<String, SPage<Object>> sellers = querySellers(keyword, keywordFeilds, page, size, true, SearchConstants.KIND);
|
|
|
+ stock = sellers.get("stock");
|
|
|
+ futures = sellers.get("futures");
|
|
|
+
|
|
|
+ map.put("stock", stock);
|
|
|
+ map.put("futures", futures);
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取品牌id
|
|
|
+ * @param keyword
|
|
|
+ * @param page
|
|
|
+ * @param size
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private SPage<Long> getBrandIds(String keyword, Integer page, Integer size, Boolean tokenized) throws IOException{
|
|
|
+ List<Long> brandIds = new ArrayList<>();
|
|
|
+ if (SearchUtils.isKeywordInvalid(keyword)) {
|
|
|
+ throw new IllegalArgumentException("搜索关键词无效:" + keyword);
|
|
|
+ }
|
|
|
+ BooleanQuery booleanQuery = new BooleanQuery();
|
|
|
+ if (tokenized) {
|
|
|
+ booleanQuery.add(SearchUtils.getBooleanQuery(SearchConstants.BRAND_NAMECN_FIELD, keyword),
|
|
|
+ BooleanClause.Occur.SHOULD);
|
|
|
+ booleanQuery.add(SearchUtils.getBooleanQuery(SearchConstants.BRAND_NAMEEN_FIELD, keyword),
|
|
|
+ BooleanClause.Occur.SHOULD);
|
|
|
+ } else {
|
|
|
+ booleanQuery.add(new TermQuery(new Term(SearchConstants.BRAND_NAMECN_UNTOKENIZED_FIELD, keyword.toLowerCase())), Occur.SHOULD);
|
|
|
+ booleanQuery.add(new TermQuery(new Term(SearchConstants.BRAND_NAMEEN_UNTOKENIZED_FIELD, keyword.toLowerCase())), Occur.SHOULD);
|
|
|
+ }
|
|
|
+ logger.info(booleanQuery.toString());
|
|
|
+ SPage<Document> documents = getDocuments(SearchConstants.BRAND_TABLE_NAME, booleanQuery, new Sort(sortBrand(keyword)), 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()) {
|
|
|
+ brandIds.add(Long.parseLong(document.get(SearchConstants.BRAND_ID_FIELD)));
|
|
|
+ }
|
|
|
+ sPage.setContent(brandIds);
|
|
|
+ return sPage;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取品牌Document
|
|
|
+ * @param keyword 关键词
|
|
|
+ * @param page 页码
|
|
|
+ * @param size 页数
|
|
|
+ * @return
|
|
|
+ * @throws IOException
|
|
|
+ */
|
|
|
private SPage<Document> getBrandDocuments(String keyword, Integer page, Integer size) throws IOException {
|
|
|
if (SearchUtils.isKeywordInvalid(keyword)) {
|
|
|
throw new IllegalArgumentException("搜索关键词无效:" + keyword);
|
|
|
}
|
|
|
+
|
|
|
BooleanQuery booleanQuery = new BooleanQuery();
|
|
|
+
|
|
|
booleanQuery.add(SearchUtils.getBooleanQuery(SearchConstants.BRAND_NAMECN_FIELD, keyword),
|
|
|
- BooleanClause.Occur.SHOULD);
|
|
|
+ BooleanClause.Occur.SHOULD);
|
|
|
booleanQuery.add(SearchUtils.getBooleanQuery(SearchConstants.BRAND_NAMEEN_FIELD, keyword),
|
|
|
- BooleanClause.Occur.SHOULD);
|
|
|
+ BooleanClause.Occur.SHOULD);
|
|
|
+
|
|
|
logger.info(booleanQuery.toString());
|
|
|
- return SearchUtils.getDocuments(SearchConstants.BRAND_TABLE_NAME, booleanQuery, new Sort(sortBrand(keyword)), page,
|
|
|
+ return getDocuments(SearchConstants.BRAND_TABLE_NAME, booleanQuery, new Sort(sortBrand(keyword)), page,
|
|
|
size);
|
|
|
}
|
|
|
|
|
|
@@ -434,7 +549,7 @@ public class SearchServiceImpl implements SearchService {
|
|
|
} catch (IOException e) {
|
|
|
logger.error("", e);
|
|
|
} finally {
|
|
|
- SearchUtils.releaseIndexSearcher(indexSearcher);
|
|
|
+ releaseIndexSearcher(indexSearcher);
|
|
|
}
|
|
|
return map;
|
|
|
}
|
|
|
@@ -555,7 +670,7 @@ public class SearchServiceImpl implements SearchService {
|
|
|
} catch (IOException e) {
|
|
|
throw new IllegalStateException("统计失败", e);
|
|
|
} finally {
|
|
|
- SearchUtils.releaseIndexSearcher(indexSearcher);
|
|
|
+ releaseIndexSearcher(indexSearcher);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -630,7 +745,7 @@ public class SearchServiceImpl implements SearchService {
|
|
|
} catch (IOException e) {
|
|
|
logger.error("", e);
|
|
|
} finally {
|
|
|
- SearchUtils.releaseIndexSearcher(indexSearcher);
|
|
|
+ releaseIndexSearcher(indexSearcher);
|
|
|
}
|
|
|
return components;
|
|
|
}
|
|
|
@@ -654,7 +769,7 @@ public class SearchServiceImpl implements SearchService {
|
|
|
|
|
|
Sort sort = new Sort(new SortField(SearchConstants.BRAND_NAMEEN_UNTOKENIZED_FIELD, new StringFieldComparatorSource(brandName)),
|
|
|
new SortField(SearchConstants.BRAND_NAMECN_UNTOKENIZED_FIELD, new StringFieldComparatorSource(brandName)));
|
|
|
- List<Document> documents = SearchUtils.getDocuments(SearchConstants.BRAND_TABLE_NAME, booleanQuery, sort, null, size)
|
|
|
+ List<Document> documents = getDocuments(SearchConstants.BRAND_TABLE_NAME, booleanQuery, sort, null, size)
|
|
|
.getContent();
|
|
|
for (Document document : documents) {
|
|
|
Map<String, Object> brand = new HashMap<>();
|
|
|
@@ -719,7 +834,7 @@ public class SearchServiceImpl implements SearchService {
|
|
|
logger.info(booleanQuery.toString());
|
|
|
|
|
|
Sort sort = new Sort(new SortField(SearchConstants.KIND_NAMECN_UNTOKENIZED_FIELD, new StringFieldComparatorSource(kindName)));
|
|
|
- List<Document> documents = SearchUtils.getDocuments(SearchConstants.KIND_TABLE_NAME, booleanQuery, sort, null, size).getContent();
|
|
|
+ List<Document> documents = getDocuments(SearchConstants.KIND_TABLE_NAME, booleanQuery, sort, null, size).getContent();
|
|
|
for (Document document : documents) {
|
|
|
Map<String, Object> map = new HashMap<>();
|
|
|
map.put("id", Long.parseLong(document.get(SearchConstants.KIND_ID_FIELD)));
|
|
|
@@ -777,7 +892,7 @@ public class SearchServiceImpl implements SearchService {
|
|
|
} catch (IOException e) {
|
|
|
logger.error("", e);
|
|
|
} finally {
|
|
|
- SearchUtils.releaseIndexSearcher(indexSearcher);
|
|
|
+ releaseIndexSearcher(indexSearcher);
|
|
|
}
|
|
|
|
|
|
List<Map<String, String>> result = new ArrayList<>();
|
|
|
@@ -878,7 +993,7 @@ public class SearchServiceImpl implements SearchService {
|
|
|
} catch (IOException e) {
|
|
|
logger.error("", e);
|
|
|
} finally {
|
|
|
- SearchUtils.releaseIndexSearcher(indexSearcher);
|
|
|
+ releaseIndexSearcher(indexSearcher);
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
@@ -921,17 +1036,29 @@ public class SearchServiceImpl implements SearchService {
|
|
|
|
|
|
@Override
|
|
|
public Map<String, Object> getGoodsIds(String keyword, PageParams pageParams) throws IOException {
|
|
|
- List<String> keywordFields = new ArrayList<>();
|
|
|
+// 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) || goodsIds.get("componentIds") == null
|
|
|
- || JSONObject.parseArray(goodsIds.get("componentIds").toString()).isEmpty()) {
|
|
|
- keyword = recursivelyGetGoodsIds(keyword, null, true);
|
|
|
- goodsIds = getGoodsIds(keyword, null, true, pageParams);
|
|
|
- }
|
|
|
- return goodsIds;
|
|
|
+// 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) || goodsIds.get("componentIds") == null
|
|
|
+// || JSONObject.parseArray(goodsIds.get("componentIds").toString()).isEmpty()) {
|
|
|
+// keyword = recursivelyGetGoodsIds(keyword, null, true);
|
|
|
+// goodsIds = getGoodsIds(keyword, null, true, pageParams);
|
|
|
+// }
|
|
|
+// return goodsIds;
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ List<String> goodsFields = new ArrayList<>();
|
|
|
+ List<String> productsFields = new ArrayList<>();
|
|
|
+ // 先根据品牌搜索,品牌不存在再搜索型号等
|
|
|
+ goodsFields.add(SearchConstants.GOODS_PR_PCMPCODE_FIELD);
|
|
|
+ goodsFields.add(SearchConstants.GOODS_CMP_CODE_FIELD);
|
|
|
+
|
|
|
+ productsFields.add(SearchConstants.PRODUCT_PRIVATE_CMPCODE_FIELD);
|
|
|
+ productsFields.add(SearchConstants.PRODUCT_PRIVATE_PCMPCODE_FIELD);
|
|
|
+ map.put("stock", getGoodsIds(keyword, goodsFields, true, pageParams));
|
|
|
+ map.put("futures", getProductIds(keyword, pageParams));
|
|
|
+ return map;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -958,7 +1085,7 @@ public class SearchServiceImpl implements SearchService {
|
|
|
pageParams.setSize(20);
|
|
|
|
|
|
Map<String, Object> map = new HashMap<String, Object>();
|
|
|
- List<Long> cmpIds = new ArrayList<>();
|
|
|
+// List<Long> cmpIds = new ArrayList<>();
|
|
|
List<Long> goIds = new ArrayList<>();
|
|
|
try {
|
|
|
BooleanQuery booleanQuery = queryGoods(keyword, keywordFields, tokenized);
|
|
|
@@ -983,29 +1110,69 @@ public class SearchServiceImpl implements SearchService {
|
|
|
|
|
|
// 数据量太大,需要指定将获取的数据(以免载入不必要的数据,降低速度)
|
|
|
Set<String> fieldsToLoad = new HashSet<>();
|
|
|
- fieldsToLoad.add(SearchConstants.GOODS_CMP_ID_FIELD);
|
|
|
+// fieldsToLoad.add(SearchConstants.GOODS_CMP_ID_FIELD);
|
|
|
fieldsToLoad.add(SearchConstants.GOODS_GO_ID_FIELD);
|
|
|
ScoreDoc[] scoreDocs = hits.scoreDocs;
|
|
|
for (ScoreDoc scoreDoc : scoreDocs) {
|
|
|
Document document = indexSearcher.doc(scoreDoc.doc, fieldsToLoad);
|
|
|
- String cmpId = document.get(SearchConstants.GOODS_CMP_ID_FIELD);
|
|
|
- cmpIds.add(StringUtils.isEmpty(cmpId) || cmpId.equals(ObjectToDocumentUtils.NULL_VALUE) ? null : Long.valueOf(cmpId));
|
|
|
+// String cmpId = document.get(SearchConstants.GOODS_CMP_ID_FIELD);
|
|
|
+// cmpIds.add(StringUtils.isEmpty(cmpId) || cmpId.equals(ObjectToDocumentUtils.NULL_VALUE) ? null : Long.valueOf(cmpId));
|
|
|
String goId = document.get(SearchConstants.GOODS_GO_ID_FIELD);
|
|
|
goIds.add(StringUtils.isEmpty(goId) || goId.equals(ObjectToDocumentUtils.NULL_VALUE) ? null : Long.valueOf(goId));
|
|
|
}
|
|
|
- map.put("componentIds", cmpIds);
|
|
|
- map.put("goodsIds", goIds);
|
|
|
+// map.put("componentIds", cmpIds);
|
|
|
+ map.put("content", goIds);
|
|
|
map.put("page", pageParams.getPage());
|
|
|
map.put("size", pageParams.getSize());
|
|
|
- map.put("total", hits.totalHits);
|
|
|
+ map.put("totalElement", hits.totalHits);
|
|
|
+ int totalPage = (int) Math.ceil(hits.totalHits / (1.0 * pageParams.getSize()));
|
|
|
+ map.put("totalPage", totalPage);
|
|
|
+ map.put("last", totalPage == pageParams.getPage() ? true : false);
|
|
|
+ map.put("first", pageParams.getPage() == 1 ? true : false);
|
|
|
} catch (IOException e) {
|
|
|
logger.error("", e);
|
|
|
} finally {
|
|
|
- SearchUtils.releaseIndexSearcher(indexSearcher);
|
|
|
+ releaseIndexSearcher(indexSearcher);
|
|
|
}
|
|
|
return map;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 获取物料信息
|
|
|
+ * @param keyword
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private SPage<Long> getProductIds(String keyword, PageParams pageParams) throws IOException{
|
|
|
+ if (pageParams == null) {
|
|
|
+ pageParams = new PageParams();
|
|
|
+ }
|
|
|
+ if (pageParams.getPage() <= 0)
|
|
|
+ pageParams.setPage(1);
|
|
|
+ if (pageParams.getSize() <= 0)
|
|
|
+ pageParams.setSize(20);
|
|
|
+
|
|
|
+ BooleanQuery q1 = new BooleanQuery();
|
|
|
+ q1.add(new TermQuery(new Term(SearchConstants.PRODUCT_PRIVATE_B2CENABLED_FIELD, String.valueOf(1))), BooleanClause.Occur.MUST);
|
|
|
+ BooleanQuery booleanQuery = new BooleanQuery();
|
|
|
+ booleanQuery.add(q1, BooleanClause.Occur.MUST);
|
|
|
+ if (!StringUtils.isEmpty(keyword)) {
|
|
|
+ BooleanQuery q2 = new BooleanQuery();
|
|
|
+ q2.add(createQuery(SearchConstants.PRODUCT_PRIVATE_PCMPCODE_FIELD, keyword, true,1), BooleanClause.Occur.SHOULD);
|
|
|
+ q2.add(createQuery(SearchConstants.PRODUCT_PRIVATE_CMPCODE_FIELD, keyword, true,1), BooleanClause.Occur.SHOULD);
|
|
|
+ booleanQuery.add(q2, BooleanClause.Occur.MUST);
|
|
|
+ }
|
|
|
+ logger.info(booleanQuery.toString());
|
|
|
+ SPage<Document> documents = getDocuments(SearchConstants.PRODUCTS_PRIVATE_TABLE_NAME, booleanQuery, new Sort(sortProduct(keyword)), pageParams.getPage(), pageParams.getSize());
|
|
|
+
|
|
|
+ SPage<Long> sPage = new SPage<>(documents.getTotalPage(), documents.getTotalElement(), documents.getPage(), documents.getSize(), documents.isFirst(), documents.isLast());
|
|
|
+ List<Long> productIds = new ArrayList<>();
|
|
|
+ for (Document document : documents.getContent()) {
|
|
|
+ productIds.add(Long.parseLong(document.get(SearchConstants.PRODUCT_PRIVATE_ID_FIELD)));
|
|
|
+ }
|
|
|
+ sPage.setContent(productIds);
|
|
|
+ return sPage;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 递归查询批次(如果没有结果,则降低精度,直至长度为 1)
|
|
|
*
|
|
|
@@ -1027,7 +1194,7 @@ public class SearchServiceImpl implements SearchService {
|
|
|
}
|
|
|
return keyword;
|
|
|
} finally {
|
|
|
- SearchUtils.releaseIndexSearcher(indexSearcher);
|
|
|
+ releaseIndexSearcher(indexSearcher);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -1119,6 +1286,31 @@ public class SearchServiceImpl implements SearchService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 设置批次过滤条件
|
|
|
+ *
|
|
|
+ * @param filters 指定的过滤条件
|
|
|
+ * @param query 原查询
|
|
|
+ */
|
|
|
+ private void setProductsFilter(Map<FilterField, Object> filters, BooleanQuery query) {
|
|
|
+ Object status;
|
|
|
+ // 筛选状态
|
|
|
+ if (!CollectionUtils.isEmpty(filters) && !StringUtils.isEmpty(filters.get(FilterField.PRODUCT_STATUS))) {
|
|
|
+ // 如果明确指定了状态,则直接过滤物料
|
|
|
+ status = filters.get(FilterField.PRODUCT_STATUS);
|
|
|
+ filter(status, SearchConstants.PRODUCT_PRIVATE_B2CENABLED_FIELD, query);
|
|
|
+ } else {
|
|
|
+ // 如果未明确指定状态,则使用默认状态分情况进行过滤(结果中包括没有批次的器件)
|
|
|
+ status = Arrays.asList(V_Products.VALID_STATUS);
|
|
|
+ // 或者批次 id 为空(此时是器件)
|
|
|
+ BooleanQuery q2 = new BooleanQuery();
|
|
|
+
|
|
|
+ BooleanQuery booleanQuery = new BooleanQuery();
|
|
|
+ booleanQuery.add(q2, Occur.SHOULD);
|
|
|
+ query.add(booleanQuery, Occur.FILTER);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 批次排序规则
|
|
|
*/
|
|
|
@@ -1238,7 +1430,7 @@ public class SearchServiceImpl implements SearchService {
|
|
|
} catch (IOException e) {
|
|
|
logger.error("", e);
|
|
|
} finally {
|
|
|
- SearchUtils.releaseIndexSearcher(indexSearcher);
|
|
|
+ releaseIndexSearcher(indexSearcher);
|
|
|
}
|
|
|
return map;
|
|
|
}
|
|
|
@@ -1263,7 +1455,7 @@ public class SearchServiceImpl implements SearchService {
|
|
|
}
|
|
|
return keyword;
|
|
|
} finally {
|
|
|
- SearchUtils.releaseIndexSearcher(indexSearcher);
|
|
|
+ releaseIndexSearcher(indexSearcher);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -1418,6 +1610,143 @@ public class SearchServiceImpl implements SearchService {
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 获取卖家信息
|
|
|
+ * @param keyword 关键词
|
|
|
+ * @param keywordFields 搜索字段
|
|
|
+ * @param page 页码
|
|
|
+ * @param size 页数
|
|
|
+ * @param tokenized 是否分词
|
|
|
+ * @param duplicate 去重类型
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private Map<String, SPage<Object>> querySellers(String keyword, List<String> keywordFields, Integer page, Integer size, boolean tokenized, String duplicate) throws IOException {
|
|
|
+ if (SearchUtils.isKeywordInvalid(keyword)) {
|
|
|
+ throw new IllegalArgumentException("搜索关键词无效:" + keyword);
|
|
|
+ }
|
|
|
+ // 现货卖家
|
|
|
+ Map<String, SPage<Object>> map = new HashMap<>();
|
|
|
+ // 期货卖家
|
|
|
+ BooleanQuery booleanQuery = new BooleanQuery();
|
|
|
+
|
|
|
+ // 未指定搜索的字段,则采用默认搜索逻辑
|
|
|
+ if (CollectionUtils.isEmpty(keywordFields)) {
|
|
|
+ Map<String, Query> boostQuerys = setSellersBoost(keyword);
|
|
|
+ } else {
|
|
|
+ BooleanQuery booleanQuery2 = new BooleanQuery();
|
|
|
+ for (String keywordField : keywordFields) {
|
|
|
+ if (!tokenized) {
|
|
|
+ booleanQuery2.add(new TermQuery(new Term(keywordField, keyword.toLowerCase())), BooleanClause.Occur.SHOULD);
|
|
|
+ } else {
|
|
|
+ booleanQuery2.add(SearchUtils.getBooleanQuery(keywordField, keyword), BooleanClause.Occur.SHOULD);
|
|
|
+ }
|
|
|
+ booleanQuery.add(booleanQuery2, Occur.MUST);
|
|
|
+ }
|
|
|
+ logger.info(booleanQuery.toString());
|
|
|
+ }
|
|
|
+ // TODO 卖家排序
|
|
|
+ Sort sort = null;
|
|
|
+ // 现货卖家
|
|
|
+ map.put("stock", querySellers(SearchConstants.GOODS_TABLE_NAME, page, size, booleanQuery, sort, duplicate));
|
|
|
+ // 期货卖家
|
|
|
+ map.put("futures", querySellers(SearchConstants.PRODUCTS_PRIVATE_TABLE_NAME, page, size, booleanQuery, sort, duplicate));
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ private SPage<Object> querySellers(String indexName, Integer page, Integer size, Query query, Sort sort, String duplicateType) throws IOException {
|
|
|
+ SPage<Object> 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);
|
|
|
+ }
|
|
|
+
|
|
|
+ DuplicateFilter duplicateFilter = null;
|
|
|
+ if (!StringUtils.isEmpty(duplicateType)) {
|
|
|
+ if (duplicateType.equals(SearchConstants.BRAND)) {
|
|
|
+ duplicateFilter = new DuplicateFilter(indexName.equals(SearchConstants.GOODS_TABLE_NAME) ? SearchConstants.GOODS_PR_PBRAND_EN_CN_STUUID_UNTOKENIZED_FIELD : SearchConstants.PRODUCT_PRIVATE_PBRAND_ENUU_FIELD);
|
|
|
+ } else if (duplicateType.equals(SearchConstants.KIND)) {
|
|
|
+ duplicateFilter = new DuplicateFilter(indexName.equals(SearchConstants.GOODS_TABLE_NAME) ? SearchConstants.GOODS_KIND_STUUID_UNTOKENIZED_FIELD : SearchConstants.PRODUCT_PRIVATE_KIND_ENUU_FIELD);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ IndexSearcher indexSearcher = SearchUtils.getIndexSearcher(indexName);
|
|
|
+ TopDocs topDocs;
|
|
|
+ try {
|
|
|
+ // 如果页码不为1
|
|
|
+ if (sPage.getPage() > 1) {
|
|
|
+ TopDocs previousTopDocs;
|
|
|
+ if (sort == null) {
|
|
|
+ previousTopDocs = duplicateFilter == null ? indexSearcher.search(query, (sPage.getPage() - 1) * sPage.getSize()) : indexSearcher.search(query, duplicateFilter, (sPage.getPage() - 1) * sPage.getSize());
|
|
|
+ } else {
|
|
|
+ previousTopDocs = indexSearcher.search(query, duplicateFilter, (sPage.getPage() - 1) * sPage.getSize(), sort);
|
|
|
+ }
|
|
|
+ int totalHits = previousTopDocs.totalHits;
|
|
|
+ ScoreDoc[] previousScoreDocs = previousTopDocs.scoreDocs;
|
|
|
+ if ((sPage.getPage() - 1) * sPage.getSize() >= totalHits) {
|
|
|
+ throw new IllegalArgumentException("页码过大:元素总数量为" + totalHits);
|
|
|
+ }
|
|
|
+ topDocs = sort == null ? indexSearcher.searchAfter(previousScoreDocs[previousScoreDocs.length - 1], query, sPage.getSize()) :
|
|
|
+ indexSearcher.searchAfter(previousScoreDocs[previousScoreDocs.length - 1], query, sPage.getSize(), sort);
|
|
|
+ } else {
|
|
|
+ sPage.setFirst(true);
|
|
|
+ if (sort == null) {
|
|
|
+ topDocs = duplicateFilter == null ? indexSearcher.search(query, sPage.getSize()) : indexSearcher.search(query, duplicateFilter, sPage.getSize());
|
|
|
+ } else {
|
|
|
+ topDocs = duplicateFilter == null ? indexSearcher.search(query, sPage.getSize(), sort) : 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));
|
|
|
+ }
|
|
|
+
|
|
|
+ List<Object> content = new ArrayList<>();
|
|
|
+ if (indexName.equals(SearchConstants.GOODS_TABLE_NAME)) {
|
|
|
+ for (Document document : documents) {
|
|
|
+ content.add(document.get(SearchConstants.GOODS_ST_UUID_FIELD));
|
|
|
+ }
|
|
|
+ } else if (indexName.equals(SearchConstants.PRODUCTS_PRIVATE_TABLE_NAME)) {
|
|
|
+ for (Document document : documents) {
|
|
|
+ content.add(Long.parseLong(document.get(SearchConstants.PRODUCT_PRIVATE_ENUU_FIELD)));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ sPage.setContent(content);
|
|
|
+ } finally {
|
|
|
+ releaseIndexSearcher(indexSearcher);
|
|
|
+ }
|
|
|
+ return sPage;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<String, Query> setSellersBoost(String keyword) {
|
|
|
+ // TODO
|
|
|
+ Map<String, Query> queryMap = new HashMap<>();
|
|
|
+ BooleanQuery goodsQuery = new BooleanQuery();
|
|
|
+ BooleanQuery productsQuery = new BooleanQuery();
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private SortField[] sortSellers(String keyword) {
|
|
|
+ // TODO
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* @param keyword
|
|
|
* @param keywordFields
|
|
|
@@ -1474,7 +1803,7 @@ public class SearchServiceImpl implements SearchService {
|
|
|
} catch (IOException e) {
|
|
|
logger.error("", e);
|
|
|
} finally {
|
|
|
- SearchUtils.releaseIndexSearcher(indexSearcher);
|
|
|
+ releaseIndexSearcher(indexSearcher);
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
@@ -1509,6 +1838,28 @@ public class SearchServiceImpl implements SearchService {
|
|
|
return booleanQuery;
|
|
|
}
|
|
|
|
|
|
+ private BooleanQuery queryProducts(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.toLowerCase())), BooleanClause.Occur.SHOULD);
|
|
|
+ } else {
|
|
|
+ booleanQuery2.add(SearchUtils.getBooleanQuery(keywordField, keyword), BooleanClause.Occur.SHOULD);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ booleanQuery.add(booleanQuery2, BooleanClause.Occur.MUST);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return booleanQuery;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 同时搜索器件、类目、品牌等,并设置boost
|
|
|
*/
|
|
|
@@ -1575,7 +1926,7 @@ public class SearchServiceImpl implements SearchService {
|
|
|
} catch (IOException e) {
|
|
|
logger.error("", e);
|
|
|
} finally {
|
|
|
- SearchUtils.releaseIndexSearcher(indexSearcher);
|
|
|
+ releaseIndexSearcher(indexSearcher);
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
@@ -1701,7 +2052,7 @@ public class SearchServiceImpl implements SearchService {
|
|
|
} catch (IOException e) {
|
|
|
logger.error("", e);
|
|
|
} finally {
|
|
|
- SearchUtils.releaseIndexSearcher(indexSearcher);
|
|
|
+ releaseIndexSearcher(indexSearcher);
|
|
|
}
|
|
|
return products;
|
|
|
}
|
|
|
@@ -1741,7 +2092,7 @@ public class SearchServiceImpl implements SearchService {
|
|
|
} catch (IOException e) {
|
|
|
logger.error("", e);
|
|
|
} finally {
|
|
|
- SearchUtils.releaseIndexSearcher(indexSearcher);
|
|
|
+ releaseIndexSearcher(indexSearcher);
|
|
|
}
|
|
|
return products;
|
|
|
}
|
|
|
@@ -1840,7 +2191,7 @@ public class SearchServiceImpl implements SearchService {
|
|
|
}
|
|
|
sPage.setContent(content);
|
|
|
} finally {
|
|
|
- SearchUtils.releaseIndexSearcher(indexSearcher);
|
|
|
+ releaseIndexSearcher(indexSearcher);
|
|
|
}
|
|
|
return sPage;
|
|
|
}
|