|
|
@ -19,6 +19,7 @@ package com.epmet.redis; |
|
|
|
|
|
|
|
import com.epmet.commons.tools.constant.NumConstant; |
|
|
|
import com.epmet.commons.tools.redis.RedisUtils; |
|
|
|
import com.epmet.commons.tools.utils.ConvertUtils; |
|
|
|
import com.epmet.constant.GovIssueRedisKeys; |
|
|
|
import com.epmet.dao.IssueProjectCategoryDictDao; |
|
|
|
import com.epmet.dao.IssueProjectTagDictDao; |
|
|
@ -72,18 +73,21 @@ public class IssueProjectTagDictRedis { |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* @Description 传入category列表,返回对应category下的标签,按热度排序 |
|
|
|
* category列表为空则查询客户下全部 |
|
|
|
* 如果想要自定义标签,单独请求一次,分类列表中只含"customize" |
|
|
|
* @Description |
|
|
|
* |
|
|
|
* 排序规则: |
|
|
|
* 1、默认标签,按照分类排序 |
|
|
|
* 2、自定义标签,按照热度排序 |
|
|
|
* |
|
|
|
* @param customerId |
|
|
|
* @param category |
|
|
|
* @return java.util.List<com.epmet.dto.result.IssueCategoryTagResultDTO> |
|
|
|
* @return |
|
|
|
* @author wangc |
|
|
|
* @date 2020.12.09 11:16 |
|
|
|
*/ |
|
|
|
public Map<String,List<IssueCategoryTagResultDTO>> getTagsOrderByRank(String customerId,List<String> category) { |
|
|
|
*/ |
|
|
|
public Map<String,List<IssueCategoryTagResultDTO>> getDefaultTagsSortedByCategoryAndCustomizedTagsOrderByRank(String customerId,List<String> category) { |
|
|
|
if (StringUtils.isBlank(customerId)) { |
|
|
|
log.error("customerId can not be null when obtain govern tags."); |
|
|
|
return null; |
|
|
@ -91,73 +95,140 @@ public class IssueProjectTagDictRedis { |
|
|
|
|
|
|
|
IssueProjectCategoryDictEntity otherCategory = categoryDictDao.selectSingleByCustomerIdAndCategoryNameAndCategoryType(customerId, ModuleConstants.CATEGORY_NAME_OTHERS, null); |
|
|
|
boolean ifOtherOnly = null == otherCategory ? false : (!CollectionUtils.isEmpty(category) && category.size() == NumConstant.ONE && category.contains(otherCategory.getId()) ? true : false); |
|
|
|
Set<String> keys; |
|
|
|
if (CollectionUtils.isEmpty(category) || ifOtherOnly) |
|
|
|
keys = redisUtils.keys(GovIssueRedisKeys.getGovernmentTagKey(customerId, null)); |
|
|
|
else keys = category.stream().map(key -> { |
|
|
|
return GovIssueRedisKeys.getGovernmentTagKey(customerId, key); |
|
|
|
}).collect(Collectors.toSet()); |
|
|
|
|
|
|
|
Map<String,List<IssueCategoryTagResultDTO>> result = new HashMap<>(); |
|
|
|
|
|
|
|
List<IssueProjectTagDictEntity> _default = poolDao.selectTagByCategory(ifOtherOnly || CollectionUtils.isEmpty(category) ? null : category, customerId, NumConstant.ZERO_STR);//默认
|
|
|
|
if(!CollectionUtils.isEmpty(_default)){ |
|
|
|
result.put(ModuleConstants.DEFAULT_TAG_CATEGORY_NAME,_default.stream().map(o -> { |
|
|
|
IssueCategoryTagResultDTO tag = ConvertUtils.sourceToTarget(o,IssueCategoryTagResultDTO.class); |
|
|
|
tag.setName(o.getTagName()); return tag;}).collect(Collectors.toList())); |
|
|
|
}else log.error("there is no default tag data in database , customerId : {}",customerId); |
|
|
|
|
|
|
|
|
|
|
|
//如果keys集合为空,说明缓存中没有当前客户的标签排行信息,直接进行补偿
|
|
|
|
if (!CollectionUtils.isEmpty(keys)){ |
|
|
|
keys.remove(GovIssueRedisKeys.getGovernmentTagKey(customerId,ModuleConstants.CUSTOMIZED_TAG_CATEGORY_NAME)); |
|
|
|
List<Set<ZSetOperations.TypedTuple<Object>>> heatTuple = redisTemplate.executePipelined(new RedisCallback<Set<ZSetOperations.TypedTuple<Object>>>() { |
|
|
|
@Nullable |
|
|
|
@Override |
|
|
|
public Set<ZSetOperations.TypedTuple<Object>> doInRedis(RedisConnection connection) throws DataAccessException { |
|
|
|
connection.openPipeline(); |
|
|
|
keys.forEach(key -> { |
|
|
|
connection.zSetCommands().zRangeByScoreWithScores(redisTemplate.getKeySerializer().serialize(key), NumConstant.ZERO_L, (long) (NumConstant.ONE_NEG)); |
|
|
|
}); |
|
|
|
return null; |
|
|
|
} |
|
|
|
}, redisTemplate.getValueSerializer()); |
|
|
|
|
|
|
|
Map<String,List<IssueCategoryTagResultDTO>> result = new HashMap<>(); |
|
|
|
if (!CollectionUtils.isEmpty(heatTuple)) { |
|
|
|
//热度Map 分数为key
|
|
|
|
Map<Double, List<IssueCategoryTagResultDTO>> heatMap = new HashMap<>(); |
|
|
|
heatTuple.forEach(tupleSet -> { |
|
|
|
tupleSet.forEach(tuple -> { |
|
|
|
Double heatScore = tuple.getScore(); |
|
|
|
List<IssueCategoryTagResultDTO> queue = heatMap.get(heatScore); |
|
|
|
if (CollectionUtils.isEmpty(queue)) queue = new LinkedList<>(); |
|
|
|
queue.add(parseObject(tuple.getValue(), IssueCategoryTagResultDTO.class)); |
|
|
|
heatMap.put(heatScore, queue); |
|
|
|
}); |
|
|
|
Set<ZSetOperations.TypedTuple<Object>> customizedTuples = redisUtils.zReverseRangeWithScores(GovIssueRedisKeys.getGovernmentTagKey(customerId, null), NumConstant.ZERO_L, (long) (NumConstant.ONE_NEG)); |
|
|
|
if(!CollectionUtils.isEmpty(customizedTuples)){ |
|
|
|
Map<Double, List<IssueCategoryTagResultDTO>> customizedHeatMap = new HashMap<>(); |
|
|
|
customizedTuples.forEach(tuple -> { |
|
|
|
List<IssueCategoryTagResultDTO> queue = customizedHeatMap.get(tuple.getValue()); |
|
|
|
if((CollectionUtils.isEmpty(queue))) queue = new LinkedList<>(); |
|
|
|
queue.add(parseObject(tuple.getValue(), IssueCategoryTagResultDTO.class)); |
|
|
|
customizedHeatMap.put((Double) tuple.getValue(),queue); |
|
|
|
}); |
|
|
|
List<IssueCategoryTagResultDTO> defaultResult = new LinkedList<>(); |
|
|
|
heatMap.keySet().stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList()).forEach(count -> { |
|
|
|
defaultResult.addAll(heatMap.get(count)); |
|
|
|
List<IssueCategoryTagResultDTO> customizedResult = new LinkedList<>(); |
|
|
|
customizedHeatMap.keySet().stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList()).forEach(count -> { |
|
|
|
customizedResult.addAll(customizedHeatMap.get(count)); |
|
|
|
}); |
|
|
|
result.put(ModuleConstants.CUSTOMIZED_TAG_CATEGORY_NAME,customizedResult); |
|
|
|
} |
|
|
|
|
|
|
|
result.put(ModuleConstants.DEFAULT_TAG_CATEGORY_NAME, defaultResult); |
|
|
|
if(!CollectionUtils.isEmpty(result)) |
|
|
|
return result; |
|
|
|
|
|
|
|
|
|
|
|
log.warn("fetch customer govern tag cache blankly,customerId:{},now begin compensation...", customerId); |
|
|
|
|
|
|
|
Map<String,List<IssueCategoryTagResultDTO>> compensate = compensate(customerId, category, ifOtherOnly); |
|
|
|
|
|
|
|
if (CollectionUtils.isEmpty(compensate)) { |
|
|
|
log.error("compensation failure or there is no tag data in database!!"); |
|
|
|
return null; |
|
|
|
} else { |
|
|
|
log.warn("compensation completed!!"); |
|
|
|
return compensate; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* @Description category为空,则补偿全部,返回默认标签和自定义标签 |
|
|
|
* category仅包含"其他"这个分类的Id时,同上 |
|
|
|
* category不为空且不只有"其他"这个分类的Id时,则返回集合中的类别标签以及自定义标签 |
|
|
|
* 默认标签不按照热度排序,自定义标签按照热度排序 |
|
|
|
* |
|
|
|
* @param customerId |
|
|
|
* @param category |
|
|
|
* @return |
|
|
|
* @author wangc |
|
|
|
* @date 2020.12.09 11:16 |
|
|
|
*/ |
|
|
|
public Map<String,List<IssueCategoryTagResultDTO>> getTagsOrderByRank(String customerId,List<String> category) { |
|
|
|
if (StringUtils.isBlank(customerId)) { |
|
|
|
log.error("customerId can not be null when obtain govern tags."); |
|
|
|
return null; |
|
|
|
} |
|
|
|
Set<ZSetOperations.TypedTuple<Object>> customizedTuples = redisUtils.zReverseRangeWithScores(GovIssueRedisKeys.getGovernmentTagKey(customerId, null), NumConstant.ZERO_L, (long) (NumConstant.ONE_NEG)); |
|
|
|
if(!CollectionUtils.isEmpty(customizedTuples)){ |
|
|
|
Map<Double, List<IssueCategoryTagResultDTO>> customizedHeatMap = new HashMap<>(); |
|
|
|
customizedTuples.forEach(tuple -> { |
|
|
|
List<IssueCategoryTagResultDTO> queue = customizedHeatMap.get(tuple.getValue()); |
|
|
|
if((CollectionUtils.isEmpty(queue))) queue = new LinkedList<>(); |
|
|
|
|
|
|
|
IssueProjectCategoryDictEntity otherCategory = categoryDictDao.selectSingleByCustomerIdAndCategoryNameAndCategoryType(customerId, ModuleConstants.CATEGORY_NAME_OTHERS, null); |
|
|
|
boolean ifOtherOnly = null == otherCategory ? false : (!CollectionUtils.isEmpty(category) && category.size() == NumConstant.ONE && category.contains(otherCategory.getId()) ? true : false); |
|
|
|
Set<String> keys; |
|
|
|
if (CollectionUtils.isEmpty(category) || ifOtherOnly) |
|
|
|
keys = redisUtils.keys(GovIssueRedisKeys.getGovernmentTagKey(customerId, null)); |
|
|
|
else keys = category.stream().map(key -> { |
|
|
|
return GovIssueRedisKeys.getGovernmentTagKey(customerId, key); |
|
|
|
}).collect(Collectors.toSet()); |
|
|
|
//如果keys集合为空,说明缓存中没有当前客户的标签排行信息,直接进行补偿
|
|
|
|
if (!CollectionUtils.isEmpty(keys)){ |
|
|
|
keys.remove(GovIssueRedisKeys.getGovernmentTagKey(customerId,ModuleConstants.CUSTOMIZED_TAG_CATEGORY_NAME)); |
|
|
|
List<Set<ZSetOperations.TypedTuple<Object>>> heatTuple = redisTemplate.executePipelined(new RedisCallback<Set<ZSetOperations.TypedTuple<Object>>>() { |
|
|
|
@Nullable |
|
|
|
@Override |
|
|
|
public Set<ZSetOperations.TypedTuple<Object>> doInRedis(RedisConnection connection) throws DataAccessException { |
|
|
|
connection.openPipeline(); |
|
|
|
keys.forEach(key -> { |
|
|
|
connection.zSetCommands().zRangeByScoreWithScores(redisTemplate.getKeySerializer().serialize(key), NumConstant.ZERO_L, (long) (NumConstant.ONE_NEG)); |
|
|
|
}); |
|
|
|
return null; |
|
|
|
} |
|
|
|
}, redisTemplate.getValueSerializer()); |
|
|
|
|
|
|
|
Map<String,List<IssueCategoryTagResultDTO>> result = new HashMap<>(); |
|
|
|
if (!CollectionUtils.isEmpty(heatTuple)) { |
|
|
|
//热度Map 分数为key
|
|
|
|
Map<Double, List<IssueCategoryTagResultDTO>> heatMap = new HashMap<>(); |
|
|
|
heatTuple.forEach(tupleSet -> { |
|
|
|
tupleSet.forEach(tuple -> { |
|
|
|
Double heatScore = tuple.getScore(); |
|
|
|
List<IssueCategoryTagResultDTO> queue = heatMap.get(heatScore); |
|
|
|
if (CollectionUtils.isEmpty(queue)) queue = new LinkedList<>(); |
|
|
|
queue.add(parseObject(tuple.getValue(), IssueCategoryTagResultDTO.class)); |
|
|
|
customizedHeatMap.put((Double) tuple.getValue(),queue); |
|
|
|
heatMap.put(heatScore, queue); |
|
|
|
}); |
|
|
|
}); |
|
|
|
List<IssueCategoryTagResultDTO> customizedResult = new LinkedList<>(); |
|
|
|
customizedHeatMap.keySet().stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList()).forEach(count -> { |
|
|
|
customizedResult.addAll(customizedHeatMap.get(count)); |
|
|
|
List<IssueCategoryTagResultDTO> defaultResult = new LinkedList<>(); |
|
|
|
heatMap.keySet().stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList()).forEach(count -> { |
|
|
|
defaultResult.addAll(heatMap.get(count)); |
|
|
|
}); |
|
|
|
result.put(ModuleConstants.CUSTOMIZED_TAG_CATEGORY_NAME,customizedResult); |
|
|
|
} |
|
|
|
return result; |
|
|
|
|
|
|
|
} |
|
|
|
result.put(ModuleConstants.DEFAULT_TAG_CATEGORY_NAME, defaultResult); |
|
|
|
} |
|
|
|
Set<ZSetOperations.TypedTuple<Object>> customizedTuples = redisUtils.zReverseRangeWithScores(GovIssueRedisKeys.getGovernmentTagKey(customerId, null), NumConstant.ZERO_L, (long) (NumConstant.ONE_NEG)); |
|
|
|
if(!CollectionUtils.isEmpty(customizedTuples)){ |
|
|
|
Map<Double, List<IssueCategoryTagResultDTO>> customizedHeatMap = new HashMap<>(); |
|
|
|
customizedTuples.forEach(tuple -> { |
|
|
|
List<IssueCategoryTagResultDTO> queue = customizedHeatMap.get(tuple.getValue()); |
|
|
|
if((CollectionUtils.isEmpty(queue))) queue = new LinkedList<>(); |
|
|
|
queue.add(parseObject(tuple.getValue(), IssueCategoryTagResultDTO.class)); |
|
|
|
customizedHeatMap.put((Double) tuple.getValue(),queue); |
|
|
|
}); |
|
|
|
List<IssueCategoryTagResultDTO> customizedResult = new LinkedList<>(); |
|
|
|
customizedHeatMap.keySet().stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList()).forEach(count -> { |
|
|
|
customizedResult.addAll(customizedHeatMap.get(count)); |
|
|
|
}); |
|
|
|
result.put(ModuleConstants.CUSTOMIZED_TAG_CATEGORY_NAME,customizedResult); |
|
|
|
} |
|
|
|
return result; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
log.warn("fetch customer govern tag cache blankly,customerId:{},now begin compensation...", customerId); |
|
|
|
|
|
|
|
Map<String,List<IssueCategoryTagResultDTO>> compensate = compensate(customerId, category, ifOtherOnly); |
|
|
|
Map<String,List<IssueCategoryTagResultDTO>> compensate = compensate(customerId, category, ifOtherOnly); |
|
|
|
|
|
|
|
if (CollectionUtils.isEmpty(compensate)) { |
|
|
|
log.error("compensation failure or there is no default tag data in database!!"); |
|
|
|
log.error("compensation failure or there is no tag data in database!!"); |
|
|
|
return null; |
|
|
|
} else { |
|
|
|
log.warn("compensation completed!!"); |
|
|
@ -165,26 +236,70 @@ public class IssueProjectTagDictRedis { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* @Description category为空,则补偿全部,返回全部 |
|
|
|
* category不为空,则补偿集合中的类别标签以及自定义标签 |
|
|
|
* category为"customize",只补偿自定义标签 |
|
|
|
* 只需查询标签库(issue_project_tag_dict)中的issueUseCount和projectUseCount即可 |
|
|
|
* @Description category为空,则补偿全部,返回默认标签和自定义标签,补偿全部 |
|
|
|
* category仅包含"其他"这个分类的Id时,返回同上,补偿全部 |
|
|
|
* category不为空且不只有"其他"这个分类的Id时,则返回并补偿集合中的类别标签以及自定义标签 |
|
|
|
* 默认标签不按照热度排序,自定义标签按照热度排序 |
|
|
|
* |
|
|
|
* |
|
|
|
* @param customerId |
|
|
|
* @param category |
|
|
|
* @return java.util.List<com.epmet.dto.result.IssueCategoryTagResultDTO> |
|
|
|
* @return |
|
|
|
* @author wangc |
|
|
|
* @date 2020.12.10 09:34 |
|
|
|
*/ |
|
|
|
public Map<String,List<IssueCategoryTagResultDTO>> compensate(String customerId,List<String> category,boolean ifOtherOnly){ |
|
|
|
|
|
|
|
|
|
|
|
List<IssueProjectTagDictEntity> _default = poolDao.selectTagByCategory(ifOtherOnly || CollectionUtils.isEmpty(category) ? null : category, NumConstant.ZERO_STR, customerId);//默认
|
|
|
|
List<IssueProjectTagDictEntity> _customized = poolDao.selectTagByCategory(null,NumConstant.ONE_STR,customerId);//自定义
|
|
|
|
List<IssueProjectTagDictEntity> db = poolDao.selectTagByCategory(ifOtherOnly || CollectionUtils.isEmpty(category) ? null : category, customerId, null); |
|
|
|
|
|
|
|
|
|
|
|
// key -> redisKey
|
|
|
|
// value -> [key : score ; value : object]
|
|
|
|
Map<String,Map<Integer,List<IssueCategoryTagResultDTO>>> fulfilled = new HashMap<>(); |
|
|
|
Map<String,List<IssueCategoryTagResultDTO>> result = new HashMap<>(); |
|
|
|
if(!CollectionUtils.isEmpty(db)) { |
|
|
|
Map<String, List<IssueProjectTagDictEntity>> categoryMap = db.stream().collect(Collectors.groupingBy(IssueProjectTagDictEntity::getCategoryId)); |
|
|
|
//key -> categoryId
|
|
|
|
categoryMap.forEach((k, v) -> { |
|
|
|
Map<Integer, List<IssueCategoryTagResultDTO>> scoreMap = new HashMap<>(); |
|
|
|
String redisKey = GovIssueRedisKeys.getGovernmentTagKey(customerId, k); |
|
|
|
v.forEach(tag -> { |
|
|
|
List<IssueCategoryTagResultDTO> unit = scoreMap.get(tag.getIssueUseCount()); |
|
|
|
if (CollectionUtils.isEmpty(unit)) unit = new LinkedList<>(); |
|
|
|
IssueCategoryTagResultDTO object = ConvertUtils.sourceToTarget(tag, IssueCategoryTagResultDTO.class); |
|
|
|
object.setName(tag.getTagName()); |
|
|
|
unit.add(object); |
|
|
|
scoreMap.put(tag.getIssueUseCount(), unit); |
|
|
|
}); |
|
|
|
fulfilled.put(redisKey, scoreMap); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
redisTemplate.executePipelined((RedisCallback) connection -> { |
|
|
|
fulfilled.forEach((redisKey, map) -> { |
|
|
|
map.forEach((score,list) -> { |
|
|
|
list.forEach(factor -> { |
|
|
|
connection.zSetCommands().zAdd(redisTemplate.getValueSerializer().serialize(redisKey), |
|
|
|
score.doubleValue(), |
|
|
|
redisTemplate.getValueSerializer().serialize(factor)); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
}); |
|
|
|
return null; |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
Map<String,List<IssueCategoryTagResultDTO>> result = new HashMap<>(); |
|
|
|
result.put(ModuleConstants.DEFAULT_TAG_CATEGORY_NAME,CollectionUtils.isEmpty(db) ? null : db.stream().filter(o -> !StringUtils.equals(ModuleConstants.CUSTOMIZED_TAG_CATEGORY_NAME,o.getCategoryId())).map(entity -> { |
|
|
|
IssueCategoryTagResultDTO tag = ConvertUtils.sourceToTarget(entity,IssueCategoryTagResultDTO.class); |
|
|
|
tag.setName(entity.getTagName()); return tag;}).collect(Collectors.toList())); |
|
|
|
result.put(ModuleConstants.CUSTOMIZED_TAG_CATEGORY_NAME,CollectionUtils.isEmpty(db) ? null : db.stream().filter(o -> !StringUtils.equals(ModuleConstants.CUSTOMIZED_TAG_CATEGORY_NAME,o.getCategoryId())).sorted(Comparator.comparing(IssueProjectTagDictEntity :: getIssueUseCount).reversed()).map(entity -> { |
|
|
|
IssueCategoryTagResultDTO tag = ConvertUtils.sourceToTarget(entity,IssueCategoryTagResultDTO.class); |
|
|
|
tag.setName(entity.getTagName());return tag;}).collect(Collectors.toList())); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|