Authored by unknown

Merge branch 'analysis' into wn_photoSearch

1 package com.yoho.search.consumer.index.common.impl; 1 package com.yoho.search.consumer.index.common.impl;
2 2
  3 +import java.io.InputStream;
  4 +import java.util.ArrayList;
  5 +import java.util.HashMap;
  6 +import java.util.List;
  7 +import java.util.Map;
  8 +import java.util.Set;
  9 +import java.util.concurrent.ConcurrentHashMap;
  10 +import java.util.regex.Pattern;
  11 +
  12 +import javax.annotation.PostConstruct;
  13 +
  14 +import org.elasticsearch.action.admin.indices.analyze.AnalyzeResponse;
  15 +import org.elasticsearch.action.admin.indices.analyze.AnalyzeResponse.AnalyzeToken;
  16 +import org.elasticsearch.action.bulk.BulkResponse;
  17 +import org.elasticsearch.action.get.GetResponse;
  18 +import org.elasticsearch.action.get.MultiGetResponse;
  19 +import org.elasticsearch.cluster.health.ClusterHealthStatus;
  20 +import org.slf4j.Logger;
  21 +import org.slf4j.LoggerFactory;
  22 +import org.springframework.beans.factory.annotation.Autowired;
  23 +import org.springframework.beans.factory.config.YamlMapFactoryBean;
  24 +import org.springframework.context.ApplicationEventPublisher;
  25 +import org.springframework.context.ApplicationEventPublisherAware;
  26 +import org.springframework.core.io.ClassPathResource;
  27 +import org.springframework.stereotype.Component;
  28 +
3 import com.yoho.search.base.utils.FileUtils; 29 import com.yoho.search.base.utils.FileUtils;
4 import com.yoho.search.base.utils.JaxbBinder; 30 import com.yoho.search.base.utils.JaxbBinder;
5 import com.yoho.search.consumer.index.common.IIndexBuilder; 31 import com.yoho.search.consumer.index.common.IIndexBuilder;
@@ -17,27 +43,6 @@ import com.yoho.search.core.es.impl.YohoIndexHelper; @@ -17,27 +43,6 @@ import com.yoho.search.core.es.impl.YohoIndexHelper;
17 import com.yoho.search.core.es.model.ESBluk; 43 import com.yoho.search.core.es.model.ESBluk;
18 import com.yoho.search.core.es.model.SearchParam; 44 import com.yoho.search.core.es.model.SearchParam;
19 import com.yoho.search.core.es.model.SearchResult; 45 import com.yoho.search.core.es.model.SearchResult;
20 -import org.elasticsearch.action.admin.indices.analyze.AnalyzeResponse;  
21 -import org.elasticsearch.action.admin.indices.analyze.AnalyzeResponse.AnalyzeToken;  
22 -import org.elasticsearch.action.bulk.BulkResponse;  
23 -import org.elasticsearch.action.get.GetResponse;  
24 -import org.elasticsearch.action.get.MultiGetResponse;  
25 -import org.elasticsearch.cluster.health.ClusterHealthStatus;  
26 -import org.slf4j.Logger;  
27 -import org.slf4j.LoggerFactory;  
28 -import org.springframework.beans.factory.annotation.Autowired;  
29 -import org.springframework.context.ApplicationEventPublisher;  
30 -import org.springframework.context.ApplicationEventPublisherAware;  
31 -import org.springframework.stereotype.Component;  
32 -  
33 -import javax.annotation.PostConstruct;  
34 -import java.io.InputStream;  
35 -import java.util.ArrayList;  
36 -import java.util.List;  
37 -import java.util.Map;  
38 -import java.util.Set;  
39 -import java.util.concurrent.ConcurrentHashMap;  
40 -import java.util.regex.Pattern;  
41 46
42 @Component 47 @Component
43 public class YohoIndexServiceImpl implements IYohoIndexService, ApplicationEventPublisherAware { 48 public class YohoIndexServiceImpl implements IYohoIndexService, ApplicationEventPublisherAware {
@@ -64,7 +69,12 @@ public class YohoIndexServiceImpl implements IYohoIndexService, ApplicationEvent @@ -64,7 +69,12 @@ public class YohoIndexServiceImpl implements IYohoIndexService, ApplicationEvent
64 69
65 // 索引配置文件 70 // 索引配置文件
66 private String configFile = "index.xml"; 71 private String configFile = "index.xml";
67 - 72 +
  73 + // 分词器配置文件
  74 + private static final String analysisPath = "analysis.yml";
  75 +
  76 + private Map<String,Object> analysisConfigMap = new HashMap<String, Object>();
  77 +
68 private Map<String, IYohoIndex> nameToIndexMap = new ConcurrentHashMap<String, IYohoIndex>(50); 78 private Map<String, IYohoIndex> nameToIndexMap = new ConcurrentHashMap<String, IYohoIndex>(50);
69 79
70 @PostConstruct 80 @PostConstruct
@@ -72,6 +82,7 @@ public class YohoIndexServiceImpl implements IYohoIndexService, ApplicationEvent @@ -72,6 +82,7 @@ public class YohoIndexServiceImpl implements IYohoIndexService, ApplicationEvent
72 long begin = System.currentTimeMillis(); 82 long begin = System.currentTimeMillis();
73 logger.info("[method=load] [step=start]"); 83 logger.info("[method=load] [step=start]");
74 this.configure(this.configFile); 84 this.configure(this.configFile);
  85 + this.initAnalyzerConfig(analysisPath);
75 logger.info("[method=load] [step=end] [cost={}ms]", System.currentTimeMillis() - begin); 86 logger.info("[method=load] [step=end] [cost={}ms]", System.currentTimeMillis() - begin);
76 } 87 }
77 88
@@ -81,7 +92,7 @@ public class YohoIndexServiceImpl implements IYohoIndexService, ApplicationEvent @@ -81,7 +92,7 @@ public class YohoIndexServiceImpl implements IYohoIndexService, ApplicationEvent
81 * @param configFile 92 * @param configFile
82 * 配置文件的路径 93 * 配置文件的路径
83 */ 94 */
84 - public void configure(String configFile) { 95 + private void configure(String configFile) {
85 try { 96 try {
86 InputStream is = this.getClass().getClassLoader().getResourceAsStream(configFile); 97 InputStream is = this.getClass().getClassLoader().getResourceAsStream(configFile);
87 JaxbBinder jaxbBinder = new JaxbBinder(IndexConfigs.class); 98 JaxbBinder jaxbBinder = new JaxbBinder(IndexConfigs.class);
@@ -105,7 +116,14 @@ public class YohoIndexServiceImpl implements IYohoIndexService, ApplicationEvent @@ -105,7 +116,14 @@ public class YohoIndexServiceImpl implements IYohoIndexService, ApplicationEvent
105 throw new RuntimeException("初始化索引服务失败,Exception: ", e); 116 throw new RuntimeException("初始化索引服务失败,Exception: ", e);
106 } 117 }
107 } 118 }
108 - 119 +
  120 + private void initAnalyzerConfig(String analysisPath) {
  121 + YamlMapFactoryBean factory = new YamlMapFactoryBean();
  122 + factory.setResources(new ClassPathResource[]{new ClassPathResource(analysisPath)});
  123 + this.analysisConfigMap = factory.getObject();
  124 + logger.info("[func=initAnalyzerConfig][analyzerConfigMap={}]", analysisConfigMap);
  125 + }
  126 +
109 @Override 127 @Override
110 public ClusterHealthStatus getClusterHealthStatus(String yohoIndexName) { 128 public ClusterHealthStatus getClusterHealthStatus(String yohoIndexName) {
111 IYohoIndex index = this.nameToIndexMap.get(yohoIndexName); 129 IYohoIndex index = this.nameToIndexMap.get(yohoIndexName);
@@ -145,7 +163,7 @@ public class YohoIndexServiceImpl implements IYohoIndexService, ApplicationEvent @@ -145,7 +163,7 @@ public class YohoIndexServiceImpl implements IYohoIndexService, ApplicationEvent
145 String yohoIndexAliasName = yohoIndexName; 163 String yohoIndexAliasName = yohoIndexName;
146 return this.createIndex(yohoIndexName, yohoIndexAliasName, force); 164 return this.createIndex(yohoIndexName, yohoIndexAliasName, force);
147 } 165 }
148 - 166 +
149 @Override 167 @Override
150 public String createIndex(final String yohoIndexName, String alias, final boolean force) throws Exception { 168 public String createIndex(final String yohoIndexName, String alias, final boolean force) throws Exception {
151 IYohoIndex index = this.nameToIndexMap.get(yohoIndexName); 169 IYohoIndex index = this.nameToIndexMap.get(yohoIndexName);
@@ -160,15 +178,22 @@ public class YohoIndexServiceImpl implements IYohoIndexService, ApplicationEvent @@ -160,15 +178,22 @@ public class YohoIndexServiceImpl implements IYohoIndexService, ApplicationEvent
160 } 178 }
161 // 2、生成真实索引名称 179 // 2、生成真实索引名称
162 String newRealIndexName = yohoIndexHelper.genRealIndexName(yohoIndexName); 180 String newRealIndexName = yohoIndexHelper.genRealIndexName(yohoIndexName);
163 - // 3、创建真实索引  
164 - final Map<String, String> settings = index.getProperties(); 181 +
  182 + // 3、获取索引配置信息
165 final String mappingContent = index.getMappingContent(); 183 final String mappingContent = index.getMappingContent();
166 - client.createIndex(newRealIndexName, yohoIndexName, settings, mappingContent);  
167 - // 4、删除旧索引别名 184 + Map<String, String> properties = index.getProperties();
  185 +
  186 + // 4、创建真实索引[获取分析器信息]
  187 + Map<String,Object> indexSettings = new HashMap<String,Object>();
  188 + indexSettings.putAll(properties);
  189 + indexSettings.put("max_result_window", "100000000");
  190 + indexSettings.putAll(this.analysisConfigMap);
  191 + client.createIndex(newRealIndexName, yohoIndexName, indexSettings, mappingContent);
  192 + // 5、删除旧索引别名
168 if (oldRealIndexNames != null && !oldRealIndexNames.isEmpty()) { 193 if (oldRealIndexNames != null && !oldRealIndexNames.isEmpty()) {
169 client.removeAlias(oldRealIndexNames, alias); 194 client.removeAlias(oldRealIndexNames, alias);
170 } 195 }
171 - // 5、添加新索引别名【如果存在一个名字为alias的真实索引,则直接删除】 196 + // 6、添加新索引别名【如果存在一个名字为alias的真实索引,则直接删除】
172 if (client.indexExists(alias)) { 197 if (client.indexExists(alias)) {
173 client.deleteIndex(alias); 198 client.deleteIndex(alias);
174 } 199 }
@@ -2,6 +2,7 @@ package com.yoho.search.consumer.index.increment.productIndex; @@ -2,6 +2,7 @@ package com.yoho.search.consumer.index.increment.productIndex;
2 2
3 import java.util.ArrayList; 3 import java.util.ArrayList;
4 import java.util.List; 4 import java.util.List;
  5 +import java.util.Map;
5 6
6 import org.apache.commons.collections.CollectionUtils; 7 import org.apache.commons.collections.CollectionUtils;
7 import org.slf4j.Logger; 8 import org.slf4j.Logger;
@@ -82,7 +83,7 @@ public class ProductMqListener extends AbstractIndexMqListener { @@ -82,7 +83,7 @@ public class ProductMqListener extends AbstractIndexMqListener {
82 83
83 private void updateProductDataToEs(final Integer productId, Integer productSkn, boolean isUpdate) { 84 private void updateProductDataToEs(final Integer productId, Integer productSkn, boolean isUpdate) {
84 CostStatistics costStatistics = new CostStatistics(); 85 CostStatistics costStatistics = new CostStatistics();
85 - // 3、获取数据 86 + // 1、获取数据
86 List<Integer> ids = new ArrayList<>(); 87 List<Integer> ids = new ArrayList<>();
87 ids.add(productId); 88 ids.add(productId);
88 List<ProductIBO> productIBOs = productIndexIndexBuilder.getProductIBOs(ids); 89 List<ProductIBO> productIBOs = productIndexIndexBuilder.getProductIBOs(ids);
@@ -90,24 +91,24 @@ public class ProductMqListener extends AbstractIndexMqListener { @@ -90,24 +91,24 @@ public class ProductMqListener extends AbstractIndexMqListener {
90 return; 91 return;
91 } 92 }
92 ProductIBO productIBO = productIBOs.get(0); 93 ProductIBO productIBO = productIBOs.get(0);
93 - // 处理isNew(规则:首次上架7天内展示且折扣率小于88折)  
94 - productIBO.setIsnew("N"); 94 + logger.info("[step1=getProductIBO][productId={}][cost={}ms]", productId, costStatistics.getCost());
  95 +
  96 + // 2、构建ProductPrice
95 ProductPrice productPrice = productPriceService.getBySkn(productSkn); 97 ProductPrice productPrice = productPriceService.getBySkn(productSkn);
96 - if (productPrice != null && productPriceBuilder.isNew(productIBO.getFirstShelveTime(), productPrice.getRetailPrice(), productPrice.getSalesPrice())) {  
97 - productIBO.setIsnew("Y");  
98 - }  
99 - logger.info("[step3=getProductI][productId={}][cost={}ms]", productId, costStatistics.getCost()); 98 + Map<String, Object> productPriceModelMap = productPriceBuilder.getProductPriceModelMap(productId, productIBO.getFirstShelveTime(), productPrice);
  99 + logger.info("[step2=getProductPrice][productId={}][cost={}ms]", productId, costStatistics.getCost());
100 100
101 - // 4、更新到ES 101 + // 3、更新到ES
102 try { 102 try {
103 JSONObject jsonObject = (JSONObject) JSON.toJSON(productIBO); 103 JSONObject jsonObject = (JSONObject) JSON.toJSON(productIBO);
104 if (!isUpdate) { 104 if (!isUpdate) {
105 jsonObject.put("salesNum", 0); 105 jsonObject.put("salesNum", 0);
106 } 106 }
  107 + jsonObject.putAll(productPriceModelMap);
107 this.updateProductIndexWithDataMap(jsonObject, productId); 108 this.updateProductIndexWithDataMap(jsonObject, productId);
108 - logger.info("[step4=updateToEs][productId={}][cost={}ms]", productId, costStatistics.getCost()); 109 + logger.info("[step3=updateToEs][productId={}][cost={}ms]", productId, costStatistics.getCost());
109 } catch (Exception e) { 110 } catch (Exception e) {
110 - logger.error("[step4=updateToEs][productId={}][cost={}ms][execption={}]", productId, costStatistics.getCost(), e.getMessage()); 111 + logger.error("[step3=updateToEs][productId={}][cost={}ms][execption={}]", productId, costStatistics.getCost(), e.getMessage());
111 productIndexMqListener.sendProductIndexMessage(productId); 112 productIndexMqListener.sendProductIndexMessage(productId);
112 } 113 }
113 } 114 }
1 package com.yoho.search.consumer.index.increment.productIndex; 1 package com.yoho.search.consumer.index.increment.productIndex;
2 2
3 -import java.math.BigDecimal;  
4 import java.util.HashMap; 3 import java.util.HashMap;
5 import java.util.Map; 4 import java.util.Map;
6 5
@@ -17,7 +16,6 @@ import com.yoho.search.base.utils.ProductIndexEsField; @@ -17,7 +16,6 @@ import com.yoho.search.base.utils.ProductIndexEsField;
17 import com.yoho.search.consumer.index.increment.AbstractIndexMqListener; 16 import com.yoho.search.consumer.index.increment.AbstractIndexMqListener;
18 import com.yoho.search.consumer.service.base.ProductPriceService; 17 import com.yoho.search.consumer.service.base.ProductPriceService;
19 import com.yoho.search.consumer.service.base.ProductService; 18 import com.yoho.search.consumer.service.base.ProductService;
20 -import com.yoho.search.consumer.service.bo.ProductPriceBO;  
21 import com.yoho.search.consumer.service.logic.SpecialDealLogicService; 19 import com.yoho.search.consumer.service.logic.SpecialDealLogicService;
22 import com.yoho.search.consumer.service.logic.productIndex.viewBuilder.ProductPriceBuilder; 20 import com.yoho.search.consumer.service.logic.productIndex.viewBuilder.ProductPriceBuilder;
23 import com.yoho.search.dal.model.Product; 21 import com.yoho.search.dal.model.Product;
@@ -75,51 +73,20 @@ public class ProductPriceMqListener extends AbstractIndexMqListener { @@ -75,51 +73,20 @@ public class ProductPriceMqListener extends AbstractIndexMqListener {
75 73
76 // 2、更新ProductIndex 74 // 2、更新ProductIndex
77 begin = System.currentTimeMillis(); 75 begin = System.currentTimeMillis();
78 - Integer productId = productService.selectProductIdBySkn(productPrice.getProductSkn());  
79 - this.updateProductIndex(productId, productPrice); 76 + this.updateProductIndex(productPrice.getProductSkn(), productPrice);
80 logger.info("[func=updateData][step=updateProductIndex][productSkn={}][cost={}ms]", productPrice.getProductSkn(), this.getCost(begin)); 77 logger.info("[func=updateData][step=updateProductIndex][productSkn={}][cost={}ms]", productPrice.getProductSkn(), this.getCost(begin));
81 } 78 }
82 79
83 - private double getDoubleFromBigDecimal(BigDecimal bigDecimal) {  
84 - if (bigDecimal == null) {  
85 - return 0d;  
86 - }  
87 - return bigDecimal.doubleValue();  
88 - }  
89 -  
90 - private void updateProductIndex(Integer productId, ProductPrice pp) {  
91 - Map<String, Object> indexData = new HashMap<String, Object>();  
92 -  
93 - // 构造ProductPriceBO  
94 - ProductPriceBO productPriceBO = new ProductPriceBO(pp);  
95 - productPriceBuilder.buildProductPriceBO(productPriceBO);  
96 - indexData.put("productId", productId);  
97 - indexData.put("marketPrice", this.getDoubleFromBigDecimal(productPriceBO.getMarketPrice()));  
98 - indexData.put("salesPrice", this.getDoubleFromBigDecimal(productPriceBO.getSalesPrice()));  
99 - indexData.put("vipPrice", this.getDoubleFromBigDecimal(productPriceBO.getVipPrice()));  
100 - indexData.put("vipDiscountType", productPriceBO.getVipDiscountType());  
101 - indexData.put("vip1Price", this.getDoubleFromBigDecimal(productPriceBO.getVip1Price()));  
102 - indexData.put("vip2Price", this.getDoubleFromBigDecimal(productPriceBO.getVip2Price()));  
103 - indexData.put("vip3Price", this.getDoubleFromBigDecimal(productPriceBO.getVip3Price()));  
104 - indexData.put("studentPrice", this.getDoubleFromBigDecimal(productPriceBO.getStudentPrice()));  
105 -  
106 - indexData.put("isDiscount", productPriceBO.getIsDiscount());  
107 - indexData.put("specialoffer", productPriceBO.getSpecialoffer());  
108 - indexData.put("promotionDiscountInt", productPriceBO.getPromotionDiscountInt());  
109 - indexData.put("promotionDiscount", this.getDoubleFromBigDecimal(productPriceBO.getPromotionDiscount()));  
110 - indexData.put("isStudentPrice", productPriceBO.getIsStudentPrice());  
111 - indexData.put("isstudentrebate", productPriceBO.getIsstudentrebate());  
112 - indexData.put("vipLevels", productPriceBO.getVipLevels());  
113 - indexData.put("priceUpdateTime", productPriceBO.getUpdateTime());  
114 - Product product = productService.getById(productId);  
115 - if (product != null) {  
116 - indexData.put("isnew", productPriceBuilder.isNew(product.getFirstShelveTime(), productPriceBO.getMarketPrice(), productPriceBO.getSalesPrice()));  
117 - } else {  
118 - indexData.put("isnew", "N"); 80 + private void updateProductIndex(Integer productSkn, ProductPrice pp) {
  81 + Product product = productService.getBySkn(productSkn);
  82 + if (product == null) {
  83 + logger.warn("[func=updateData][step=updateProductIndex fail ][product is null ][productSkn is {}]", productSkn);
  84 + return;
119 } 85 }
120 - indexData.put(ProductIndexEsField.specialSearchFieldPrice, specialSearchFieldLogicService.getSpecialSearchFieldPrice(productPriceBO)); 86 + // 构造增量的建到Pi索引里的数据
  87 + Map<String, Object> indexData = productPriceBuilder.getProductPriceModelMap(product.getId(), product.getFirstShelveTime(), pp);
121 // 更新商品索引 88 // 更新商品索引
122 - this.updateProductIndexWithDataMap(indexData, productId); 89 + this.updateProductIndexWithDataMap(indexData, product.getId());
123 } 90 }
124 91
125 /** 92 /**
@@ -128,14 +95,14 @@ public class ProductPriceMqListener extends AbstractIndexMqListener { @@ -128,14 +95,14 @@ public class ProductPriceMqListener extends AbstractIndexMqListener {
128 private void updateProductIndexByClearPrice(Integer productId) { 95 private void updateProductIndexByClearPrice(Integer productId) {
129 Map<String, Object> indexData = new HashMap<String, Object>(30); 96 Map<String, Object> indexData = new HashMap<String, Object>(30);
130 indexData.put("productId", productId); 97 indexData.put("productId", productId);
131 - indexData.put("marketPrice", null);  
132 - indexData.put("salesPrice", null);  
133 - indexData.put("vipPrice", null);  
134 - indexData.put("vipDiscountType", null);  
135 - indexData.put("vip1Price", null);  
136 - indexData.put("vip2Price", null);  
137 - indexData.put("vip3Price", null);  
138 - indexData.put("studentPrice", null); 98 + indexData.put("marketPrice", 0);
  99 + indexData.put("salesPrice", 0);
  100 + indexData.put("vipPrice", 0);
  101 + indexData.put("vipDiscountType", 0);
  102 + indexData.put("vip1Price", 0);
  103 + indexData.put("vip2Price", 0);
  104 + indexData.put("vip3Price", 0);
  105 + indexData.put("studentPrice", 0);
139 // others 106 // others
140 indexData.put("isDiscount", "N"); 107 indexData.put("isDiscount", "N");
141 indexData.put("specialoffer", "N"); 108 indexData.put("specialoffer", "N");
1 package com.yoho.search.consumer.service.logic.productIndex.viewBuilder; 1 package com.yoho.search.consumer.service.logic.productIndex.viewBuilder;
2 2
  3 +import java.math.BigDecimal;
  4 +import java.math.RoundingMode;
  5 +import java.text.DecimalFormat;
  6 +import java.util.Date;
  7 +import java.util.HashMap;
  8 +import java.util.List;
  9 +import java.util.Map;
  10 +import java.util.stream.Collectors;
  11 +
  12 +import org.slf4j.Logger;
  13 +import org.slf4j.LoggerFactory;
  14 +import org.springframework.beans.factory.annotation.Autowired;
  15 +import org.springframework.stereotype.Component;
  16 +
3 import com.yoho.search.base.utils.DateUtil; 17 import com.yoho.search.base.utils.DateUtil;
4 import com.yoho.search.base.utils.MathUtils; 18 import com.yoho.search.base.utils.MathUtils;
  19 +import com.yoho.search.base.utils.ProductIndexEsField;
5 import com.yoho.search.consumer.service.bo.ProductIndexBO; 20 import com.yoho.search.consumer.service.bo.ProductIndexBO;
6 import com.yoho.search.consumer.service.bo.ProductPriceBO; 21 import com.yoho.search.consumer.service.bo.ProductPriceBO;
7 import com.yoho.search.consumer.service.logic.SpecialDealLogicService; 22 import com.yoho.search.consumer.service.logic.SpecialDealLogicService;
8 import com.yoho.search.consumer.service.logic.VipPriceLogicService; 23 import com.yoho.search.consumer.service.logic.VipPriceLogicService;
9 import com.yoho.search.dal.ProductPriceMapper; 24 import com.yoho.search.dal.ProductPriceMapper;
10 import com.yoho.search.dal.model.ProductPrice; 25 import com.yoho.search.dal.model.ProductPrice;
11 -import org.slf4j.Logger;  
12 -import org.slf4j.LoggerFactory;  
13 -import org.springframework.beans.factory.annotation.Autowired;  
14 -import org.springframework.stereotype.Component;  
15 -  
16 -import java.math.BigDecimal;  
17 -import java.math.RoundingMode;  
18 -import java.text.DecimalFormat;  
19 -import java.util.Date;  
20 -import java.util.List;  
21 -import java.util.Map;  
22 -import java.util.stream.Collectors;  
23 26
24 /** 27 /**
25 * Created by wangnan on 2017/1/6. 28 * Created by wangnan on 2017/1/6.
@@ -27,150 +30,184 @@ import java.util.stream.Collectors; @@ -27,150 +30,184 @@ import java.util.stream.Collectors;
27 @Component 30 @Component
28 public class ProductPriceBuilder implements ViewBuilder { 31 public class ProductPriceBuilder implements ViewBuilder {
29 32
30 - private final Logger logger = LoggerFactory.getLogger(ProductPriceBuilder.class); 33 + private final Logger logger = LoggerFactory.getLogger(ProductPriceBuilder.class);
31 34
32 - @Autowired  
33 - private ProductPriceMapper productPriceMapper;  
34 - @Autowired  
35 - private VipPriceLogicService vipPriceLogicService;  
36 - @Autowired  
37 - private SpecialDealLogicService specialSearchFieldLogicService; 35 + @Autowired
  36 + private ProductPriceMapper productPriceMapper;
  37 + @Autowired
  38 + private VipPriceLogicService vipPriceLogicService;
  39 + @Autowired
  40 + private SpecialDealLogicService specialSearchFieldLogicService;
38 41
39 - @Override  
40 - public void build(List<ProductIndexBO> productIndexBOs, List<Integer> ids, List<Integer> sknList) {  
41 - List<ProductPrice> productPrices = productPriceMapper.selectBySknList(sknList);  
42 - Map<Integer, ProductPrice> productPricesMap = productPrices.stream().collect(Collectors.toMap(ProductPrice::getProductSkn, (p) -> p));  
43 - for (ProductIndexBO productIndexBO : productIndexBOs) {  
44 - try {  
45 - // 如果该skn对应价格对象不存在,直接跳过  
46 - ProductPrice productPrice = productPricesMap.get(productIndexBO.getProductSkn());  
47 - if (productPrice == null) {  
48 - continue;  
49 - }  
50 - // 构造ProductPriceBO  
51 - ProductPriceBO productPriceBO = new ProductPriceBO(productPrice);  
52 - this.buildProductPriceBO(productPriceBO);  
53 - // 构造ProductIndexBO  
54 - this.buildProductIndexBO(productIndexBO, productPriceBO);  
55 - } catch (Exception e) {  
56 - logger.error(e.getMessage(), e);  
57 - }  
58 - }  
59 - } 42 + @Override
  43 + public void build(List<ProductIndexBO> productIndexBOs, List<Integer> ids, List<Integer> sknList) {
  44 + List<ProductPrice> productPrices = productPriceMapper.selectBySknList(sknList);
  45 + Map<Integer, ProductPrice> productPricesMap = productPrices.stream().collect(Collectors.toMap(ProductPrice::getProductSkn, (p) -> p));
  46 + for (ProductIndexBO productIndexBO : productIndexBOs) {
  47 + try {
  48 + // 如果该skn对应价格对象不存在,直接跳过
  49 + ProductPrice productPrice = productPricesMap.get(productIndexBO.getProductSkn());
  50 + if (productPrice == null) {
  51 + continue;
  52 + }
  53 + // 构造ProductPriceBO
  54 + ProductPriceBO productPriceBO = new ProductPriceBO(productPrice);
  55 + this.buildProductPriceBO(productPriceBO);
  56 + // 构造ProductIndexBO
  57 + this.buildProductIndexBO(productIndexBO, productPriceBO);
  58 + } catch (Exception e) {
  59 + logger.error(e.getMessage(), e);
  60 + }
  61 + }
  62 + }
60 63
61 - /**  
62 - * 增量+全量都调用  
63 - */  
64 - public void buildProductPriceBO(ProductPriceBO productPriceBO) {  
65 - // 1、计算并重设vip相关价格  
66 - vipPriceLogicService.fillProductPriceVipPrice(productPriceBO);  
67 - // 2、计算折扣相关  
68 - double salesPrice = this.getDoubleFromBigDecimal(productPriceBO.getSalesPrice());  
69 - double marketPrice = this.getDoubleFromBigDecimal(productPriceBO.getMarketPrice()); 64 + /**
  65 + * 增量+全量都调用
  66 + */
  67 + public void buildProductPriceBO(ProductPriceBO productPriceBO) {
  68 + // 1、计算并重设vip相关价格
  69 + vipPriceLogicService.fillProductPriceVipPrice(productPriceBO);
  70 + // 2、计算折扣相关
  71 + double salesPrice = this.getDoubleFromBigDecimal(productPriceBO.getSalesPrice());
  72 + double marketPrice = this.getDoubleFromBigDecimal(productPriceBO.getMarketPrice());
70 productPriceBO.setIsDiscount(salesPrice < marketPrice ? "Y" : "N"); 73 productPriceBO.setIsDiscount(salesPrice < marketPrice ? "Y" : "N");
71 - double specialOffer = this.divide(1, productPriceBO.getSalesPrice(), productPriceBO.getMarketPrice());  
72 - if (specialOffer <= 0.5) {  
73 - productPriceBO.setSpecialoffer("Y");  
74 - } else {  
75 - productPriceBO.setSpecialoffer("N");  
76 - }  
77 - double promotionDiscountInt = this.divide(1, productPriceBO.getSalesPrice().multiply(new BigDecimal(10)), productPriceBO.getMarketPrice());  
78 - productPriceBO.setPromotionDiscountInt((long) promotionDiscountInt);  
79 - double promotionDiscount = this.divide(3, productPriceBO.getSalesPrice(), productPriceBO.getMarketPrice());  
80 - productPriceBO.setPromotionDiscount(this.getBigDecimalFromDouble(promotionDiscount));  
81 - // 3、设置学生价相关属性  
82 - productPriceBO.setIsStudentPrice(productPriceBO.getStudentPrice() != null ? "Y" : "N");  
83 - productPriceBO.setIsstudentrebate(productPriceBO.getStudentCoinRate() == null || productPriceBO.getStudentCoinRate().compareTo(BigDecimal.ZERO) == 0 ? "N" : "Y");  
84 - } 74 + double specialOffer = this.divide(1, productPriceBO.getSalesPrice(), productPriceBO.getMarketPrice());
  75 + if (specialOffer <= 0.5) {
  76 + productPriceBO.setSpecialoffer("Y");
  77 + } else {
  78 + productPriceBO.setSpecialoffer("N");
  79 + }
  80 + double promotionDiscountInt = this.divide(1, productPriceBO.getSalesPrice().multiply(new BigDecimal(10)), productPriceBO.getMarketPrice());
  81 + productPriceBO.setPromotionDiscountInt((long) promotionDiscountInt);
  82 + double promotionDiscount = this.divide(3, productPriceBO.getSalesPrice(), productPriceBO.getMarketPrice());
  83 + productPriceBO.setPromotionDiscount(this.getBigDecimalFromDouble(promotionDiscount));
  84 + // 3、设置学生价相关属性
  85 + BigDecimal studentPrice = productPriceBO.getStudentPrice();
  86 + productPriceBO.setIsStudentPrice(studentPrice== null || studentPrice.compareTo(BigDecimal.ZERO)==0 ? "N" : "Y");
  87 + productPriceBO.setIsstudentrebate(productPriceBO.getStudentCoinRate() == null || productPriceBO.getStudentCoinRate().compareTo(BigDecimal.ZERO) == 0 ? "N" : "Y");
  88 + }
  89 +
  90 + private void buildProductIndexBO(ProductIndexBO productIndexBO, ProductPriceBO productPriceBO) {
  91 + productIndexBO.setIsDiscount("N");
  92 + productIndexBO.setSpecialoffer("N");
  93 + productIndexBO.setPromotionDiscount(new BigDecimal(1));
  94 + productIndexBO.setPromotionDiscountInt(10L);
  95 + productIndexBO.setIsStudentPrice("N");
  96 + productIndexBO.setIsStudentRebate("N");
  97 + productIndexBO.setIsnew("N");
  98 + productIndexBO.setMarketPrice(productPriceBO.getMarketPrice());
  99 + productIndexBO.setVipDiscountType(productPriceBO.getVipDiscountType());
  100 + productIndexBO.setSalesPrice(productPriceBO.getSalesPrice());
  101 + productIndexBO.setVipPrice(productPriceBO.getVipPrice());
  102 + productIndexBO.setVip1Price(productPriceBO.getVip1Price());
  103 + productIndexBO.setVip2Price(productPriceBO.getVip2Price());
  104 + productIndexBO.setVip3Price(productPriceBO.getVip3Price());
  105 + productIndexBO.setStudentPrice(productPriceBO.getStudentPrice());
  106 + // 折扣相关
  107 + productIndexBO.setIsDiscount(productPriceBO.getIsDiscount());
  108 + productIndexBO.setSpecialoffer(productPriceBO.getSpecialoffer());
  109 + productIndexBO.setPromotionDiscountInt(productPriceBO.getPromotionDiscountInt());
  110 + productIndexBO.setPromotionDiscount(productPriceBO.getPromotionDiscount());
  111 + // 学生价相关字段
  112 + productIndexBO.setIsStudentPrice(productPriceBO.getIsStudentPrice());
  113 + productIndexBO.setIsStudentRebate(productPriceBO.getIsstudentrebate());
  114 + // 设置vipLevels
  115 + productIndexBO.setVipLevels(productPriceBO.getVipLevels());
  116 + // 设置价格更新时间
  117 + productIndexBO.setPriceUpdateTime(productPriceBO.getUpdateTime());
  118 + // 设置最后一次降价时间
  119 + productIndexBO.setLastReducePriceTime(productPriceBO.getLastReducePriceTime());
  120 + // 计算isNew(规则:首次上架7天内展示且折扣率大于等于88折)
  121 + productIndexBO.setIsnew("N");
  122 + if (this.isNew(productIndexBO.getFirstShelveTime(), productIndexBO.getMarketPrice(), productIndexBO.getSalesPrice())) {
  123 + productIndexBO.setIsnew("Y");
  124 + }
  125 + // 计算specialSearchFieldPrice
  126 + productIndexBO.setSpecialSearchFieldPrice(specialSearchFieldLogicService.getSpecialSearchFieldPrice(productPriceBO));
  127 + }
85 128
86 - private void buildProductIndexBO(ProductIndexBO productIndexBO, ProductPriceBO productPriceBO) {  
87 - productIndexBO.setIsDiscount("N");  
88 - productIndexBO.setSpecialoffer("N");  
89 - productIndexBO.setPromotionDiscount(new BigDecimal(1));  
90 - productIndexBO.setPromotionDiscountInt(10L);  
91 - productIndexBO.setIsStudentPrice("N");  
92 - productIndexBO.setIsStudentRebate("N");  
93 - productIndexBO.setIsnew("N");  
94 - productIndexBO.setMarketPrice(productPriceBO.getMarketPrice());  
95 - productIndexBO.setVipDiscountType(productPriceBO.getVipDiscountType());  
96 - productIndexBO.setSalesPrice(productPriceBO.getSalesPrice());  
97 - productIndexBO.setVipPrice(productPriceBO.getVipPrice());  
98 - productIndexBO.setVip1Price(productPriceBO.getVip1Price());  
99 - productIndexBO.setVip2Price(productPriceBO.getVip2Price());  
100 - productIndexBO.setVip3Price(productPriceBO.getVip3Price());  
101 - productIndexBO.setStudentPrice(productPriceBO.getStudentPrice());  
102 - // 折扣相关  
103 - productIndexBO.setIsDiscount(productPriceBO.getIsDiscount());  
104 - productIndexBO.setSpecialoffer(productPriceBO.getSpecialoffer());  
105 - productIndexBO.setPromotionDiscountInt(productPriceBO.getPromotionDiscountInt());  
106 - productIndexBO.setPromotionDiscount(productPriceBO.getPromotionDiscount());  
107 - // 学生价相关字段  
108 - productIndexBO.setIsStudentPrice(productPriceBO.getIsStudentPrice());  
109 - productIndexBO.setIsStudentRebate(productPriceBO.getIsstudentrebate());  
110 - // 设置vipLevels  
111 - productIndexBO.setVipLevels(productPriceBO.getVipLevels());  
112 - // 设置价格更新时间  
113 - productIndexBO.setPriceUpdateTime(productPriceBO.getUpdateTime());  
114 - // 设置最后一次降价时间  
115 - productIndexBO.setLastReducePriceTime(productPriceBO.getLastReducePriceTime());  
116 - // 计算isNew(规则:首次上架7天内展示且折扣率大于等于88折)  
117 - productIndexBO.setIsnew("N");  
118 - if (this.isNew(productIndexBO.getFirstShelveTime(), productIndexBO.getMarketPrice(), productIndexBO.getSalesPrice())) {  
119 - productIndexBO.setIsnew("Y");  
120 - }  
121 - // 计算specialSearchFieldPrice  
122 - productIndexBO.setSpecialSearchFieldPrice(specialSearchFieldLogicService.getSpecialSearchFieldPrice(productPriceBO));  
123 - } 129 + public Map<String, Object> getProductPriceModelMap(Integer productId, Integer firstShelveTime, ProductPrice pp) {
  130 + Map<String, Object> indexData = new HashMap<String, Object>();
  131 + indexData.put("isnew", "N");
  132 + if (pp == null) {
  133 + return indexData;
  134 + }
  135 + // 构造ProductPriceBO
  136 + ProductPriceBO productPriceBO = new ProductPriceBO(pp);
  137 + this.buildProductPriceBO(productPriceBO);
  138 + indexData.put("productId", productId);
  139 + indexData.put("marketPrice", this.getDoubleFromBigDecimal(productPriceBO.getMarketPrice()));
  140 + indexData.put("salesPrice", this.getDoubleFromBigDecimal(productPriceBO.getSalesPrice()));
  141 + indexData.put("vipPrice", this.getDoubleFromBigDecimal(productPriceBO.getVipPrice()));
  142 + indexData.put("vipDiscountType", productPriceBO.getVipDiscountType());
  143 + indexData.put("vip1Price", this.getDoubleFromBigDecimal(productPriceBO.getVip1Price()));
  144 + indexData.put("vip2Price", this.getDoubleFromBigDecimal(productPriceBO.getVip2Price()));
  145 + indexData.put("vip3Price", this.getDoubleFromBigDecimal(productPriceBO.getVip3Price()));
  146 + indexData.put("studentPrice", this.getDoubleFromBigDecimal(productPriceBO.getStudentPrice()));
124 147
  148 + indexData.put("isDiscount", productPriceBO.getIsDiscount());
  149 + indexData.put("specialoffer", productPriceBO.getSpecialoffer());
  150 + indexData.put("promotionDiscountInt", productPriceBO.getPromotionDiscountInt());
  151 + indexData.put("promotionDiscount", this.getDoubleFromBigDecimal(productPriceBO.getPromotionDiscount()));
  152 + indexData.put("isStudentPrice", productPriceBO.getIsStudentPrice());
  153 + indexData.put("isstudentrebate", productPriceBO.getIsstudentrebate());
  154 + indexData.put("vipLevels", productPriceBO.getVipLevels());
  155 + indexData.put("priceUpdateTime", productPriceBO.getUpdateTime());
  156 + if (firstShelveTime != null) {
  157 + indexData.put("isnew", this.isNew(firstShelveTime, productPriceBO.getMarketPrice(), productPriceBO.getSalesPrice()));
  158 + }
  159 + indexData.put(ProductIndexEsField.specialSearchFieldPrice, specialSearchFieldLogicService.getSpecialSearchFieldPrice(productPriceBO));
  160 + return indexData;
  161 + }
125 162
126 - /**  
127 - * isNew 标签逻辑  
128 - */  
129 - public boolean isNew(Integer firstShelveTime, BigDecimal marketPrice, BigDecimal salesPrice) {  
130 - try {  
131 - if (firstShelveTime == null || firstShelveTime <= 0 || salesPrice == null || marketPrice == null) {  
132 - return false;  
133 - }  
134 - long dateCount = DateUtil.daysBetween(new Date(firstShelveTime * 1000L), new Date());  
135 - if (dateCount > 7) {  
136 - return false;  
137 - }  
138 - // 计算折扣  
139 - Double discount = MathUtils.getDevideValue(salesPrice, marketPrice, 2, RoundingMode.DOWN);  
140 - if (discount >= 0.88) {  
141 - return true;  
142 - }  
143 - return false;  
144 - } catch (Exception e) {  
145 - return false;  
146 - }  
147 - } 163 + /**
  164 + * isNew 标签逻辑
  165 + */
  166 + public boolean isNew(Integer firstShelveTime, BigDecimal marketPrice, BigDecimal salesPrice) {
  167 + try {
  168 + if (firstShelveTime == null || firstShelveTime <= 0 || salesPrice == null || marketPrice == null) {
  169 + return false;
  170 + }
  171 + long dateCount = DateUtil.daysBetween(new Date(firstShelveTime * 1000L), new Date());
  172 + if (dateCount > 7) {
  173 + return false;
  174 + }
  175 + // 计算折扣
  176 + Double discount = MathUtils.getDevideValue(salesPrice, marketPrice, 2, RoundingMode.DOWN);
  177 + if (discount >= 0.88) {
  178 + return true;
  179 + }
  180 + return false;
  181 + } catch (Exception e) {
  182 + return false;
  183 + }
  184 + }
148 185
149 - private double divide(int scale, BigDecimal a, BigDecimal b) {  
150 - if (b == null || b.compareTo(BigDecimal.ZERO) == 0) {  
151 - return 0;  
152 - }  
153 - StringBuilder sb = new StringBuilder("0.0");  
154 - for (int i = 1; i < scale; i++) {  
155 - sb.append('0');  
156 - }  
157 - BigDecimal divideResult = a.divide(b, scale, RoundingMode.DOWN);  
158 - DecimalFormat decimalFormat = new DecimalFormat(sb.toString());  
159 - String result = decimalFormat.format(divideResult);  
160 - return Double.parseDouble(result);  
161 - } 186 + private double divide(int scale, BigDecimal a, BigDecimal b) {
  187 + if (b == null || b.compareTo(BigDecimal.ZERO) == 0) {
  188 + return 0;
  189 + }
  190 + StringBuilder sb = new StringBuilder("0.0");
  191 + for (int i = 1; i < scale; i++) {
  192 + sb.append('0');
  193 + }
  194 + BigDecimal divideResult = a.divide(b, scale, RoundingMode.DOWN);
  195 + DecimalFormat decimalFormat = new DecimalFormat(sb.toString());
  196 + String result = decimalFormat.format(divideResult);
  197 + return Double.parseDouble(result);
  198 + }
162 199
163 - private double getDoubleFromBigDecimal(BigDecimal bigDecimal) {  
164 - if (bigDecimal == null) {  
165 - return 0d;  
166 - }  
167 - return bigDecimal.doubleValue();  
168 - } 200 + private double getDoubleFromBigDecimal(BigDecimal bigDecimal) {
  201 + if (bigDecimal == null) {
  202 + return 0d;
  203 + }
  204 + return bigDecimal.doubleValue();
  205 + }
169 206
170 - private BigDecimal getBigDecimalFromDouble(Double d) {  
171 - if (d == null) {  
172 - return new BigDecimal(0);  
173 - }  
174 - return new BigDecimal(d);  
175 - } 207 + private BigDecimal getBigDecimalFromDouble(Double d) {
  208 + if (d == null) {
  209 + return new BigDecimal(0);
  210 + }
  211 + return new BigDecimal(d);
  212 + }
176 } 213 }
  1 +index:
  2 + analysis:
  3 + tokenizer:
  4 + my_pinyin:
  5 + type: pinyin
  6 + first_letter: prefix
  7 + padding_char: ''
  8 + pinyin_first_letter:
  9 + type: pinyin
  10 + first_letter: only
  11 + simple_pinyin:
  12 + type: pinyin
  13 + first_letter: none
  14 + padding_char: ''
  15 + ngram_1_to_2:
  16 + type: nGram
  17 + min_gram: 1
  18 + max_gram: 2
  19 + ngram_1_to_3:
  20 + type: nGram
  21 + min_gram: 1
  22 + max_gram: 3
  23 + filter:
  24 + ngram_min_3:
  25 + max_gram: 10
  26 + min_gram: 3
  27 + type: nGram
  28 + ngram_min_2:
  29 + max_gram: 10
  30 + min_gram: 2
  31 + type: nGram
  32 + ngram_min_1:
  33 + max_gram: 10
  34 + min_gram: 1
  35 + type: nGram
  36 + min2_length:
  37 + min: 2
  38 + max: 4
  39 + type: length
  40 + min3_length:
  41 + min: 3
  42 + max: 4
  43 + type: length
  44 + pinyin_first_letter:
  45 + type: pinyin
  46 + first_letter: only
  47 + my_stop:
  48 + type: stop
  49 + stopwords_path: custom/stopwords.txt
  50 + my_synonym:
  51 + type: synonym
  52 + synonyms_path: custom/synonyms.dic
  53 + analyzer:
  54 + lowercase_standard:
  55 + type: custom
  56 + filter:
  57 + - lowercase
  58 + tokenizer: standard
  59 + lowercase_keyword:
  60 + type: custom
  61 + filter:
  62 + - lowercase
  63 + tokenizer: keyword
  64 + lowercase_whitespace:
  65 + type: custom
  66 + filter:
  67 + - lowercase
  68 + tokenizer: whitespace
  69 + lowercase_keyword_ngram:
  70 + type: custom
  71 + filter:
  72 + - lowercase
  73 + - stop
  74 + - trim
  75 + - unique
  76 + tokenizer: ngram_1_to_3
  77 + ik_max_word:
  78 + type: ik
  79 + use_smart: false
  80 + ik_max_word_syno:
  81 + type: custom
  82 + tokenizer: ik
  83 + filter: [my_synonym]
  84 + use_smart: false
  85 + ik_smart:
  86 + type: ik
  87 + use_smart: true
  88 + ik_complex:
  89 + type: custom
  90 + tokenizer: ik_smart
  91 + filter:
  92 + - lowercase
  93 + - ik_dyn_synonym
  94 + - lowercase
  95 + - my_stop
  96 + - unique
  97 + ik_complex_search:
  98 + type: custom
  99 + tokenizer: ik_smart
  100 + filter:
  101 + - lowercase
  102 + - my_stop
  103 + - unique
  104 + comma_spliter:
  105 + type: pattern
  106 + pattern: "[,|\\s]+"
  107 + pinyin_analyzer:
  108 + type: custom
  109 + tokenizer: simple_pinyin
  110 + filter:
  111 + - standard
  112 + - word_delimiter
  113 + - lowercase
  114 + - trim
  115 + - unique
  116 +
  117 +
  118 +index.analysis.analyzer.default.type: keyword
  119 +
  120 +index.search.slowlog.level: TRACE
  121 +index.search.slowlog.threshold.query.warn: 1s
  122 +index.search.slowlog.threshold.query.info: 800ms
  123 +index.search.slowlog.threshold.query.debug: 500ms
  124 +index.search.slowlog.threshold.query.trace: 200ms
  125 +index.search.slowlog.threshold.fetch.warn: 1s
  126 +index.search.slowlog.threshold.fetch.info: 800ms
  127 +index.search.slowlog.threshold.fetch.debug: 500ms
  128 +index.search.slowlog.threshold.fetch.trace: 200ms