Commit b2fe20c8 by shenjunjie

Merge branch 'feature' into 'dev'

渠道影响力计算完成;修复渠道库部分

See merge request !20
parents 41bd816b 426ad205
......@@ -60,8 +60,8 @@ public class RedisKeyPrefix {
*/
private static final String EVENT_ANALYZE_PROGRESS = "BRANDKBS:EVENT:ANALYZE:PROGRESS:";
public static String eventAnalysisProgress(String eventId) {
return RedisKeyPrefix.generateRedisKey(RedisKeyPrefix.EVENT_ANALYZE_PROGRESS, UserThreadLocal.getProjectId(), eventId);
public static String eventAnalysisProgress(String eventId, String projectId) {
return RedisKeyPrefix.generateRedisKey(RedisKeyPrefix.EVENT_ANALYZE_PROGRESS, projectId, eventId);
}
public static String yuqingProgressKey(String linkedGroupId) {
......
......@@ -2,6 +2,8 @@ package com.zhiwei.brandkbs2.config;
import org.apache.commons.lang3.time.FastDateFormat;
import java.text.ParseException;
/**
* @ClassName: Constant
* @Description 常量
......@@ -10,6 +12,7 @@ import org.apache.commons.lang3.time.FastDateFormat;
*/
public class Constant {
public static final Long EIGHT_HOUR = 8 * 60 * 60 * 1000L;
public static final Long ONE_DAY = 24 * 60 * 60 * 1000L;
public static final Long ONE_MONTH = 30 * 24 * 60 * 60 * 1000L;
......@@ -19,6 +22,7 @@ public class Constant {
public static final FastDateFormat HOUR_FORMAT = FastDateFormat.getInstance(HOUR_PATTERN);
public static final FastDateFormat DAY_FORMAT = FastDateFormat.getInstance(DAY_PATTERN);
public static final FastDateFormat MONTH_FORMAT = FastDateFormat.getInstance(MONTH_PATTERN);
/**
* 自定义fid分隔符号
......@@ -38,4 +42,13 @@ public class Constant {
*/
public static final String TASK_REPORT_JOB = "定时生成项目简报数据";
public static final int INIT_VERSION = 0;
public static Long add8Hours(String time, FastDateFormat dateFormat) {
try {
return dateFormat.parse(time).getTime() + EIGHT_HOUR;
} catch (ParseException ignored) {
}
return -1L;
}
}
......@@ -6,6 +6,7 @@ import com.zhiwei.brandkbs2.easyexcel.EasyExcelUtil;
import com.zhiwei.brandkbs2.easyexcel.dto.ExportAppChannelArticleDTO;
import com.zhiwei.brandkbs2.enmus.RoleEnum;
import com.zhiwei.brandkbs2.model.ResponseResult;
import com.zhiwei.brandkbs2.pojo.dto.ExportAppChannelEventDTO;
import com.zhiwei.brandkbs2.service.ChannelService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
......@@ -94,7 +95,7 @@ public class AppChannelController extends BaseController {
@ApiOperation("渠道库-收藏渠道")
@ApiImplicitParam(name = "channelId", value = "渠道ID", required = true, paramType = "path", dataType = "string")
@PostMapping("/collect/{channelId}}")
@PostMapping("/collect/{channelId}")
public ResponseResult collectChannel(@PathVariable String channelId) {
return ResponseResult.success(channelService.collectChannel(channelId));
}
......@@ -190,4 +191,38 @@ public class AppChannelController extends BaseController {
return ResponseResult.success();
}
@ApiOperation("渠道-事件列表")
@ApiImplicitParams({
@ApiImplicitParam(name = "startTime", value = "开始时间", required = true, paramType = "query", dataType = "long"),
@ApiImplicitParam(name = "endTime", value = "结束时间", required = true, paramType = "query", dataType = "long"),
@ApiImplicitParam(name = "page", value = "页码", defaultValue = "1", paramType = "query", dataType = "int"),
@ApiImplicitParam(name = "pageSize", value = "页码大小", defaultValue = "10", paramType = "query", dataType = "int"),
@ApiImplicitParam(name = "channelId", value = "渠道ID", required = true, paramType = "query", dataType = "int"),
@ApiImplicitParam(name = "contendId", value = "竞品ID", defaultValue = "0", paramType = "query", dataType = "int")
})
@GetMapping("/events")
public ResponseResult getEvents(@RequestParam(value = "startTime") Long startTime,
@RequestParam(value = "endTime") Long endTime,
@RequestParam(value = "page", defaultValue = "1") int page,
@RequestParam(value = "pageSize", defaultValue = "10") int pageSize,
@RequestParam("channelId") String channelId,
@RequestParam(value = "contendId", defaultValue = "0") String contendId) {
return ResponseResult.success(channelService.getEventsByTime(startTime, endTime, page, pageSize, channelId, contendId));
}
@ApiOperation("渠道库-下载事件列表")
@ApiImplicitParams({
@ApiImplicitParam(name = "startTime", value = "开始时间", required = true, paramType = "query", dataType = "long"),
@ApiImplicitParam(name = "endTime", value = "结束时间", required = true, paramType = "query", dataType = "long"),
@ApiImplicitParam(name = "channelId", value = "渠道ID", required = true, paramType = "query", dataType = "string")
})
@GetMapping("/events/download")
public ResponseResult downloadEvents(@RequestParam(value = "startTime") long startTime,
@RequestParam(value = "endTime") long endTime,
@RequestParam("channelId") String channelId) {
List<ExportAppChannelEventDTO> exportAppChannelEventDTOS = channelService.downloadEventsByTime(startTime, endTime, channelId);
EasyExcelUtil.download(channelId + "渠道列表数据", "sheet1", ExportAppChannelEventDTO.class, exportAppChannelEventDTOS, response);
return ResponseResult.success();
}
}
......@@ -152,11 +152,7 @@ public interface BaseMongoDao<T extends AbstractBaseMongo> {
*/
default Criteria addChannelIndex(ChannelIndex channelIndex) {
Criteria criteria = new Criteria();
criteria.and("platform").is(channelIndex.getPlatform());
criteria.and("realSource").is(channelIndex.getRealSource());
criteria.and("source").is(channelIndex.getSource());
criteria.and("projectId").is(channelIndex.getProjectId());
criteria.and("linkedGroupId").is(channelIndex.getLinkedGroupId());
criteria.and("channelFid").is(channelIndex.getFid());
return criteria;
}
}
......@@ -60,4 +60,14 @@ public interface EventDao extends BaseMongoDao<Event> {
*/
Map<Long, List<Event>> getEventMonth(ChannelIndex channelIndex, Long startTime, Long endTime);
/**
* 获取参与的反常事件数
*
* @param channelIndex 渠道标识
* @param eventEmotions 事件情感倾向
* @param articleEmotion 文章情感倾向
* @return 参与的反常事件数
*/
long getEventCount(ChannelIndex channelIndex, List<String> eventEmotions, String articleEmotion);
}
package com.zhiwei.brandkbs2.dao.impl;
import com.alibaba.fastjson.JSONObject;
import com.zhiwei.brandkbs2.config.Constant;
import com.zhiwei.brandkbs2.dao.EventDao;
import com.zhiwei.brandkbs2.pojo.ChannelIndex;
import com.zhiwei.brandkbs2.pojo.Event;
import com.zhiwei.brandkbs2.util.Tools;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
import static com.zhiwei.brandkbs2.dao.impl.EventDataDaoImpl.COLLECTION_PREFIX;
......@@ -58,27 +58,71 @@ public class EventDaoImpl extends BaseMongoDaoImpl<Event> implements EventDao {
@Override
public Map<Long, List<Event>> getEventDay(ChannelIndex channelIndex, Long startTime, Long endTime) {
return getEventTimePattern(channelIndex, startTime, endTime, 8);
return getEventTimePattern(channelIndex, startTime, endTime, 8 + 2);
}
@Override
public Map<Long, List<Event>> getEventMonth(ChannelIndex channelIndex, Long startTime, Long endTime) {
return getEventTimePattern(channelIndex, startTime, endTime, 6);
return getEventTimePattern(channelIndex, startTime, endTime, 6 + 1);
}
@Override
public long getEventCount(ChannelIndex channelIndex, List<String> eventEmotions, String emotion) {
Criteria criteria = Criteria.where("emotion").in(eventEmotions).
and("projectId").is(channelIndex.getProjectId()).and("contendId").is(channelIndex.getContendId());
String aliasName = "articles";
Criteria lookUpCriteria = Criteria.where(aliasName.concat(".channelFid")).is(channelIndex.getFid());
if (null != emotion) {
lookUpCriteria.and(aliasName.concat(".emotion")).is(emotion);
}
// long count = mongoTemplate.count(Query.query(criteria), COLLECTION_NAME);
List<AggregationOperation> operations = Arrays.asList(
Aggregation.match(criteria),
// aoc -> new Document("$addFields", new Document("_id", new Document("$toString", "$_id"))), 该方式mongo版本不支持
Aggregation.lookup(getAggreeCollection(), "_id", "eventId", aliasName),
Aggregation.match(lookUpCriteria)
);
AggregationResults<JSONObject> aggregate = mongoTemplate.aggregate(Aggregation.newAggregation(operations), COLLECTION_NAME, JSONObject.class);
List<JSONObject> mappedResults = aggregate.getMappedResults();
return mappedResults.size();
}
private Map<Long, List<Event>> getEventTimePattern(ChannelIndex channelIndex, Long startTime, Long endTime, int nrOfChars) {
// 添加渠道唯一标识
Criteria criteria = addChannelIndex(channelIndex);
Map<Long, List<Event>> res = new HashMap<>();
// 事件筛选条件
Criteria criteria = Criteria.where("projectId").is(channelIndex.getProjectId()).and("contendId").is(channelIndex.getContendId());
criteria.and("startTime").gte(startTime).lt(endTime);
String aliasName = "articles";
Criteria lookUpCriteria = Criteria.where(aliasName.concat(".channelFid")).is(channelIndex.getFid());
// 分组
Aggregation agg = Aggregation.newAggregation(Aggregation.match(criteria),
// 截取前8位,按日分组
Aggregation.project("startTime", "eventId", "emotion").andExpression("add(new java.util.Date(0l),startTime)").substring(0, nrOfChars).as("patternDate"),
Aggregation.group("patternDate").count().as("eventCount"));
AggregationResults<JSONObject> aggregate = mongoTemplate.aggregate(agg, getAggreeCollection(), JSONObject.class);
Aggregation.project("startTime", "_id", "emotion", "influence", "title", "endTime", "eventTag"),
// 想通过截取的方式来分组,但是会有8小时误差问题未解决,故舍弃
// .andExpression("add(new java.util.Date(8),startTime)").substring(0, nrOfChars).as("patternDate"),
Aggregation.lookup(getAggreeCollection(), "_id", "eventId", aliasName),
Aggregation.match(lookUpCriteria)
);
AggregationResults<JSONObject> aggregate = mongoTemplate.aggregate(agg, COLLECTION_NAME, JSONObject.class);
List<JSONObject> mappedResults = aggregate.getMappedResults();
// TODO
return new HashMap<>();
for (JSONObject mappedResult : mappedResults) {
Long mapKey = mappedResult.getLong("startTime");
String pattern = Constant.MONTH_PATTERN;
if (10 == nrOfChars) {
pattern = Constant.DAY_PATTERN;
}
mapKey = Tools.truncDate(new Date(mapKey), pattern).getTime();
res.putIfAbsent(mapKey, new ArrayList<>());
Event event = new Event();
event.setId(mappedResult.getString("_id"));
event.setTitle(mappedResult.getString("title"));
event.setEmotion(mappedResult.getString("emotion"));
event.setStartTime(mappedResult.getLong("startTime"));
event.setEndTime(mappedResult.getLong("endTime"));
event.setEventTag(mappedResult.getJSONObject("eventTag"));
event.setInfluence(mappedResult.getDouble("influence"));
res.get(mapKey).add(event);
}
return res;
}
private String getAggreeCollection() {
......
package com.zhiwei.brandkbs2.easyexcel.dto;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zhiwei.brandkbs2.common.GenericAttribute;
import com.zhiwei.brandkbs2.config.Constant;
import com.zhiwei.brandkbs2.pojo.Event;
import com.zhiwei.brandkbs2.pojo.EventData;
......@@ -11,6 +9,7 @@ import com.zhiwei.brandkbs2.util.Tools;
import lombok.Data;
import lombok.ToString;
import org.apache.logging.log4j.util.Strings;
import org.bson.types.ObjectId;
import java.util.Date;
import java.util.Optional;
......@@ -83,11 +82,11 @@ public class UploadEventDataDTO {
JSONObject tagInfo = new JSONObject();
Optional.ofNullable(this.getEmotion()).ifPresent(emotion -> tagInfo.put(Constant.EMOTION_LABEL_KEY, emotion));
Optional.ofNullable(this.getBrand()).ifPresent(brand -> tagInfo.put(Constant.BRAND_LABEL_KEY, brand));
eventData.setTagInfo(JSON.toJSONString(tagInfo));
eventData.setTagInfo(tagInfo);
eventData.setEmotion(this.getEmotion());
eventData.setForward(this.isForward);
eventData.setEventId(event.getId());
eventData.setEventId(new ObjectId(event.getId()));
eventData.setProjectId(event.getProjectId());
eventData.setLinkedGroupId(event.getLinkedGroupId());
eventData.setCTime(System.currentTimeMillis());
......
......@@ -120,7 +120,7 @@ public class ChannelEsDao extends EsClientDao {
private BoolQueryBuilder channelUniqueBool(String fid) {
BoolQueryBuilder postFilter = QueryBuilders.boolQuery();
return postFilter.must(QueryBuilders.termQuery(ChannelRecord.KEY + ".keyword", fid));
return postFilter.must(QueryBuilders.termQuery("channel_fid.keyword", fid));
}
}
......@@ -31,7 +31,7 @@ public class ChannelIndex extends AbstractBaseMongo {
/**
* 竞品id
*/
private String contendId;
private String contendId = "0";
/**
* 关联项目组ID
......@@ -62,20 +62,20 @@ public class ChannelIndex extends AbstractBaseMongo {
*/
private Double emotionIndex;
public ChannelIndex(String projectId, String linkedGroupId, Channel channel) {
this(projectId, linkedGroupId, channel.getPlatform(), channel.getRealSource(), channel.getSource());
public ChannelIndex(Channel channel) {
this(channel.getProjectId(), channel.getContendId(), channel.getPlatform(), channel.getRealSource(), channel.getSource());
}
public ChannelIndex(String projectId, String linkedGroupId, String platform, String realSource, String source) {
public ChannelIndex(String projectId, String contendId, String platform, String realSource, String source) {
this.projectId = projectId;
this.linkedGroupId = linkedGroupId;
this.contendId = contendId;
this.platform = platform;
this.realSource = realSource;
this.source = source;
this.fid = Tools.getFid(projectId, linkedGroupId, platform, realSource, source);
this.fid = Tools.getFid(projectId, contendId, platform, realSource, source);
}
public static ChannelIndex createChannelIndex(Map<String, Object> sourceAsMap, String projectId, String linkedGroupId) {
public static ChannelIndex createChannelIndex(Map<String, Object> sourceAsMap, String projectId, String contendId) {
String realSource = String.valueOf(sourceAsMap.get(GenericAttribute.ES_REAL_SOURCE));
String source = String.valueOf(sourceAsMap.get(GenericAttribute.ES_SOURCE));
Integer c5 = Integer.parseInt(String.valueOf(sourceAsMap.get(GenericAttribute.ES_C5)));
......@@ -84,7 +84,7 @@ public class ChannelIndex extends AbstractBaseMongo {
if (null == messagePlatform) {
return null;
}
return new ChannelIndex(projectId, linkedGroupId, messagePlatform.getName(), realSource, source);
return new ChannelIndex(projectId, contendId, messagePlatform.getName(), realSource, source);
}
public static List<ChannelIndex> createChannelIndexes(Map<String, Object> sourceAsMap) {
......@@ -100,8 +100,8 @@ public class ChannelIndex extends AbstractBaseMongo {
List<Map<String, Object>> cacheMaps = (List<Map<String, Object>>) sourceAsMap.get(GenericAttribute.ES_BRANDKBS_CACHE_MAPS);
for (Map<String, Object> cacheMap : cacheMaps) {
String projectId = String.valueOf(cacheMap.get("project_id"));
String linkedGroupId = String.valueOf(cacheMap.get("linked_group_id"));
ChannelIndex channelIndex = new ChannelIndex(projectId, linkedGroupId, messagePlatform.getName(), realSource, source);
String contendId = String.valueOf(cacheMap.get("contend_id"));
ChannelIndex channelIndex = new ChannelIndex(projectId, contendId, messagePlatform.getName(), realSource, source);
// 默认主品牌
channelIndex.setContendId(String.valueOf(0));
Optional.ofNullable(cacheMap.get("contend_id")).ifPresent(e -> channelIndex.setContendId(String.valueOf(e)));
......@@ -249,12 +249,12 @@ public class ChannelIndex extends AbstractBaseMongo {
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
ChannelIndex that = (ChannelIndex) o;
return Objects.equals(fid, that.fid) && Objects.equals(contendId, that.contendId);
return Objects.equals(fid, that.fid);
}
@Override
public int hashCode() {
return Objects.hash(fid, contendId);
return Objects.hash(fid);
}
}
......@@ -6,6 +6,7 @@ import com.zhiwei.brandkbs2.pojo.dto.EventDataDTO;
import com.zhiwei.brandkbs2.util.Tools;
import lombok.Getter;
import lombok.Setter;
import org.bson.types.ObjectId;
import java.util.Map;
......@@ -20,9 +21,13 @@ import java.util.Map;
public class EventData extends AbstractBaseMongo {
/**
* 数据id
*/
private String articleId;
/**
* 事件ID
*/
private String eventId;
private ObjectId eventId;
/**
* 平台
*/
......@@ -64,6 +69,10 @@ public class EventData extends AbstractBaseMongo {
*/
private String contendId;
/**
* 渠道唯一ID
*/
private String channelFid;
/**
* 情感倾向
*/
private String emotion;
......@@ -78,29 +87,30 @@ public class EventData extends AbstractBaseMongo {
/**
* 标签数据
*/
private String tagInfo;
private JSONObject tagInfo;
/**
* 原创/转发(微博平台)
*/
private boolean isForward;
/**
* 来源标签(重要渠道)
* 渠道标签(重要渠道)
*/
private String sourceTag;
private String channelTag;
public static EventData createFromEsMap(Map<String, Object> map, Event event) {
EventData data = new EventData();
JSONObject jsonMap = new JSONObject(map);
BaseMap baseMap = Tools.getBaseFromEsMap(map);
data.setEventId(event.getId());
data.setEventId(new ObjectId(event.getId()));
data.setProjectId(event.getProjectId());
data.setContendId(event.getContendId());
data.setLinkedGroupId(event.getLinkedGroupId());
data.setPlatform(baseMap.getPlatform());
data.setRealSource(baseMap.getRealSource());
data.setSource(baseMap.getSource());
data.setChannelFid(Tools.concat(data.projectId, data.contendId, data.platform, data.realSource, data.source));
data.setUrl(baseMap.getUrl());
data.setTitle(baseMap.getTitleNullOptionalContent());
data.setTitle(baseMap.getTitle());
data.setAggTitle(Tools.filterSpecialCharacter(baseMap.getTitle()));
data.setContent(baseMap.getContent());
data.setEmotion(baseMap.getEmotion());
......@@ -108,7 +118,9 @@ public class EventData extends AbstractBaseMongo {
data.setForward(baseMap.isForward());
data.setCTime(jsonMap.getLong(GenericAttribute.ES_CTIME));
// TagInfo
data.setTagInfo(Tools.change2TagInfoByMtag(jsonMap.getString(GenericAttribute.ES_MTAG)).toJSONString());
data.setTagInfo(Tools.change2TagInfoByMtag(jsonMap.getString(GenericAttribute.ES_MTAG)));
data.setEmotion(baseMap.getEmotion());
data.setArticleId(jsonMap.getString("id"));
return data;
}
......
package com.zhiwei.brandkbs2.pojo.dto;
import com.alibaba.excel.annotation.ExcelProperty;
import com.zhiwei.brandkbs2.enmus.EventTagEnum;
import com.zhiwei.brandkbs2.pojo.Event;
import lombok.Data;
import lombok.ToString;
import java.util.Date;
/**
* @author lxj
* @version 1.0
* @description 导出渠道事件实体类
* @date 2019/11/12 15:05
*/
@Data
@ToString
public class ExportAppChannelEventDTO {
@ExcelProperty("开始时间")
private Date startTime;
@ExcelProperty("结束时间")
private Date endTime;
@ExcelProperty("事件名")
private String title;
@ExcelProperty("情感倾向")
private String emotion;
@ExcelProperty("事件类型")
private String eventType;
@ExcelProperty("影响力")
private Double influence;
public static ExportAppChannelEventDTO createFromEvent(Event event) {
ExportAppChannelEventDTO dto = new ExportAppChannelEventDTO();
dto.setStartTime(new Date(event.getStartTime()));
dto.setEndTime(new Date(event.getEndTime()));
dto.setTitle(event.getTitle());
dto.setEmotion(event.getEmotion());
dto.setInfluence(event.getInfluence());
dto.setEventType(event.getEventTag().getString(EventTagEnum.EVENT_TYPE.getName()));
return dto;
}
}
......@@ -5,7 +5,9 @@ import com.zhiwei.brandkbs2.easyexcel.dto.ExportAdminChannelArticleDTO;
import com.zhiwei.brandkbs2.easyexcel.dto.ExportAdminChannelEventDTO;
import com.zhiwei.brandkbs2.easyexcel.dto.ExportAppChannelArticleDTO;
import com.zhiwei.brandkbs2.easyexcel.dto.ExportChannelDTO;
import com.zhiwei.brandkbs2.pojo.Channel;
import com.zhiwei.brandkbs2.pojo.dto.ChannelDTO;
import com.zhiwei.brandkbs2.pojo.dto.ExportAppChannelEventDTO;
import com.zhiwei.brandkbs2.pojo.vo.ChannelListVO;
import com.zhiwei.brandkbs2.pojo.vo.PageVO;
......@@ -221,8 +223,32 @@ public interface ChannelService {
List<ExportAppChannelArticleDTO> downloadArticlesByTime(Long startTime, Long endTime, String channelId, String contendId);
/**
* 计算渠道倾向及指数
* 获取时间段事件信息
*
* @param startTime 开始时间时间戳
* @param endTime 结束时间
* @param page 页码
* @param pageSize 页码大小
* @param channelId 渠道ID
* @param contendId 竞品ID
* @return 事件信息
*/
JSONObject getEventsByTime(Long startTime, Long endTime, int page, int pageSize, String channelId, String contendId);
/**
* 下载时间段事件信息
*
* @param startTime 开始时间时间戳
* @param endTime 结束时间
* @param channelId 渠道ID
* @return 事件信息
*/
List<ExportAppChannelEventDTO> downloadEventsByTime(Long startTime, Long endTime, String channelId);
/**
* 计算渠道倾向及指数
*
* @param channel 渠道
*/
void calculateChannelEmotionIndex(String channelId);
Channel calculateChannelEmotionIndex(Channel channel);
}
......@@ -41,6 +41,8 @@ public interface ProjectService {
*/
ProjectVO getProjectVOById(String pid);
Project getProjectById(String pid);
/**
* 修改项目
*
......
......@@ -23,6 +23,7 @@ import com.zhiwei.brandkbs2.exception.ExceptionCast;
import com.zhiwei.brandkbs2.model.CommonCodeEnum;
import com.zhiwei.brandkbs2.pojo.*;
import com.zhiwei.brandkbs2.pojo.dto.ChannelDTO;
import com.zhiwei.brandkbs2.pojo.dto.ExportAppChannelEventDTO;
import com.zhiwei.brandkbs2.pojo.vo.ChannelListVO;
import com.zhiwei.brandkbs2.pojo.vo.PageVO;
import com.zhiwei.brandkbs2.service.ChannelService;
......@@ -47,6 +48,8 @@ import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilde
import org.elasticsearch.search.aggregations.metrics.Sum;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.joda.time.Period;
import org.joda.time.PeriodType;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
......@@ -482,6 +485,7 @@ public class ChannelServiceImpl implements ChannelService {
jsonObject.put("source", channel.getSource());
jsonObject.put("emotion", ChannelEmotion.getNameFromState(channel.getEmotion()));
jsonObject.put("emotionIndex", BigDecimal.valueOf(channel.getEmotionIndex()).setScale(2, RoundingMode.UP));
jsonObject.put("emotionRank", getChannelEmotionRank(channel.getEmotionIndex(), channel.getEmotion()));
jsonObject.put("articlesCount", channel.getArticleCount());
jsonObject.put("eventCount", channel.getEventCount());
jsonObject.put("channelTag", channelTagDao.getTagByChannelName(channel.getSource()));
......@@ -567,7 +571,7 @@ public class ChannelServiceImpl implements ChannelService {
for (Map.Entry<String, List<ChannelIndex.Article>> entry : contendMap.entrySet()) {
String contendId = entry.getKey();
Pair<Long, JSONObject> dataCount = getDataCount(entry.getValue());
Pair<Long, JSONObject> eventCount = getEventCount(startTime, endTime, projectId, contendId, channel);
Pair<Long, JSONObject> eventCount = getEventCount(startTime, endTime, channel);
articleTotal += dataCount.getLeft();
eventTotal += eventCount.getLeft();
// 合并统计
......@@ -657,6 +661,22 @@ public class ChannelServiceImpl implements ChannelService {
return dayResult;
}
private JSONObject getDayResultWithEvent(List<Event> list, int page, int pageSize, Long time) {
JSONObject dayResult = new JSONObject();
List<JSONObject> collect = list.stream().skip((long) (page - 1) * pageSize).limit(pageSize).map(event -> {
JSONObject json = new JSONObject();
json.put("id", event.getId());
json.put("emotion", event.getEmotion());
json.put("title", event.getTitle());
json.put("influence", event.getInfluence());
return json;
}).collect(Collectors.toList());
dayResult.put("events", collect);
dayResult.put("eventCount", list.size());
dayResult.put("time", time);
return dayResult;
}
@Override
public List<ExportAppChannelArticleDTO> downloadArticlesByTime(Long startTime, Long endTime, String channelId, String contendId) {
Map<String, List<ChannelIndex.Article>> sourceContendMap = getSourceContendMap(channelId, Collections.singleton(contendId), startTime, endTime);
......@@ -669,14 +689,42 @@ public class ChannelServiceImpl implements ChannelService {
}
@Override
public void calculateChannelEmotionIndex(String channelId) {
try {
public JSONObject getEventsByTime(Long startTime, Long endTime, int page, int pageSize, String channelId, String contendId) {
JSONObject res = new JSONObject();
List<JSONObject> dayList = new ArrayList<>();
Channel channel = channelDao.findOneById(channelId);
Map<Long, List<Event>> eventDay = eventDao.getEventDay(new ChannelIndex(channel), startTime, endTime);
eventDay = Tools.sortTimeKeyMap(eventDay, true);
eventDay.forEach((time, list) -> dayList.add(getDayResultWithEvent(list, page, pageSize, time)));
res.put("list", dayList);
return res;
}
@Override
public List<ExportAppChannelEventDTO> downloadEventsByTime(Long startTime, Long endTime, String channelId) {
List<ExportAppChannelEventDTO> res = new ArrayList<>();
Channel channel = channelDao.findOneById(channelId);
Map<Long, List<Event>> eventDay = eventDao.getEventDay(new ChannelIndex(channel), startTime, endTime);
Tools.sortTimeKeyMap(eventDay, true).values().forEach(events -> {
events.forEach(event -> {
res.add(ExportAppChannelEventDTO.createFromEvent(event));
});
});
return res;
}
@Override
public Channel calculateChannelEmotionIndex(Channel channel) {
try {
Project project = projectService.getProjectById(channel.getProjectId());
// 数据格式变化未含有contendId部分
if (null == channel.getContendId()) {
channel.setContendId("0");
}
if (hasEmotion(channel)) {
// 不做统计
if (!hasEmotion(channel)) {
return channel;
}
//该渠道发布正面稿件
Long positiveCount = markCountByEmotion(channel, EmotionEnum.POSITIVE.getName());
//该渠道发布中性稿件
......@@ -685,12 +733,408 @@ public class ChannelServiceImpl implements ChannelService {
Long negativeCount = markCountByEmotion(channel, EmotionEnum.NEGATIVE.getName());
//是否友好渠道
boolean isPositive = false;
boolean isNegative = false;
long specNegativeCount = eventDao.getEventCount(new ChannelIndex(channel), Arrays.asList(EmotionEnum.POSITIVE.getName(),
EmotionEnum.NEUTRAL.getName()), EmotionEnum.NEGATIVE.getName());
long specPositiveCount = eventDao.getEventCount(new ChannelIndex(channel), Arrays.asList(EmotionEnum.NEGATIVE.getName(),
EmotionEnum.POSITIVE.getName()), EmotionEnum.POSITIVE.getName());
// 特殊情况:若皆有发布过反常稿件
if (specNegativeCount > 0 && specPositiveCount > 0) {
//正面稿件数>负面稿件数,为正面
if (positiveCount > negativeCount) {
isPositive = true;
//正面稿件数<负面稿件数,为负面
} else if (positiveCount < negativeCount) {
isNegative = true;
}
} else {
// 在正/中性事件中发布负面稿件||负面报道数>正面报道数(满足任一条件)
if (negativeCount > positiveCount) {
isNegative = true;
//如果有在正面事件中发布负面稿件
} else if (specNegativeCount > 0) {
// 或满足三者复合条件:发布正面稿件>负面稿件&&正面稿件>=中性稿件&&月均参与正面事件数≥4.64
if (positiveCount > negativeCount && positiveCount >= neutralCount
&& (this.inEventCountMonthAverage(channel, EmotionEnum.POSITIVE.getName()) >= 4.64)) {
isPositive = true;
} else {
isNegative = true;
}
} else {
// 在负面事件中发布过正面稿件即满足
if (specPositiveCount > 0) {
isPositive = true;
// 或满足三者复合条件:发布正面稿件>负面稿件&&正面稿件>=中性稿件&&月均参与正面事件数≥4.64
} else if (positiveCount > negativeCount && positiveCount >= neutralCount
&& (this.inEventCountMonthAverage(channel, EmotionEnum.POSITIVE.getName()) >= 4.64)) {
isPositive = true;
}
}
}
//更新渠道指数,渠道等级,情感倾向并记录变化
this.updateChannel(channel, project, positiveCount, neutralCount, negativeCount, isPositive, isNegative, specPositiveCount,
specNegativeCount);
} catch (Exception e) {
log.error("calculateChannelEmotionIndex-", e);
}
return channel;
}
/**
* 更新渠道指数,渠道等级,情感倾向并记录变化
*
* @param channel 渠道
* @param project 项目
* @param positiveCount 正面稿件数
* @param neutralCount 中性稿件数
* @param negativeCount 负面稿件数
*/
private void updateChannel(Channel channel, Project project, long positiveCount, long neutralCount, long negativeCount, boolean isPositive,
boolean isNegative, long specPositiveCount, long specNegativeCount) {
double index;
int emotion;
// 负面渠道走负面渠道指数计算规则并更新
if (isNegative) {
//根据各指数计算最终渠道指数
index = this.negativeChannelIndexRule(channel, positiveCount, negativeCount, specNegativeCount, project.getNegativeChannelParams());
// TODO 添加或记录变化情况
// this.recordChannelChange(channel, rank, EmotionEnum.NEGATIVE.getState());
emotion = EmotionEnum.NEGATIVE.getState();
//正面渠道走正面渠道指数计算规则并更新
} else if (isPositive) {
//根据各指数计算最终渠道指数
index = this.positiveChannelIndexRule(channel, positiveCount, neutralCount, negativeCount, specPositiveCount, project.getPositiveChannelParams());
// TODO 添加或记录变化情况
// this.recordChannelChange(channel, rank, EmotionEnum.POSITIVE.getState());
emotion = EmotionEnum.POSITIVE.getState();
} else {
index = 0d;
//TODO 添加或记录变化情况
emotion = EmotionEnum.NEUTRAL.getState();
}
channel.setEmotionIndex(index);
channel.setEmotion(emotion);
}
/**
* 友好渠道计算指数
*
* @param channel 渠道信息
* @param positiveCount 正面稿件数
* @param neutralCount 中性稿件数
* @param negativeCount 负面稿件数
* @param positiveChannelMap 模块配置的正面渠道指数计算比例
* @return 计算指数
*/
private double positiveChannelIndexRule(Channel channel, long positiveCount, long neutralCount, long negativeCount, long specPositiveCount,
Map<String, Double> positiveChannelMap) {
//正面稿件数-中性稿件数
long value = positiveCount - neutralCount;
//正面-中性得分
double neutralScore = this.getNeutralScore(value);
//正面稿件数-负面稿件数
value = positiveCount - negativeCount;
//正面-负面得分
double negativeScore = this.getNegativeScore(value);
//正面事件
value = eventDao.getEventCount(new ChannelIndex(channel), Collections.singletonList(EmotionEnum.POSITIVE.getName()), null);
//正面事件得分
double positiveEventScore = this.getPositiveEventScore(value);
//特殊稿件
value = specPositiveCount;
//特殊稿件得分
double specialArticlesScore = this.getPositiveSpecialArticlesScore(value);
//经验评级
String experienceStr = channel.getExperienceLevel();
//经验评级得分
double experienceScore = this.getPositiveExperienceScore(experienceStr);
Double neutral = positiveChannelMap.get("neutral");
Double negative = positiveChannelMap.get("negative");
Double positiveEvent = positiveChannelMap.get("positiveEvent");
Double specialArticles = positiveChannelMap.get("specialArticles");
Double experience = positiveChannelMap.get("experience");
return neutralScore * neutral + negativeScore * negative + positiveEventScore * positiveEvent + specialArticlesScore * specialArticles + experienceScore * experience;
}
/**
* 获取经验评级得分
*
* @param experienceStr 经验评级
* @return 经验评级得分
*/
private double getPositiveExperienceScore(String experienceStr) {
double experienceScore = 0;
if (StringUtils.isNotEmpty(experienceStr)) {
if ("友好1级".equalsIgnoreCase(experienceStr)) {
experienceScore = 100;
} else if ("友好2级".equalsIgnoreCase(experienceStr)) {
experienceScore = 75;
} else if ("友好3级".equalsIgnoreCase(experienceStr)) {
experienceScore = 60;
} else if ("中性渠道".equalsIgnoreCase(experienceStr)) {
experienceScore = 30;
}
}
return experienceScore;
}
/**
* 获取特殊稿件得分
*
* @param value 得分值
* @return 特殊稿件得分
*/
private double getPositiveSpecialArticlesScore(long value) {
double specialArticlesScore;
// 占比0
if (value <= 0) {
specialArticlesScore = 0;
// 占比0-60
} else if (value <= 2) {
specialArticlesScore = proportionCompute(value, 0, 2, 0, 60);
// 占比60-100
} else if (value <= 4) {
specialArticlesScore = proportionCompute(value, 2, 4, 60, 100);
} else {
specialArticlesScore = 100;
}
return specialArticlesScore;
}
/**
* 获取正面事件得分
*
* @param value 得分值
* @return 正面事件得分
*/
private double getPositiveEventScore(long value) {
double positiveEventScore;
// 占比0
if (value <= 4) {
positiveEventScore = 0;
// 占比0-60
} else if (value <= 10) {
positiveEventScore = proportionCompute(value, 4.54, 10, 0, 60);
// 占比60-80
} else if (value <= 30) {
positiveEventScore = proportionCompute(value, 10, 30, 60, 80);
// 占比80-100
} else if (value <= 50) {
positiveEventScore = proportionCompute(value, 30, 50, 80, 100);
} else {
positiveEventScore = 100;
}
return positiveEventScore;
}
/**
* 获取正面-负面得分
*
* @param value 得分值
* @return 正面-负面得分
*/
private double getNegativeScore(long value) {
double negativeScore;
// 占比0
if (value < 0) {
negativeScore = 0;
// 占比0-60
} else if (value <= 5) {
negativeScore = proportionCompute(value, 0, 5.68, 0, 60);
// 占比60-70
} else if (value <= 19) {
negativeScore = proportionCompute(value, 5.68, 19, 60, 70);
} else {
negativeScore = this.getCommonScore(value);
}
return negativeScore;
}
/**
* 获取正面-中性得分
*
* @param value 得分值
* @return 正面-中性得分
*/
private double getNeutralScore(long value) {
double neutralScore;
// 占比0
if (value < 0) {
neutralScore = 0;
// 占比0-60
} else if (value <= 4) {
neutralScore = proportionCompute(value, 0, 4.39, 0, 60);
// 占比60-70
} else if (value <= 19) {
neutralScore = proportionCompute(value, 4.39, 19, 60, 70);
} else {
neutralScore = this.getCommonScore(value);
}
return neutralScore;
}
/**
* 公共计算正面-中性或正面-负面大于19得分情况
*
* @param value 得分值
* @return 正面-中性或正面-负面大于19得分情况
*/
private double getCommonScore(long value) {
double score;
// 占比70-80
if (value <= 49) {
score = proportionCompute(value, 19, 49, 70, 80);
// 占比80-90
} else if (value <= 99) {
score = proportionCompute(value, 49, 99, 80, 90);
// 占比90-100
} else if (value <= 150) {
score = proportionCompute(value, 99, 150, 90, 100);
} else {
score = 100;
}
return score;
}
/**
* 不友好渠道计算指数
*
* @param channel 渠道信息
* @param positiveCount 正面稿件数
* @param negativeCount 负面稿件数
* @param negativeChannelMap 项目模块配置的负面渠道指数计算比例
* @return 不友好渠道计算指数
*/
private double negativeChannelIndexRule(Channel channel, long positiveCount, long negativeCount, long specNegativeCount, Map<String, Double> negativeChannelMap) {
//负面稿件-正面稿件
long value = negativeCount - positiveCount;
//负面稿件数得分
double negativeArticlesScore = this.getNegativeArticlesScore(value);
//参与负面事件
value = eventDao.getEventCount(channel, Collections.singletonList(EmotionEnum.NEGATIVE.getName()), null);
//参与负面事件得分
double negativeEventScore = this.getNegativeEventScore(value);
//特殊稿件
value = specNegativeCount;
//特殊稿件得分
double specialArticlesScore = this.getNegativeSpecialArticlesScore(value);
String experienceStr = channel.getExperienceLevel();
//经验评级得分
double experienceScore = this.getNegativeExperienceScore(experienceStr);
Double negativeArticles = negativeChannelMap.get("negativeArticles");
Double negativeEvent = negativeChannelMap.get("negativeEvent");
Double specialArticles = negativeChannelMap.get("specialArticles");
Double experience = negativeChannelMap.get("experience");
return negativeArticlesScore * negativeArticles + negativeEventScore * negativeEvent + specialArticlesScore * specialArticles + experienceScore * experience;
}
/**
* 获取经验评级得分
*
* @param experienceStr 经验评级
* @return 经验评级得分
*/
private double getNegativeExperienceScore(String experienceStr) {
double experienceScore = 0;
if (StringUtils.isNotEmpty(experienceStr)) {
if ("敌对1级".equalsIgnoreCase(experienceStr)) {
experienceScore = 100;
} else if ("敌对2级".equalsIgnoreCase(experienceStr)) {
experienceScore = 75;
} else if ("敌对3级".equalsIgnoreCase(experienceStr)) {
experienceScore = 60;
} else if ("中性渠道".equalsIgnoreCase(experienceStr)) {
experienceScore = 30;
}
}
return experienceScore;
}
/**
* 获取特殊稿件得分
*
* @param value 得分值
* @return 特殊稿件得分
*/
private double getNegativeSpecialArticlesScore(long value) {
double specialArticlesScore;
// 占比0-60
if (value <= 4) {
specialArticlesScore = proportionCompute(value, 0, 4, 0, 60);
// 占比60-100
} else if (value <= 7) {
specialArticlesScore = proportionCompute(value, 4, 7, 60, 100);
} else {
specialArticlesScore = 100;
}
return specialArticlesScore;
}
/**
* 获取参与负面事件得分
*
* @param value 得分值
* @return 参与负面事件得分
*/
private double getNegativeEventScore(long value) {
double negativeEventScore;
// 占比0-60
if (value >= 0 && value <= 2) {
negativeEventScore = proportionCompute(value, 0, 2.16, 0, 60);
// 占比75-90
} else if (value < 4) {
negativeEventScore = proportionCompute(value, 2.16, 4, 75, 90);
} else {
negativeEventScore = 100;
}
return negativeEventScore;
}
/**
* 渠道计算占比公式
*
* @param index 得分值
* @param start 开始值
* @param end 结束值
* @param startPercent 开始得分值
* @param endPercent 结束得分值
* @return 得分值
*/
private double proportionCompute(double index, double start, double end, int startPercent, int endPercent) {
return (index - start) * (endPercent - startPercent) / (end - start) + startPercent;
}
/**
* 获取负面-正面稿件数得分
*
* @param value 得分值
* @return 负面-正面稿件数得分
*/
private double getNegativeArticlesScore(long value) {
double negativeArticlesScore;
// 占比0
if (value < 0) {
negativeArticlesScore = 0;
// 占比30-60
} else if (value <= 2) {
negativeArticlesScore = proportionCompute(value, 0, 2.31, 30, 60);
// 占比70-90
} else if (value <= 4) {
negativeArticlesScore = proportionCompute(value, 2.31, 4, 70, 90);
// 占比90-100
} else if (value <= 5) {
negativeArticlesScore = proportionCompute(value, 4, 5, 90, 100);
} else {
negativeArticlesScore = 100;
}
return negativeArticlesScore;
}
private double inEventCountMonthAverage(Channel channel, String eventEmotion) {
long eventCount = eventDao.getEventCount(new ChannelIndex(channel), Collections.singletonList(eventEmotion), null);
Period periodDays = new Period(channel.getCTime(), System.currentTimeMillis(), PeriodType.months());
return (double) eventCount / periodDays.getMonths();
}
private Long markCountByEmotion(Channel channel, String emotion) throws IOException {
......@@ -740,14 +1184,13 @@ public class ChannelServiceImpl implements ChannelService {
return Pair.of(total, res);
}
private Pair<Long, JSONObject> getEventCount(Long startTime, Long endTime, String projectId, String contendId, Channel channel) {
private Pair<Long, JSONObject> getEventCount(Long startTime, Long endTime, Channel channel) {
JSONObject res = new JSONObject();
String linkedGroupId = projectService.getProjectByContendId(contendId).getBrandLinkedGroupId();
Map<Long, List<Event>> eventCount;
if (endTime - startTime > Constant.ONE_MONTH) {
eventCount = eventDao.getEventMonth(new ChannelIndex(projectId, linkedGroupId, channel), startTime, endTime);
eventCount = eventDao.getEventMonth(new ChannelIndex(channel), startTime, endTime);
} else {
eventCount = eventDao.getEventDay(new ChannelIndex(projectId, linkedGroupId, channel), startTime, endTime);
eventCount = eventDao.getEventDay(new ChannelIndex(channel), startTime, endTime);
}
// 事件部分
long positiveEventCount = 0;
......@@ -782,12 +1225,11 @@ public class ChannelServiceImpl implements ChannelService {
}
private List<JSONObject> spreadingTendEvent(Long startTime, Long endTime, Channel channel, String projectId, String contendId, String timePattern) {
String linkedGroupId = projectService.getProjectByContendId(contendId).getBrandLinkedGroupId();
Map<Long, List<Event>> eventCount = completeTimes(startTime, endTime, timePattern);
if (Constant.MONTH_PATTERN.equals(timePattern)) {
eventCount.putAll(eventDao.getEventMonth(new ChannelIndex(projectId, linkedGroupId, channel), startTime, endTime));
eventCount.putAll(eventDao.getEventMonth(new ChannelIndex(channel), startTime, endTime));
} else {
eventCount.putAll(eventDao.getEventDay(new ChannelIndex(projectId, linkedGroupId, channel), startTime, endTime));
eventCount.putAll(eventDao.getEventDay(new ChannelIndex(channel), startTime, endTime));
}
return eventCount.entrySet().stream().sorted(Comparator.comparingLong(Map.Entry::getKey)).map(e -> {
JSONObject spreadJson = new JSONObject();
......@@ -957,8 +1399,16 @@ public class ChannelServiceImpl implements ChannelService {
return res;
}
private long judgeSpecEventCount(String channelId, List<Integer> eventEmotions, int articleEmotion) {
return 0;
private String getChannelEmotionRank(Double emotionIndex, int emotion) {
int rank;
if (emotionIndex >= 80) {
rank = 1;
} else if (emotionIndex >= 60) {
rank = 2;
} else {
rank = 3;
}
return rank + "级" + ChannelEmotion.getNameFromState(emotion);
}
}
......@@ -138,7 +138,9 @@ public class CustomEventServiceImpl implements CustomEventService {
ExceptionCast.cast(CommonCodeEnum.FAIL.message("该事件数据更新中,无法修改该事件信息!"));
}
// 修改自定义事件及清空历史数据
customEventDao.updateOne(customEvent);
Update update = Update.update("title", customEventDTO.getTitle()).set("startTime", customEventDTO.getStartTime()).
set("endTime", customEventDTO.getEndTime()).set("keywords", customEventDTO.getKeywords());
customEventDao.updateOneByIdWithField(customEvent.getId(), update);
customEventDataDao.deleteOneByQuery(Query.query(Criteria.where("customEventId").is(customEventDTO.getId())));
// this.saveCustomEvent(customEventDTO);
}
......
package com.zhiwei.brandkbs2.service.impl;
import com.google.common.collect.Lists;
import com.zhiwei.brandkbs2.dao.EventDao;
import com.zhiwei.brandkbs2.dao.EventDataDao;
import com.zhiwei.brandkbs2.pojo.Event;
......@@ -14,6 +15,7 @@ import org.joda.time.PeriodType;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
......@@ -70,17 +72,19 @@ public class EventDataServiceImpl implements EventDataService {
}
private void updateEventData(Event event, List<EventData> eventDataList) {
long update = 0;
String keyword = event.getKeyword();
// 删除历史数据
eventDataDao.deleteByEventId(event.getId(), event.getCollectionName());
List<EventData> insertList = new ArrayList<>();
for (EventData data : eventDataList) {
// 关键词筛选
if (Tools.containsKeyword(Arrays.asList(keyword.split(keyword.contains(",") ? "," : "\\|")), (data.getTitle() + data.getContent()).toLowerCase())) {
eventDataDao.insertOne(data);
update++;
insertList.add(data);
}
}
log.info("analysisEvent-eventId:{},更新事件数据完毕,实际更新:{}条", event.getId(), update);
Lists.partition(insertList, 1000).forEach(list -> {
eventDataDao.insertMany(list, event.getCollectionName());
});
log.info("analysisEvent-eventId:{},更新事件数据完毕,实际更新:{}条", event.getId(), insertList.size());
}
}
......@@ -33,6 +33,7 @@ import com.zhiwei.brandkbs2.service.EventDataService;
import com.zhiwei.brandkbs2.service.EventService;
import com.zhiwei.brandkbs2.service.ProjectService;
import com.zhiwei.brandkbs2.util.MongoUtil;
import com.zhiwei.brandkbs2.util.RedisUtil;
import com.zhiwei.brandkbs2.util.Tools;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
......@@ -106,6 +107,9 @@ public class EventServiceImpl implements EventService {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Resource
private RedisUtil redisUtil;
// private static final Pattern PATTERN = Pattern.compile("[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]");
@Override
......@@ -268,10 +272,11 @@ public class EventServiceImpl implements EventService {
ExceptionCast.cast(CommonCodeEnum.INVALID_PARAM);
}
JSONObject res = new JSONObject();
String projectId = UserThreadLocal.getProjectId();
List<JSONObject> infos = new ArrayList<>();
boolean finish = true;
for (String eventId : eventIds) {
String redisKey = RedisKeyPrefix.eventAnalysisProgress(eventId);
String redisKey = RedisKeyPrefix.eventAnalysisProgress(eventId, projectId);
String progress = stringRedisTemplate.opsForValue().get(redisKey);
if (null == progress) {
progress = "100";
......@@ -351,6 +356,7 @@ public class EventServiceImpl implements EventService {
Event event = getEventById(eventId);
Query query = new Query(Criteria.where("eventId").is(eventId));
long count = eventDataDao.count(query, event.getCollectionName());
eventDataDao.addSort(query, "{\"time\":\"ascend\"}");
mongoUtil.start(page, size, query);
//根据事件ID获取所有稿件信息
List<EventData> eventDataList = eventDataDao.findList(query, event.getCollectionName());
......@@ -449,19 +455,22 @@ public class EventServiceImpl implements EventService {
@Override
public void analysisEvents(List<String> eventIds) {
ApplicationProjectListener.getThreadPool().execute(() -> eventIds.forEach(eventId -> {
String redisKey = RedisKeyPrefix.eventAnalysisProgress(eventId);
// ApplicationProjectListener.getThreadPool().execute(() -> eventIds.forEach(eventId -> {
eventIds.forEach(eventId -> {
String redisKey = null;
try {
Event event = getEventById(eventId);
stringRedisTemplate.opsForValue().set(redisKey, "0");
redisKey = RedisKeyPrefix.eventAnalysisProgress(eventId, event.getProjectId());
redisUtil.set(redisKey, "0");
//更新事件信息
eventDataService.analysisEvent(event);
stringRedisTemplate.opsForValue().set(redisKey, "100");
redisUtil.set(redisKey, "100");
} catch (Exception e) {
log.error("事件id:{}更新失败", eventId, e);
stringRedisTemplate.opsForValue().set(redisKey, "-1");
redisUtil.set(redisKey, "-1");
}
}));
});
// }));
}
@Override
......@@ -544,14 +553,12 @@ public class EventServiceImpl implements EventService {
// 数据
List<Event> eventList = eventDao.findList(query);
// vo封装
List<EventListInfoVO> eventListInfoVOList = eventList.stream()
.map(event -> {
List<EventListInfoVO> eventListInfoVOList = eventList.stream().map(event -> {
EventListInfoVO vo = new EventListInfoVO(event);
// 放入首发稿件
vo.setFirstEventData(eventDataDao.findFirstData(event.getId(), event.getCollectionName()));
return vo;
})
.collect(Collectors.toList());
}).collect(Collectors.toList());
PageVO<EventListInfoVO> pageVo = PageVO.createPageVo(total, page, pageSize, eventListInfoVOList);
return pageVo;
}
......@@ -615,8 +622,7 @@ public class EventServiceImpl implements EventService {
List<EventTopArticlesAnalysis> eventTopArticlesAnalyses = eventTopArticlesAnalysisDao.findList(query);
switch (type) {
case "按时间":
Map<String, List<EventTopArticlesAnalysisVO>> collect = eventTopArticlesAnalyses.stream()
.map(eventTopArticlesAnalysis -> {
Map<String, List<EventTopArticlesAnalysisVO>> collect = eventTopArticlesAnalyses.stream().map(eventTopArticlesAnalysis -> {
boolean highLight = Objects.equals(aggTitle, eventTopArticlesAnalysis.getAggTitle());
return new EventTopArticlesAnalysisVO(eventTopArticlesAnalysis, highLight);
}).collect(Collectors.groupingBy(EventTopArticlesAnalysisVO::getTimePoint));
......@@ -641,8 +647,7 @@ public class EventServiceImpl implements EventService {
String year = Tools.DF_YEAR.format(new Date());
int yearInt = Integer.parseInt(year);
List<Integer> years = Arrays.asList(yearInt, yearInt - 1, yearInt - 2);
List<JSONObject> collect = years.stream()
.map(yearInfo -> {
List<JSONObject> collect = years.stream().map(yearInfo -> {
JSONObject result = new JSONObject();
try {
String yearStr = String.valueOf(yearInfo);
......@@ -653,8 +658,7 @@ public class EventServiceImpl implements EventService {
throw new RuntimeException(e);
}
return result;
})
.collect(Collectors.toList());
}).collect(Collectors.toList());
return collect;
}
......@@ -684,14 +688,12 @@ public class EventServiceImpl implements EventService {
JSONObject priBrandResult = new JSONObject();
priBrandResult.put("id", projectVO.getBrandLinkedGroupId());
priBrandResult.put("name", projectVO.getBrandLinkedGroup());
List<JSONObject> resultList = projectVO.getContendList().stream()
.map(contend -> {
List<JSONObject> resultList = projectVO.getContendList().stream().map(contend -> {
JSONObject result = new JSONObject();
result.put("id", contend.getBrandLinkedGroupId());
result.put("name", contend.getBrandName());
return result;
})
.collect(Collectors.toList());
}).collect(Collectors.toList());
resultList.add(0, priBrandResult);
return resultList;
}
......
......@@ -77,7 +77,7 @@ import java.util.stream.Collectors;
public class MarkDataServiceImpl implements MarkDataService {
private static final Logger log = LogManager.getLogger(MarkDataServiceImpl.class);
private static final String[] EVENT_FETCH_SOURCE = new String[]{"ind_full_text", "c5", "real_source", "source", "mtime", "time", "url", "mtag"};
private static final String[] EVENT_FETCH_SOURCE = new String[]{"ind_full_text", "c5", "real_source", "source", "mtime", "time", "url", "mtag", "foreign", "brandkbs_mark_cache_maps"};
@Resource(name = "projectServiceImpl")
private ProjectService projectService;
......@@ -212,7 +212,7 @@ public class MarkDataServiceImpl implements MarkDataService {
for (AggreeResult aggreeResult : fatherList) {
List<MarkFlowEntity> markFlowEntities = new ArrayList<>();
MarkFlowEntity instance = new MarkFlowEntity(aggreeResult.getData());
instance.setInfo(markFlowService.createMarkFlowInfo(aggreeResult.getData(), dto.getProjectId(), dto.getLinkedGroupId()));
instance.setInfo(markFlowService.createMarkFlowInfo(aggreeResult.getData(), dto.getProjectId(), dto.getContendId()));
markFlowEntities.add(instance);
// 添加父标题集下的子标题集
// markFlowEntities.addAll(fatherMap.get(aggreeResult.getFatherId()).stream().map(sonResult -> new MarkFlowEntity(sonResult.getData())).collect(Collectors.toList()));
......@@ -1082,7 +1082,7 @@ public class MarkDataServiceImpl implements MarkDataService {
private List<MarkFlowEntity> getMarkFlowEntity(MarkSearchDTO markSearchDTO, SearchHits searchHits) {
String projectId = UserThreadLocal.getProjectId();
String linkedGroupId = markSearchDTO.getLinkedGroupId();
String contendId = markSearchDTO.getContendId();
// 重复消息折叠
if (markSearchDTO.isFold()) {
Map<String, List<Map<String, Object>>> collect = Arrays.stream(searchHits.getHits()).map(SearchHit::getSourceAsMap).collect(Collectors.groupingBy(map -> {
......@@ -1090,14 +1090,14 @@ public class MarkDataServiceImpl implements MarkDataService {
String title = baseMap.getTitleNullOptionalContent();
return Tools.filterSpecialCharacter(title) + baseMap.getTypeB().encode();
}));
return collect.values().stream().map(list -> MarkFlowEntity.getFoldInstance(list.stream().map(map -> getMarkFlowEntity(map, projectId, linkedGroupId)).collect(Collectors.toList()))).collect(Collectors.toList());
return collect.values().stream().map(list -> MarkFlowEntity.getFoldInstance(list.stream().map(map -> getMarkFlowEntity(map, projectId, contendId)).collect(Collectors.toList()))).collect(Collectors.toList());
}
return Arrays.stream(searchHits.getHits()).map(hit -> getMarkFlowEntity(hit.getSourceAsMap(), projectId, linkedGroupId)).collect(Collectors.toList());
return Arrays.stream(searchHits.getHits()).map(hit -> getMarkFlowEntity(hit.getSourceAsMap(), projectId, contendId)).collect(Collectors.toList());
}
private MarkFlowEntity getMarkFlowEntity(Map<String, Object> map, String projectId, String linkedGroupId) {
private MarkFlowEntity getMarkFlowEntity(Map<String, Object> map, String projectId, String contendId) {
MarkFlowEntity instance = new MarkFlowEntity(new JSONObject(map));
instance.setInfo(markFlowService.createMarkFlowInfo(new JSONObject(map), projectId, linkedGroupId));
instance.setInfo(markFlowService.createMarkFlowInfo(new JSONObject(map), projectId, contendId));
return instance;
}
......
......@@ -45,9 +45,9 @@ public class MarkFlowServiceImpl implements MarkFlowService {
RedisUtil redisUtil;
@Override
public JSONObject createMarkFlowInfo(JSONObject json, String projectId, String linkedGroupId) {
public JSONObject createMarkFlowInfo(JSONObject json, String projectId, String contendId) {
JSONObject resultInfo = createInfoWithEmotion(json);
resultInfo.put("sourceDetails", getSourceDetails(json, projectId, linkedGroupId));
resultInfo.put("sourceDetails", getSourceDetails(json, projectId, contendId));
return resultInfo;
}
......@@ -106,7 +106,7 @@ public class MarkFlowServiceImpl implements MarkFlowService {
return info;
}
private JSONObject getSourceDetails(JSONObject tJson, String projectId, String linkedGroupId) {
private JSONObject getSourceDetails(JSONObject tJson, String projectId, String contendId) {
JSONObject sourceDetails = new JSONObject();
String source = tJson.getString(GenericAttribute.ES_SOURCE);
// 是否原创
......@@ -125,14 +125,15 @@ public class MarkFlowServiceImpl implements MarkFlowService {
// 渠道标签
sourceDetails.put("channelTag", channelTagDao.getTagByChannelName(source));
// 渠道倾向及id
Channel channel = channelDao.queryUnique(ChannelIndex.createChannelIndex(tJson, projectId, linkedGroupId));
Channel channel = channelDao.queryUnique(ChannelIndex.createChannelIndex(tJson, projectId, contendId));
if (null != channel) {
sourceDetails.put("channelId", channel.getId());
sourceDetails.put("channelEmotion", ChannelEmotion.getNameFromState(channel.getEmotion()));
} else {
List<Map<String, Object>> cacheMaps = (List<Map<String, Object>>) tJson.get(GenericAttribute.ES_BRANDKBS_CACHE_MAPS);
if (null != cacheMaps) {
Map<String, Object> hitMap = cacheMaps.stream().filter(map -> projectId.equals(map.get("project_id")) && linkedGroupId.equals(map.get("linked_group_id"))).findAny().orElse(Collections.emptyMap());
Map<String, Object> hitMap =
cacheMaps.stream().filter(map -> projectId.equals(map.get("project_id")) && contendId.equals(map.get("contend_id"))).findAny().orElse(Collections.emptyMap());
sourceDetails.put("channelId", hitMap.get("channel_id"));
sourceDetails.put("channelEmotion", ChannelEmotion.getNameFromState(hitMap.get("channel_emotion")));
}
......
......@@ -100,6 +100,11 @@ public class ProjectServiceImpl implements ProjectService {
}
@Override
public Project getProjectById(String pid) {
return projectDao.findOneById(pid);
}
@Override
public void updateProject(ProjectVO projectVO) {
Project existsProject = projectDao.findOneById(projectVO.getId());
if (Objects.isNull(existsProject)) {
......
......@@ -7,10 +7,7 @@ import com.zhiwei.brandkbs2.es.ChannelEsDao;
import com.zhiwei.brandkbs2.es.EsClientDao;
import com.zhiwei.brandkbs2.listener.ApplicationProjectListener;
import com.zhiwei.brandkbs2.pojo.*;
import com.zhiwei.brandkbs2.service.BrandkbsTaskService;
import com.zhiwei.brandkbs2.service.ProjectService;
import com.zhiwei.brandkbs2.service.ReportService;
import com.zhiwei.brandkbs2.service.TaskService;
import com.zhiwei.brandkbs2.service.*;
import com.zhiwei.brandkbs2.util.Tools;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.tuple.Pair;
......@@ -47,8 +44,8 @@ public class TaskServiceImpl implements TaskService {
@Resource(name = "channelDao")
ChannelDao channelDao;
@Resource(name = "eventDataDao")
EventDataDao eventDataDao;
@Resource(name = "channelServiceImpl")
ChannelService channelService;
@Resource(name = "brandkbsTaskDao")
BrandkbsTaskDao brandkbsTaskDao;
......@@ -114,10 +111,10 @@ public class TaskServiceImpl implements TaskService {
Channel channel = fidChannel.get(fid);
if (null == channel) {
channel = Channel.createFromChannelIndexRecord(entry.getKey(), entry.getValue());
insertList.add(channel);
insertList.add(channelService.calculateChannelEmotionIndex(channel));
} else {
channel.setRecord(entry.getValue());
channelDao.updateOne(channel);
channelDao.updateOne(channelService.calculateChannelEmotionIndex(channel));
}
// 设置查询数值
entry.getKey().setChannelInfo(channel);
......@@ -161,9 +158,7 @@ public class TaskServiceImpl implements TaskService {
}
}
log.info("渠道统计-渠道总计-查询更新结束,开始批量入库");
ListUtils.partition(insertList, 1000).forEach(list -> {
channelDao.insertMany(list);
});
ListUtils.partition(insertList, 1000).forEach(list -> channelDao.insertMany(list));
log.info("渠道统计-渠道总计-录入完毕,新增渠道{}条,更新渠道{}条", insertList.size(), total - insertList.size());
}
......
......@@ -40,6 +40,9 @@ public class RedisUtil {
}
public void set(String key, String value) {
if (null == key) {
return;
}
stringRedisTemplate.opsForValue().set(key, value);
}
......
......@@ -171,6 +171,9 @@ public class Tools {
* @return 过滤特殊字符后的字符串
*/
public static String filterSpecialCharacter(String str) {
if (null == str) {
return null;
}
return PATTERN.matcher(str).replaceAll("");
}
......@@ -786,4 +789,18 @@ public class Tools {
return Collections.emptyMap();
}
public static <T> Map<Long, T> sortTimeKeyMap(Map<Long, T> map, boolean isDesc) {
Map<Long, T> res = new LinkedHashMap<>();
List<Map.Entry<Long, T>> sortKey = map.entrySet().stream().sorted((x, y) -> {
if (isDesc) {
return Long.compare(y.getKey(), x.getKey());
}
return Long.compare(x.getKey(), y.getKey());
}).collect(Collectors.toList());
for (Map.Entry<Long, T> longTEntry : sortKey) {
res.put(longTEntry.getKey(), longTEntry.getValue());
}
return res;
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment