Authored by unknown

Merge branch 'analysis' into wn_photoSearch

package com.yoho.search.consumer.index.common.impl;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
import javax.annotation.PostConstruct;
import org.elasticsearch.action.admin.indices.analyze.AnalyzeResponse;
import org.elasticsearch.action.admin.indices.analyze.AnalyzeResponse.AnalyzeToken;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.get.MultiGetResponse;
import org.elasticsearch.cluster.health.ClusterHealthStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.YamlMapFactoryBean;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;
import com.yoho.search.base.utils.FileUtils;
import com.yoho.search.base.utils.JaxbBinder;
import com.yoho.search.consumer.index.common.IIndexBuilder;
... ... @@ -17,27 +43,6 @@ import com.yoho.search.core.es.impl.YohoIndexHelper;
import com.yoho.search.core.es.model.ESBluk;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.model.SearchResult;
import org.elasticsearch.action.admin.indices.analyze.AnalyzeResponse;
import org.elasticsearch.action.admin.indices.analyze.AnalyzeResponse.AnalyzeToken;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.get.MultiGetResponse;
import org.elasticsearch.cluster.health.ClusterHealthStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
@Component
public class YohoIndexServiceImpl implements IYohoIndexService, ApplicationEventPublisherAware {
... ... @@ -64,7 +69,12 @@ public class YohoIndexServiceImpl implements IYohoIndexService, ApplicationEvent
// 索引配置文件
private String configFile = "index.xml";
// 分词器配置文件
private static final String analysisPath = "analysis.yml";
private Map<String,Object> analysisConfigMap = new HashMap<String, Object>();
private Map<String, IYohoIndex> nameToIndexMap = new ConcurrentHashMap<String, IYohoIndex>(50);
@PostConstruct
... ... @@ -72,6 +82,7 @@ public class YohoIndexServiceImpl implements IYohoIndexService, ApplicationEvent
long begin = System.currentTimeMillis();
logger.info("[method=load] [step=start]");
this.configure(this.configFile);
this.initAnalyzerConfig(analysisPath);
logger.info("[method=load] [step=end] [cost={}ms]", System.currentTimeMillis() - begin);
}
... ... @@ -81,7 +92,7 @@ public class YohoIndexServiceImpl implements IYohoIndexService, ApplicationEvent
* @param configFile
* 配置文件的路径
*/
public void configure(String configFile) {
private void configure(String configFile) {
try {
InputStream is = this.getClass().getClassLoader().getResourceAsStream(configFile);
JaxbBinder jaxbBinder = new JaxbBinder(IndexConfigs.class);
... ... @@ -105,7 +116,14 @@ public class YohoIndexServiceImpl implements IYohoIndexService, ApplicationEvent
throw new RuntimeException("初始化索引服务失败,Exception: ", e);
}
}
private void initAnalyzerConfig(String analysisPath) {
YamlMapFactoryBean factory = new YamlMapFactoryBean();
factory.setResources(new ClassPathResource[]{new ClassPathResource(analysisPath)});
this.analysisConfigMap = factory.getObject();
logger.info("[func=initAnalyzerConfig][analyzerConfigMap={}]", analysisConfigMap);
}
@Override
public ClusterHealthStatus getClusterHealthStatus(String yohoIndexName) {
IYohoIndex index = this.nameToIndexMap.get(yohoIndexName);
... ... @@ -145,7 +163,7 @@ public class YohoIndexServiceImpl implements IYohoIndexService, ApplicationEvent
String yohoIndexAliasName = yohoIndexName;
return this.createIndex(yohoIndexName, yohoIndexAliasName, force);
}
@Override
public String createIndex(final String yohoIndexName, String alias, final boolean force) throws Exception {
IYohoIndex index = this.nameToIndexMap.get(yohoIndexName);
... ... @@ -160,15 +178,22 @@ public class YohoIndexServiceImpl implements IYohoIndexService, ApplicationEvent
}
// 2、生成真实索引名称
String newRealIndexName = yohoIndexHelper.genRealIndexName(yohoIndexName);
// 3、创建真实索引
final Map<String, String> settings = index.getProperties();
// 3、获取索引配置信息
final String mappingContent = index.getMappingContent();
client.createIndex(newRealIndexName, yohoIndexName, settings, mappingContent);
// 4、删除旧索引别名
Map<String, String> properties = index.getProperties();
// 4、创建真实索引[获取分析器信息]
Map<String,Object> indexSettings = new HashMap<String,Object>();
indexSettings.putAll(properties);
indexSettings.put("max_result_window", "100000000");
indexSettings.putAll(this.analysisConfigMap);
client.createIndex(newRealIndexName, yohoIndexName, indexSettings, mappingContent);
// 5、删除旧索引别名
if (oldRealIndexNames != null && !oldRealIndexNames.isEmpty()) {
client.removeAlias(oldRealIndexNames, alias);
}
// 5、添加新索引别名【如果存在一个名字为alias的真实索引,则直接删除】
// 6、添加新索引别名【如果存在一个名字为alias的真实索引,则直接删除】
if (client.indexExists(alias)) {
client.deleteIndex(alias);
}
... ...
... ... @@ -2,6 +2,7 @@ package com.yoho.search.consumer.index.increment.productIndex;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
... ... @@ -82,7 +83,7 @@ public class ProductMqListener extends AbstractIndexMqListener {
private void updateProductDataToEs(final Integer productId, Integer productSkn, boolean isUpdate) {
CostStatistics costStatistics = new CostStatistics();
// 3、获取数据
// 1、获取数据
List<Integer> ids = new ArrayList<>();
ids.add(productId);
List<ProductIBO> productIBOs = productIndexIndexBuilder.getProductIBOs(ids);
... ... @@ -90,24 +91,24 @@ public class ProductMqListener extends AbstractIndexMqListener {
return;
}
ProductIBO productIBO = productIBOs.get(0);
// 处理isNew(规则:首次上架7天内展示且折扣率小于88折)
productIBO.setIsnew("N");
logger.info("[step1=getProductIBO][productId={}][cost={}ms]", productId, costStatistics.getCost());
// 2、构建ProductPrice
ProductPrice productPrice = productPriceService.getBySkn(productSkn);
if (productPrice != null && productPriceBuilder.isNew(productIBO.getFirstShelveTime(), productPrice.getRetailPrice(), productPrice.getSalesPrice())) {
productIBO.setIsnew("Y");
}
logger.info("[step3=getProductI][productId={}][cost={}ms]", productId, costStatistics.getCost());
Map<String, Object> productPriceModelMap = productPriceBuilder.getProductPriceModelMap(productId, productIBO.getFirstShelveTime(), productPrice);
logger.info("[step2=getProductPrice][productId={}][cost={}ms]", productId, costStatistics.getCost());
// 4、更新到ES
// 3、更新到ES
try {
JSONObject jsonObject = (JSONObject) JSON.toJSON(productIBO);
if (!isUpdate) {
jsonObject.put("salesNum", 0);
}
jsonObject.putAll(productPriceModelMap);
this.updateProductIndexWithDataMap(jsonObject, productId);
logger.info("[step4=updateToEs][productId={}][cost={}ms]", productId, costStatistics.getCost());
logger.info("[step3=updateToEs][productId={}][cost={}ms]", productId, costStatistics.getCost());
} catch (Exception e) {
logger.error("[step4=updateToEs][productId={}][cost={}ms][execption={}]", productId, costStatistics.getCost(), e.getMessage());
logger.error("[step3=updateToEs][productId={}][cost={}ms][execption={}]", productId, costStatistics.getCost(), e.getMessage());
productIndexMqListener.sendProductIndexMessage(productId);
}
}
... ...
package com.yoho.search.consumer.index.increment.productIndex;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
... ... @@ -17,7 +16,6 @@ import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.consumer.index.increment.AbstractIndexMqListener;
import com.yoho.search.consumer.service.base.ProductPriceService;
import com.yoho.search.consumer.service.base.ProductService;
import com.yoho.search.consumer.service.bo.ProductPriceBO;
import com.yoho.search.consumer.service.logic.SpecialDealLogicService;
import com.yoho.search.consumer.service.logic.productIndex.viewBuilder.ProductPriceBuilder;
import com.yoho.search.dal.model.Product;
... ... @@ -75,51 +73,20 @@ public class ProductPriceMqListener extends AbstractIndexMqListener {
// 2、更新ProductIndex
begin = System.currentTimeMillis();
Integer productId = productService.selectProductIdBySkn(productPrice.getProductSkn());
this.updateProductIndex(productId, productPrice);
this.updateProductIndex(productPrice.getProductSkn(), productPrice);
logger.info("[func=updateData][step=updateProductIndex][productSkn={}][cost={}ms]", productPrice.getProductSkn(), this.getCost(begin));
}
private double getDoubleFromBigDecimal(BigDecimal bigDecimal) {
if (bigDecimal == null) {
return 0d;
}
return bigDecimal.doubleValue();
}
private void updateProductIndex(Integer productId, ProductPrice pp) {
Map<String, Object> indexData = new HashMap<String, Object>();
// 构造ProductPriceBO
ProductPriceBO productPriceBO = new ProductPriceBO(pp);
productPriceBuilder.buildProductPriceBO(productPriceBO);
indexData.put("productId", productId);
indexData.put("marketPrice", this.getDoubleFromBigDecimal(productPriceBO.getMarketPrice()));
indexData.put("salesPrice", this.getDoubleFromBigDecimal(productPriceBO.getSalesPrice()));
indexData.put("vipPrice", this.getDoubleFromBigDecimal(productPriceBO.getVipPrice()));
indexData.put("vipDiscountType", productPriceBO.getVipDiscountType());
indexData.put("vip1Price", this.getDoubleFromBigDecimal(productPriceBO.getVip1Price()));
indexData.put("vip2Price", this.getDoubleFromBigDecimal(productPriceBO.getVip2Price()));
indexData.put("vip3Price", this.getDoubleFromBigDecimal(productPriceBO.getVip3Price()));
indexData.put("studentPrice", this.getDoubleFromBigDecimal(productPriceBO.getStudentPrice()));
indexData.put("isDiscount", productPriceBO.getIsDiscount());
indexData.put("specialoffer", productPriceBO.getSpecialoffer());
indexData.put("promotionDiscountInt", productPriceBO.getPromotionDiscountInt());
indexData.put("promotionDiscount", this.getDoubleFromBigDecimal(productPriceBO.getPromotionDiscount()));
indexData.put("isStudentPrice", productPriceBO.getIsStudentPrice());
indexData.put("isstudentrebate", productPriceBO.getIsstudentrebate());
indexData.put("vipLevels", productPriceBO.getVipLevels());
indexData.put("priceUpdateTime", productPriceBO.getUpdateTime());
Product product = productService.getById(productId);
if (product != null) {
indexData.put("isnew", productPriceBuilder.isNew(product.getFirstShelveTime(), productPriceBO.getMarketPrice(), productPriceBO.getSalesPrice()));
} else {
indexData.put("isnew", "N");
private void updateProductIndex(Integer productSkn, ProductPrice pp) {
Product product = productService.getBySkn(productSkn);
if (product == null) {
logger.warn("[func=updateData][step=updateProductIndex fail ][product is null ][productSkn is {}]", productSkn);
return;
}
indexData.put(ProductIndexEsField.specialSearchFieldPrice, specialSearchFieldLogicService.getSpecialSearchFieldPrice(productPriceBO));
// 构造增量的建到Pi索引里的数据
Map<String, Object> indexData = productPriceBuilder.getProductPriceModelMap(product.getId(), product.getFirstShelveTime(), pp);
// 更新商品索引
this.updateProductIndexWithDataMap(indexData, productId);
this.updateProductIndexWithDataMap(indexData, product.getId());
}
/**
... ... @@ -128,14 +95,14 @@ public class ProductPriceMqListener extends AbstractIndexMqListener {
private void updateProductIndexByClearPrice(Integer productId) {
Map<String, Object> indexData = new HashMap<String, Object>(30);
indexData.put("productId", productId);
indexData.put("marketPrice", null);
indexData.put("salesPrice", null);
indexData.put("vipPrice", null);
indexData.put("vipDiscountType", null);
indexData.put("vip1Price", null);
indexData.put("vip2Price", null);
indexData.put("vip3Price", null);
indexData.put("studentPrice", null);
indexData.put("marketPrice", 0);
indexData.put("salesPrice", 0);
indexData.put("vipPrice", 0);
indexData.put("vipDiscountType", 0);
indexData.put("vip1Price", 0);
indexData.put("vip2Price", 0);
indexData.put("vip3Price", 0);
indexData.put("studentPrice", 0);
// others
indexData.put("isDiscount", "N");
indexData.put("specialoffer", "N");
... ...
package com.yoho.search.consumer.service.logic.productIndex.viewBuilder;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.yoho.search.base.utils.DateUtil;
import com.yoho.search.base.utils.MathUtils;
import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.consumer.service.bo.ProductIndexBO;
import com.yoho.search.consumer.service.bo.ProductPriceBO;
import com.yoho.search.consumer.service.logic.SpecialDealLogicService;
import com.yoho.search.consumer.service.logic.VipPriceLogicService;
import com.yoho.search.dal.ProductPriceMapper;
import com.yoho.search.dal.model.ProductPrice;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Created by wangnan on 2017/1/6.
... ... @@ -27,150 +30,184 @@ import java.util.stream.Collectors;
@Component
public class ProductPriceBuilder implements ViewBuilder {
private final Logger logger = LoggerFactory.getLogger(ProductPriceBuilder.class);
private final Logger logger = LoggerFactory.getLogger(ProductPriceBuilder.class);
@Autowired
private ProductPriceMapper productPriceMapper;
@Autowired
private VipPriceLogicService vipPriceLogicService;
@Autowired
private SpecialDealLogicService specialSearchFieldLogicService;
@Autowired
private ProductPriceMapper productPriceMapper;
@Autowired
private VipPriceLogicService vipPriceLogicService;
@Autowired
private SpecialDealLogicService specialSearchFieldLogicService;
@Override
public void build(List<ProductIndexBO> productIndexBOs, List<Integer> ids, List<Integer> sknList) {
List<ProductPrice> productPrices = productPriceMapper.selectBySknList(sknList);
Map<Integer, ProductPrice> productPricesMap = productPrices.stream().collect(Collectors.toMap(ProductPrice::getProductSkn, (p) -> p));
for (ProductIndexBO productIndexBO : productIndexBOs) {
try {
// 如果该skn对应价格对象不存在,直接跳过
ProductPrice productPrice = productPricesMap.get(productIndexBO.getProductSkn());
if (productPrice == null) {
continue;
}
// 构造ProductPriceBO
ProductPriceBO productPriceBO = new ProductPriceBO(productPrice);
this.buildProductPriceBO(productPriceBO);
// 构造ProductIndexBO
this.buildProductIndexBO(productIndexBO, productPriceBO);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
}
@Override
public void build(List<ProductIndexBO> productIndexBOs, List<Integer> ids, List<Integer> sknList) {
List<ProductPrice> productPrices = productPriceMapper.selectBySknList(sknList);
Map<Integer, ProductPrice> productPricesMap = productPrices.stream().collect(Collectors.toMap(ProductPrice::getProductSkn, (p) -> p));
for (ProductIndexBO productIndexBO : productIndexBOs) {
try {
// 如果该skn对应价格对象不存在,直接跳过
ProductPrice productPrice = productPricesMap.get(productIndexBO.getProductSkn());
if (productPrice == null) {
continue;
}
// 构造ProductPriceBO
ProductPriceBO productPriceBO = new ProductPriceBO(productPrice);
this.buildProductPriceBO(productPriceBO);
// 构造ProductIndexBO
this.buildProductIndexBO(productIndexBO, productPriceBO);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
}
/**
* 增量+全量都调用
*/
public void buildProductPriceBO(ProductPriceBO productPriceBO) {
// 1、计算并重设vip相关价格
vipPriceLogicService.fillProductPriceVipPrice(productPriceBO);
// 2、计算折扣相关
double salesPrice = this.getDoubleFromBigDecimal(productPriceBO.getSalesPrice());
double marketPrice = this.getDoubleFromBigDecimal(productPriceBO.getMarketPrice());
/**
* 增量+全量都调用
*/
public void buildProductPriceBO(ProductPriceBO productPriceBO) {
// 1、计算并重设vip相关价格
vipPriceLogicService.fillProductPriceVipPrice(productPriceBO);
// 2、计算折扣相关
double salesPrice = this.getDoubleFromBigDecimal(productPriceBO.getSalesPrice());
double marketPrice = this.getDoubleFromBigDecimal(productPriceBO.getMarketPrice());
productPriceBO.setIsDiscount(salesPrice < marketPrice ? "Y" : "N");
double specialOffer = this.divide(1, productPriceBO.getSalesPrice(), productPriceBO.getMarketPrice());
if (specialOffer <= 0.5) {
productPriceBO.setSpecialoffer("Y");
} else {
productPriceBO.setSpecialoffer("N");
}
double promotionDiscountInt = this.divide(1, productPriceBO.getSalesPrice().multiply(new BigDecimal(10)), productPriceBO.getMarketPrice());
productPriceBO.setPromotionDiscountInt((long) promotionDiscountInt);
double promotionDiscount = this.divide(3, productPriceBO.getSalesPrice(), productPriceBO.getMarketPrice());
productPriceBO.setPromotionDiscount(this.getBigDecimalFromDouble(promotionDiscount));
// 3、设置学生价相关属性
productPriceBO.setIsStudentPrice(productPriceBO.getStudentPrice() != null ? "Y" : "N");
productPriceBO.setIsstudentrebate(productPriceBO.getStudentCoinRate() == null || productPriceBO.getStudentCoinRate().compareTo(BigDecimal.ZERO) == 0 ? "N" : "Y");
}
double specialOffer = this.divide(1, productPriceBO.getSalesPrice(), productPriceBO.getMarketPrice());
if (specialOffer <= 0.5) {
productPriceBO.setSpecialoffer("Y");
} else {
productPriceBO.setSpecialoffer("N");
}
double promotionDiscountInt = this.divide(1, productPriceBO.getSalesPrice().multiply(new BigDecimal(10)), productPriceBO.getMarketPrice());
productPriceBO.setPromotionDiscountInt((long) promotionDiscountInt);
double promotionDiscount = this.divide(3, productPriceBO.getSalesPrice(), productPriceBO.getMarketPrice());
productPriceBO.setPromotionDiscount(this.getBigDecimalFromDouble(promotionDiscount));
// 3、设置学生价相关属性
BigDecimal studentPrice = productPriceBO.getStudentPrice();
productPriceBO.setIsStudentPrice(studentPrice== null || studentPrice.compareTo(BigDecimal.ZERO)==0 ? "N" : "Y");
productPriceBO.setIsstudentrebate(productPriceBO.getStudentCoinRate() == null || productPriceBO.getStudentCoinRate().compareTo(BigDecimal.ZERO) == 0 ? "N" : "Y");
}
private void buildProductIndexBO(ProductIndexBO productIndexBO, ProductPriceBO productPriceBO) {
productIndexBO.setIsDiscount("N");
productIndexBO.setSpecialoffer("N");
productIndexBO.setPromotionDiscount(new BigDecimal(1));
productIndexBO.setPromotionDiscountInt(10L);
productIndexBO.setIsStudentPrice("N");
productIndexBO.setIsStudentRebate("N");
productIndexBO.setIsnew("N");
productIndexBO.setMarketPrice(productPriceBO.getMarketPrice());
productIndexBO.setVipDiscountType(productPriceBO.getVipDiscountType());
productIndexBO.setSalesPrice(productPriceBO.getSalesPrice());
productIndexBO.setVipPrice(productPriceBO.getVipPrice());
productIndexBO.setVip1Price(productPriceBO.getVip1Price());
productIndexBO.setVip2Price(productPriceBO.getVip2Price());
productIndexBO.setVip3Price(productPriceBO.getVip3Price());
productIndexBO.setStudentPrice(productPriceBO.getStudentPrice());
// 折扣相关
productIndexBO.setIsDiscount(productPriceBO.getIsDiscount());
productIndexBO.setSpecialoffer(productPriceBO.getSpecialoffer());
productIndexBO.setPromotionDiscountInt(productPriceBO.getPromotionDiscountInt());
productIndexBO.setPromotionDiscount(productPriceBO.getPromotionDiscount());
// 学生价相关字段
productIndexBO.setIsStudentPrice(productPriceBO.getIsStudentPrice());
productIndexBO.setIsStudentRebate(productPriceBO.getIsstudentrebate());
// 设置vipLevels
productIndexBO.setVipLevels(productPriceBO.getVipLevels());
// 设置价格更新时间
productIndexBO.setPriceUpdateTime(productPriceBO.getUpdateTime());
// 设置最后一次降价时间
productIndexBO.setLastReducePriceTime(productPriceBO.getLastReducePriceTime());
// 计算isNew(规则:首次上架7天内展示且折扣率大于等于88折)
productIndexBO.setIsnew("N");
if (this.isNew(productIndexBO.getFirstShelveTime(), productIndexBO.getMarketPrice(), productIndexBO.getSalesPrice())) {
productIndexBO.setIsnew("Y");
}
// 计算specialSearchFieldPrice
productIndexBO.setSpecialSearchFieldPrice(specialSearchFieldLogicService.getSpecialSearchFieldPrice(productPriceBO));
}
private void buildProductIndexBO(ProductIndexBO productIndexBO, ProductPriceBO productPriceBO) {
productIndexBO.setIsDiscount("N");
productIndexBO.setSpecialoffer("N");
productIndexBO.setPromotionDiscount(new BigDecimal(1));
productIndexBO.setPromotionDiscountInt(10L);
productIndexBO.setIsStudentPrice("N");
productIndexBO.setIsStudentRebate("N");
productIndexBO.setIsnew("N");
productIndexBO.setMarketPrice(productPriceBO.getMarketPrice());
productIndexBO.setVipDiscountType(productPriceBO.getVipDiscountType());
productIndexBO.setSalesPrice(productPriceBO.getSalesPrice());
productIndexBO.setVipPrice(productPriceBO.getVipPrice());
productIndexBO.setVip1Price(productPriceBO.getVip1Price());
productIndexBO.setVip2Price(productPriceBO.getVip2Price());
productIndexBO.setVip3Price(productPriceBO.getVip3Price());
productIndexBO.setStudentPrice(productPriceBO.getStudentPrice());
// 折扣相关
productIndexBO.setIsDiscount(productPriceBO.getIsDiscount());
productIndexBO.setSpecialoffer(productPriceBO.getSpecialoffer());
productIndexBO.setPromotionDiscountInt(productPriceBO.getPromotionDiscountInt());
productIndexBO.setPromotionDiscount(productPriceBO.getPromotionDiscount());
// 学生价相关字段
productIndexBO.setIsStudentPrice(productPriceBO.getIsStudentPrice());
productIndexBO.setIsStudentRebate(productPriceBO.getIsstudentrebate());
// 设置vipLevels
productIndexBO.setVipLevels(productPriceBO.getVipLevels());
// 设置价格更新时间
productIndexBO.setPriceUpdateTime(productPriceBO.getUpdateTime());
// 设置最后一次降价时间
productIndexBO.setLastReducePriceTime(productPriceBO.getLastReducePriceTime());
// 计算isNew(规则:首次上架7天内展示且折扣率大于等于88折)
productIndexBO.setIsnew("N");
if (this.isNew(productIndexBO.getFirstShelveTime(), productIndexBO.getMarketPrice(), productIndexBO.getSalesPrice())) {
productIndexBO.setIsnew("Y");
}
// 计算specialSearchFieldPrice
productIndexBO.setSpecialSearchFieldPrice(specialSearchFieldLogicService.getSpecialSearchFieldPrice(productPriceBO));
}
public Map<String, Object> getProductPriceModelMap(Integer productId, Integer firstShelveTime, ProductPrice pp) {
Map<String, Object> indexData = new HashMap<String, Object>();
indexData.put("isnew", "N");
if (pp == null) {
return indexData;
}
// 构造ProductPriceBO
ProductPriceBO productPriceBO = new ProductPriceBO(pp);
this.buildProductPriceBO(productPriceBO);
indexData.put("productId", productId);
indexData.put("marketPrice", this.getDoubleFromBigDecimal(productPriceBO.getMarketPrice()));
indexData.put("salesPrice", this.getDoubleFromBigDecimal(productPriceBO.getSalesPrice()));
indexData.put("vipPrice", this.getDoubleFromBigDecimal(productPriceBO.getVipPrice()));
indexData.put("vipDiscountType", productPriceBO.getVipDiscountType());
indexData.put("vip1Price", this.getDoubleFromBigDecimal(productPriceBO.getVip1Price()));
indexData.put("vip2Price", this.getDoubleFromBigDecimal(productPriceBO.getVip2Price()));
indexData.put("vip3Price", this.getDoubleFromBigDecimal(productPriceBO.getVip3Price()));
indexData.put("studentPrice", this.getDoubleFromBigDecimal(productPriceBO.getStudentPrice()));
indexData.put("isDiscount", productPriceBO.getIsDiscount());
indexData.put("specialoffer", productPriceBO.getSpecialoffer());
indexData.put("promotionDiscountInt", productPriceBO.getPromotionDiscountInt());
indexData.put("promotionDiscount", this.getDoubleFromBigDecimal(productPriceBO.getPromotionDiscount()));
indexData.put("isStudentPrice", productPriceBO.getIsStudentPrice());
indexData.put("isstudentrebate", productPriceBO.getIsstudentrebate());
indexData.put("vipLevels", productPriceBO.getVipLevels());
indexData.put("priceUpdateTime", productPriceBO.getUpdateTime());
if (firstShelveTime != null) {
indexData.put("isnew", this.isNew(firstShelveTime, productPriceBO.getMarketPrice(), productPriceBO.getSalesPrice()));
}
indexData.put(ProductIndexEsField.specialSearchFieldPrice, specialSearchFieldLogicService.getSpecialSearchFieldPrice(productPriceBO));
return indexData;
}
/**
* isNew 标签逻辑
*/
public boolean isNew(Integer firstShelveTime, BigDecimal marketPrice, BigDecimal salesPrice) {
try {
if (firstShelveTime == null || firstShelveTime <= 0 || salesPrice == null || marketPrice == null) {
return false;
}
long dateCount = DateUtil.daysBetween(new Date(firstShelveTime * 1000L), new Date());
if (dateCount > 7) {
return false;
}
// 计算折扣
Double discount = MathUtils.getDevideValue(salesPrice, marketPrice, 2, RoundingMode.DOWN);
if (discount >= 0.88) {
return true;
}
return false;
} catch (Exception e) {
return false;
}
}
/**
* isNew 标签逻辑
*/
public boolean isNew(Integer firstShelveTime, BigDecimal marketPrice, BigDecimal salesPrice) {
try {
if (firstShelveTime == null || firstShelveTime <= 0 || salesPrice == null || marketPrice == null) {
return false;
}
long dateCount = DateUtil.daysBetween(new Date(firstShelveTime * 1000L), new Date());
if (dateCount > 7) {
return false;
}
// 计算折扣
Double discount = MathUtils.getDevideValue(salesPrice, marketPrice, 2, RoundingMode.DOWN);
if (discount >= 0.88) {
return true;
}
return false;
} catch (Exception e) {
return false;
}
}
private double divide(int scale, BigDecimal a, BigDecimal b) {
if (b == null || b.compareTo(BigDecimal.ZERO) == 0) {
return 0;
}
StringBuilder sb = new StringBuilder("0.0");
for (int i = 1; i < scale; i++) {
sb.append('0');
}
BigDecimal divideResult = a.divide(b, scale, RoundingMode.DOWN);
DecimalFormat decimalFormat = new DecimalFormat(sb.toString());
String result = decimalFormat.format(divideResult);
return Double.parseDouble(result);
}
private double divide(int scale, BigDecimal a, BigDecimal b) {
if (b == null || b.compareTo(BigDecimal.ZERO) == 0) {
return 0;
}
StringBuilder sb = new StringBuilder("0.0");
for (int i = 1; i < scale; i++) {
sb.append('0');
}
BigDecimal divideResult = a.divide(b, scale, RoundingMode.DOWN);
DecimalFormat decimalFormat = new DecimalFormat(sb.toString());
String result = decimalFormat.format(divideResult);
return Double.parseDouble(result);
}
private double getDoubleFromBigDecimal(BigDecimal bigDecimal) {
if (bigDecimal == null) {
return 0d;
}
return bigDecimal.doubleValue();
}
private double getDoubleFromBigDecimal(BigDecimal bigDecimal) {
if (bigDecimal == null) {
return 0d;
}
return bigDecimal.doubleValue();
}
private BigDecimal getBigDecimalFromDouble(Double d) {
if (d == null) {
return new BigDecimal(0);
}
return new BigDecimal(d);
}
private BigDecimal getBigDecimalFromDouble(Double d) {
if (d == null) {
return new BigDecimal(0);
}
return new BigDecimal(d);
}
}
... ...
index:
analysis:
tokenizer:
my_pinyin:
type: pinyin
first_letter: prefix
padding_char: ''
pinyin_first_letter:
type: pinyin
first_letter: only
simple_pinyin:
type: pinyin
first_letter: none
padding_char: ''
ngram_1_to_2:
type: nGram
min_gram: 1
max_gram: 2
ngram_1_to_3:
type: nGram
min_gram: 1
max_gram: 3
filter:
ngram_min_3:
max_gram: 10
min_gram: 3
type: nGram
ngram_min_2:
max_gram: 10
min_gram: 2
type: nGram
ngram_min_1:
max_gram: 10
min_gram: 1
type: nGram
min2_length:
min: 2
max: 4
type: length
min3_length:
min: 3
max: 4
type: length
pinyin_first_letter:
type: pinyin
first_letter: only
my_stop:
type: stop
stopwords_path: custom/stopwords.txt
my_synonym:
type: synonym
synonyms_path: custom/synonyms.dic
analyzer:
lowercase_standard:
type: custom
filter:
- lowercase
tokenizer: standard
lowercase_keyword:
type: custom
filter:
- lowercase
tokenizer: keyword
lowercase_whitespace:
type: custom
filter:
- lowercase
tokenizer: whitespace
lowercase_keyword_ngram:
type: custom
filter:
- lowercase
- stop
- trim
- unique
tokenizer: ngram_1_to_3
ik_max_word:
type: ik
use_smart: false
ik_max_word_syno:
type: custom
tokenizer: ik
filter: [my_synonym]
use_smart: false
ik_smart:
type: ik
use_smart: true
ik_complex:
type: custom
tokenizer: ik_smart
filter:
- lowercase
- ik_dyn_synonym
- lowercase
- my_stop
- unique
ik_complex_search:
type: custom
tokenizer: ik_smart
filter:
- lowercase
- my_stop
- unique
comma_spliter:
type: pattern
pattern: "[,|\\s]+"
pinyin_analyzer:
type: custom
tokenizer: simple_pinyin
filter:
- standard
- word_delimiter
- lowercase
- trim
- unique
index.analysis.analyzer.default.type: keyword
index.search.slowlog.level: TRACE
index.search.slowlog.threshold.query.warn: 1s
index.search.slowlog.threshold.query.info: 800ms
index.search.slowlog.threshold.query.debug: 500ms
index.search.slowlog.threshold.query.trace: 200ms
index.search.slowlog.threshold.fetch.warn: 1s
index.search.slowlog.threshold.fetch.info: 800ms
index.search.slowlog.threshold.fetch.debug: 500ms
index.search.slowlog.threshold.fetch.trace: 200ms
\ No newline at end of file
... ...