Commit fddf6786 by shenjunjie

Merge branch 'feature' into 'dev'

Feature

See merge request !22
parents 80d39e08 4e60b856
...@@ -31,7 +31,7 @@ public class RedisKeyPrefix { ...@@ -31,7 +31,7 @@ public class RedisKeyPrefix {
* 自定义事件相关缓存 * 自定义事件相关缓存
*/ */
public static final String CUSTOM_EVENT_LIST = "BRANDKBS:CUSTOM_EVENT:LIST:"; public static final String CUSTOM_EVENT_LIST = "BRANDKBS:CUSTOM_EVENT:LIST:";
public static final String CUSTOM_EVENT_ANALYZE_SHARE = "BRANDKBS:CUSTOM_EVENT:SHARE"; public static final String CUSTOM_EVENT_ANALYZE_SHARE = "BRANDKBS:CUSTOM_EVENT:SHARE:";
public static final String CUSTOM_EVENT_ANALYZE = "BRANDKBS:CUSTOM_EVENT:ANALYZE:"; public static final String CUSTOM_EVENT_ANALYZE = "BRANDKBS:CUSTOM_EVENT:ANALYZE:";
/** /**
...@@ -60,10 +60,24 @@ public class RedisKeyPrefix { ...@@ -60,10 +60,24 @@ public class RedisKeyPrefix {
*/ */
private static final String EVENT_ANALYZE_PROGRESS = "BRANDKBS:EVENT:ANALYZE:PROGRESS:"; private static final String EVENT_ANALYZE_PROGRESS = "BRANDKBS:EVENT:ANALYZE:PROGRESS:";
/**
* 竞品库-获取竞品对比舆情解读数据(PC
*/
public static final String INDEX_COMPARE_SUMMARY_PC = "BRANDKBS:CONTEND:COMPARESUMMARY:PC:";
/**
* 竞品库-获取竞品对比传播分析数据
*/
public static final String INDEX_COMPARE_ANALYZE = "BRANDKBS:CONTEND:COMPAREANALYZE:";
public static String eventAnalysisProgress(String eventId, String projectId) { public static String eventAnalysisProgress(String eventId, String projectId) {
return RedisKeyPrefix.generateRedisKey(RedisKeyPrefix.EVENT_ANALYZE_PROGRESS, projectId, eventId); return RedisKeyPrefix.generateRedisKey(RedisKeyPrefix.EVENT_ANALYZE_PROGRESS, projectId, eventId);
} }
public static String eventAnalysisProgress(String eventId) {
return RedisKeyPrefix.generateRedisKey(RedisKeyPrefix.EVENT_ANALYZE_PROGRESS, UserThreadLocal.getProjectId(), eventId);
}
public static String yuqingProgressKey(String linkedGroupId) { public static String yuqingProgressKey(String linkedGroupId) {
return yuqingProgressKey(UserThreadLocal.getProjectId(), linkedGroupId); return yuqingProgressKey(UserThreadLocal.getProjectId(), linkedGroupId);
} }
......
...@@ -51,4 +51,9 @@ public class Constant { ...@@ -51,4 +51,9 @@ public class Constant {
return -1L; return -1L;
} }
/**
* 主品牌默认竞品ID
*/
public static final String PRIMARY_CONTENDID = "0";
} }
...@@ -84,9 +84,9 @@ public class TaskPoolConfig { ...@@ -84,9 +84,9 @@ public class TaskPoolConfig {
log.info("start taskServiceExecutor"); log.info("start taskServiceExecutor");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 配置核心线程数 // 配置核心线程数
executor.setCorePoolSize(8); executor.setCorePoolSize(16);
// 配置最大线程数 // 配置最大线程数
executor.setMaxPoolSize(16); executor.setMaxPoolSize(32);
// 配置线程池中的线程的名称前缀 // 配置线程池中的线程的名称前缀
executor.setThreadNamePrefix("taskServiceExecutor-"); executor.setThreadNamePrefix("taskServiceExecutor-");
// rejection-policy:当pool已经达到max size的时候,如何处理新任务 // rejection-policy:当pool已经达到max size的时候,如何处理新任务
......
package com.zhiwei.brandkbs2.controller.app;
import com.zhiwei.brandkbs2.auth.Auth;
import com.zhiwei.brandkbs2.controller.BaseController;
import com.zhiwei.brandkbs2.enmus.RoleEnum;
import com.zhiwei.brandkbs2.model.ResponseResult;
import com.zhiwei.brandkbs2.pojo.dto.MarkSearchDTO;
import com.zhiwei.brandkbs2.service.MarkDataService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.io.IOException;
import java.text.ParseException;
import java.util.List;
/**
* @ClassName AppContendController
* @Description 提供前台竞品库相关信息展示
* @author cjz
* @date 2022-08-09 10:22
*/
@RestController
@RequestMapping("/app/contend")
@Api(tags = "前台竞品库展示接口",description = "提供前台竞品库相关信息展示")
@Auth(role = RoleEnum.CUSTOMER)
public class AppContendController extends BaseController {
@Resource(name = "markDataServiceImpl")
MarkDataService markDataService;
@ApiOperation("竞品库-竞品舆情-搜索条件")
@GetMapping("/searchCriteria")
public ResponseResult getContendSearchCriteria(@RequestParam(required = false) String linkedGroupId) {
return ResponseResult.success(markDataService.getContendSearchCriteria(linkedGroupId));
}
@ApiOperation("竞品库-竞品舆情-搜索结果列表")
@GetMapping("/list")
public ResponseResult getContendSearchList(@RequestBody MarkSearchDTO markSearchDTO) throws IOException {
return ResponseResult.success(markDataService.getContendSearchList(markSearchDTO));
}
@ApiOperation("竞品库-竞品分析-舆情总结页面")
@GetMapping("/summary")
public ResponseResult getSummary(@RequestBody MarkSearchDTO markSearchDTO) throws IOException {
return ResponseResult.success(markDataService.getContendSummary(markSearchDTO, true));
}
@ApiOperation("竞品库-竞品对比-传播分析页面")
@GetMapping("/spread/analyze")
public ResponseResult getSpreadAnalyze(@RequestBody MarkSearchDTO markSearchDTO) throws IOException {
return ResponseResult.success(markDataService.getContendSpreadAnalyze(markSearchDTO, 5, true));
}
}
...@@ -26,8 +26,6 @@ import org.springframework.web.client.RestTemplate; ...@@ -26,8 +26,6 @@ import org.springframework.web.client.RestTemplate;
@Api(tags = "前台危机展示接口",description = "提供前台危机相关信息展示") @Api(tags = "前台危机展示接口",description = "提供前台危机相关信息展示")
@Auth(role = RoleEnum.CUSTOMER) @Auth(role = RoleEnum.CUSTOMER)
public class AppCrisisController extends BaseController { public class AppCrisisController extends BaseController {
@Value("${crisis.search.url}")
private String crisisSearchUrl;
@Value("${crisis.searchTags.url}") @Value("${crisis.searchTags.url}")
private String crisisTagsUrl; private String crisisTagsUrl;
...@@ -47,16 +45,6 @@ public class AppCrisisController extends BaseController { ...@@ -47,16 +45,6 @@ public class AppCrisisController extends BaseController {
@Autowired @Autowired
private RestTemplate restTemplate; private RestTemplate restTemplate;
@ApiOperation("危机库-查危机")
@GetMapping("/crisisSearch")
public ResponseResult crisisSearch(@RequestParam(value = "page",defaultValue = "1") Integer page,
@RequestParam(value = "pageSize",defaultValue = "3") Integer pageSize,
@RequestParam("keyword") String keyword){
ResponseEntity<String> responseEntity = restTemplate.getForEntity(crisisSearchUrl, String.class, page, pageSize, keyword);
Object data = JSON.parseObject(responseEntity.getBody()).get("data");
return ResponseResult.success(data);
}
@ApiOperation("危机库-通过标签查危机") @ApiOperation("危机库-通过标签查危机")
@GetMapping("/crisisTags") @GetMapping("/crisisTags")
public ResponseResult crisisTags(@RequestParam(value = "page",defaultValue = "1") Integer page, public ResponseResult crisisTags(@RequestParam(value = "page",defaultValue = "1") Integer page,
......
...@@ -57,14 +57,14 @@ public class AppEventController extends BaseController { ...@@ -57,14 +57,14 @@ public class AppEventController extends BaseController {
@ApiOperation("前台事件库-品牌事件库") @ApiOperation("前台事件库-品牌事件库")
@GetMapping("/list") @GetMapping("/list")
public ResponseResult getEventList(@RequestParam(value = "brandLinkedGroupId", required = false) String linkedGroupId, public ResponseResult getEventList(@RequestParam(value = "contendId", defaultValue = "0") String contendId,
@RequestParam(value = "emotion", defaultValue = "全部") String emotion, @RequestParam(value = "emotion", defaultValue = "全部") String emotion,
@RequestParam(value = "startTime", required = false) Long startTime, @RequestParam(value = "startTime", required = false) Long startTime,
@RequestParam(value = "endTime", required = false) Long endTime, @RequestParam(value = "endTime", required = false) Long endTime,
@RequestParam(value = "page", defaultValue = "1") int page, @RequestParam(value = "page", defaultValue = "1") int page,
@RequestParam(value = "pageSize", defaultValue = "50") int pageSize, @RequestParam(value = "pageSize", defaultValue = "50") int pageSize,
@RequestParam(value = "sorter", required = false) String sorter) { @RequestParam(value = "sorter", required = false) String sorter) {
return ResponseResult.success(eventService.getEventList(linkedGroupId, emotion, startTime, endTime, page, pageSize, sorter)); return ResponseResult.success(eventService.getEventList(contendId, emotion, startTime, endTime, page, pageSize, sorter));
} }
@ApiOperation("前台事件库-事件详情-基础信息") @ApiOperation("前台事件库-事件详情-基础信息")
...@@ -101,7 +101,7 @@ public class AppEventController extends BaseController { ...@@ -101,7 +101,7 @@ public class AppEventController extends BaseController {
@ApiOperation("前台事件库-全网事件库-搜索") @ApiOperation("前台事件库-全网事件库-搜索")
@GetMapping("/getWholeNetworkEvents") @GetMapping("/getWholeNetworkEvents")
public ResponseResult getWholeNetworkEvents(@RequestParam("keyword") String keyword, public ResponseResult getWholeNetworkEvents(@RequestParam("keyword") String keyword,
@RequestParam(value = "page",defaultValue = "1") Integer page){ @RequestParam(value = "page", defaultValue = "1") Integer page) {
String name = keyword.trim(); String name = keyword.trim();
ResponseEntity<String> responseEntity = restTemplate.getForEntity(getEfSearchUrl, String.class, name, page); ResponseEntity<String> responseEntity = restTemplate.getForEntity(getEfSearchUrl, String.class, name, page);
JSONObject jsonObject = JSON.parseObject(responseEntity.getBody()); JSONObject jsonObject = JSON.parseObject(responseEntity.getBody());
...@@ -110,7 +110,7 @@ public class AppEventController extends BaseController { ...@@ -110,7 +110,7 @@ public class AppEventController extends BaseController {
@ApiOperation("前台事件库-全网事件库-搜索条件") @ApiOperation("前台事件库-全网事件库-搜索条件")
@GetMapping("/getWholeNetworkSearchCriteria") @GetMapping("/getWholeNetworkSearchCriteria")
public ResponseResult getWholeNetworkSearchCriteria(){ public ResponseResult getWholeNetworkSearchCriteria() {
ResponseEntity<String> responseEntity = restTemplate.getForEntity(getEfSearchCriteriaUrl, String.class); ResponseEntity<String> responseEntity = restTemplate.getForEntity(getEfSearchCriteriaUrl, String.class);
JSONObject jsonObject = JSON.parseObject(responseEntity.getBody()); JSONObject jsonObject = JSON.parseObject(responseEntity.getBody());
return ResponseResult.success(jsonObject); return ResponseResult.success(jsonObject);
...@@ -121,7 +121,7 @@ public class AppEventController extends BaseController { ...@@ -121,7 +121,7 @@ public class AppEventController extends BaseController {
public ResponseResult getWholeNetworkEventsList(@RequestParam(value = "firstType", required = false, defaultValue = "") String firstType, public ResponseResult getWholeNetworkEventsList(@RequestParam(value = "firstType", required = false, defaultValue = "") String firstType,
@RequestParam(value = "start", required = false, defaultValue = "0") long start, @RequestParam(value = "start", required = false, defaultValue = "0") long start,
@RequestParam(value = "end", required = false, defaultValue = "0") long end, @RequestParam(value = "end", required = false, defaultValue = "0") long end,
@RequestParam(value = "page", required = false, defaultValue = "1") int page){ @RequestParam(value = "page", required = false, defaultValue = "1") int page) {
ResponseEntity<String> responseEntity = restTemplate.getForEntity(getFilterNewUrl, String.class, firstType, start, end, page); ResponseEntity<String> responseEntity = restTemplate.getForEntity(getFilterNewUrl, String.class, firstType, start, end, page);
JSONObject jsonObject = JSON.parseObject(responseEntity.getBody()); JSONObject jsonObject = JSON.parseObject(responseEntity.getBody());
return ResponseResult.success(jsonObject); return ResponseResult.success(jsonObject);
...@@ -129,7 +129,7 @@ public class AppEventController extends BaseController { ...@@ -129,7 +129,7 @@ public class AppEventController extends BaseController {
@ApiOperation("前台事件库-全网事件库-得到验证码") @ApiOperation("前台事件库-全网事件库-得到验证码")
@GetMapping("/getWholeNetworkCaptcha") @GetMapping("/getWholeNetworkCaptcha")
public ResponseResult getWholeNetworkCaptcha(){ public ResponseResult getWholeNetworkCaptcha() {
ResponseEntity<String> responseEntity = restTemplate.getForEntity(efCaptchaUrl, String.class); ResponseEntity<String> responseEntity = restTemplate.getForEntity(efCaptchaUrl, String.class);
JSONObject jsonObject = JSON.parseObject(responseEntity.getBody()); JSONObject jsonObject = JSON.parseObject(responseEntity.getBody());
return ResponseResult.success(jsonObject); return ResponseResult.success(jsonObject);
...@@ -138,7 +138,7 @@ public class AppEventController extends BaseController { ...@@ -138,7 +138,7 @@ public class AppEventController extends BaseController {
@ApiOperation("前台事件库-全网事件库-校验验证码") @ApiOperation("前台事件库-全网事件库-校验验证码")
@GetMapping("/checkWholeNetworkCaptcha") @GetMapping("/checkWholeNetworkCaptcha")
public ResponseResult checkWholeNetworkCaptcha(@RequestParam(value = "id", required = false, defaultValue = "") String id, public ResponseResult checkWholeNetworkCaptcha(@RequestParam(value = "id", required = false, defaultValue = "") String id,
@RequestParam(value = "captcha", required = false, defaultValue = "") String captcha){ @RequestParam(value = "captcha", required = false, defaultValue = "") String captcha) {
ResponseEntity<String> responseEntity = restTemplate.getForEntity(efCheckCaptchaUrl, String.class, id, captcha); ResponseEntity<String> responseEntity = restTemplate.getForEntity(efCheckCaptchaUrl, String.class, id, captcha);
JSONObject jsonObject = JSON.parseObject(responseEntity.getBody()); JSONObject jsonObject = JSON.parseObject(responseEntity.getBody());
return ResponseResult.success(jsonObject); return ResponseResult.success(jsonObject);
......
...@@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject; ...@@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject;
import com.zhiwei.brandkbs2.auth.Auth; import com.zhiwei.brandkbs2.auth.Auth;
import com.zhiwei.brandkbs2.auth.UserThreadLocal; import com.zhiwei.brandkbs2.auth.UserThreadLocal;
import com.zhiwei.brandkbs2.common.RedisKeyPrefix; import com.zhiwei.brandkbs2.common.RedisKeyPrefix;
import com.zhiwei.brandkbs2.config.Constant;
import com.zhiwei.brandkbs2.controller.BaseController; import com.zhiwei.brandkbs2.controller.BaseController;
import com.zhiwei.brandkbs2.enmus.RoleEnum; import com.zhiwei.brandkbs2.enmus.RoleEnum;
import com.zhiwei.brandkbs2.model.ResponseResult; import com.zhiwei.brandkbs2.model.ResponseResult;
...@@ -48,9 +49,6 @@ public class AppHotController extends BaseController { ...@@ -48,9 +49,6 @@ public class AppHotController extends BaseController {
@Value("${trends.longTimeInListSearchByInner.url}") @Value("${trends.longTimeInListSearchByInner.url}")
private String trendsListUrl; private String trendsListUrl;
@Value("${trends.findHotSearchESDataInTimeByInner.url}")
private String trendsSearchUrl;
@Value("${trends.longTimeInListSearch.url}") @Value("${trends.longTimeInListSearch.url}")
private String longTimeInListSearchUrl; private String longTimeInListSearchUrl;
...@@ -74,7 +72,7 @@ public class AppHotController extends BaseController { ...@@ -74,7 +72,7 @@ public class AppHotController extends BaseController {
* douyin 抖音 * douyin 抖音
* bilibili-ranking B站 * bilibili-ranking B站
*/ */
@ApiOperation("热点库") @ApiOperation("热点库-列表")
@GetMapping("/getHotList") @GetMapping("/getHotList")
public ResponseResult getHotList(@RequestParam(value = "sortType",defaultValue = "realTime") String sortType, public ResponseResult getHotList(@RequestParam(value = "sortType",defaultValue = "realTime") String sortType,
@RequestParam(value = "type",defaultValue = "weibo") String type){ @RequestParam(value = "type",defaultValue = "weibo") String type){
...@@ -96,21 +94,6 @@ public class AppHotController extends BaseController { ...@@ -96,21 +94,6 @@ public class AppHotController extends BaseController {
} }
} }
@ApiOperation("热点库-查热点")
@GetMapping("/searchHotList")
public ResponseResult searchHotList(@RequestParam(value = "pageSize",defaultValue ="10") Integer limit,
@RequestParam(value = "page",defaultValue ="1") Integer page,
@RequestParam(value = "type",defaultValue = "weibo") String type,
@RequestParam(value = "word") String word){
ResponseEntity<JSONObject> jsonObjectResponseEntity = restTemplate.getForEntity(trendsSearchUrl, JSONObject.class, limit, page, type, word);
JSONObject body = jsonObjectResponseEntity.getBody();
if(Objects.nonNull(body)){
return ResponseResult.success(body);
}else{
return ResponseResult.failure("响应超时");
}
}
@ApiOperation("热点库-热点榜单") @ApiOperation("热点库-热点榜单")
@GetMapping("/hot") @GetMapping("/hot")
public ResponseResult hot(){ public ResponseResult hot(){
...@@ -142,14 +125,14 @@ public class AppHotController extends BaseController { ...@@ -142,14 +125,14 @@ public class AppHotController extends BaseController {
Date startDate = DateUtils.addHours(endDate, -24); Date startDate = DateUtils.addHours(endDate, -24);
List<Map.Entry<String, Integer>> markTopTitleList = List<Map.Entry<String, Integer>> markTopTitleList =
markDataService.getMarkTopTitle(startDate.getTime(), endDate.getTime(), null, projectId, linkedGroupId,"0", size); markDataService.getMarkTopTitle(startDate.getTime(), endDate.getTime(), null, projectId, linkedGroupId, Constant.PRIMARY_CONTENDID, size);
List<JSONObject> resultList = markTopTitleList.stream().map(map -> { List<JSONObject> resultList = markTopTitleList.stream().map(map -> {
JSONObject resultJsonObject = new JSONObject(); JSONObject resultJsonObject = new JSONObject();
resultJsonObject.put("title", map.getKey()); resultJsonObject.put("title", map.getKey());
resultJsonObject.put("num", map.getValue()); resultJsonObject.put("num", map.getValue());
try { try {
BaseMap firstArticle = markDataService.getFirstArticle(startDate.getTime(), endDate.getTime(), map.getKey(), projectId, linkedGroupId); BaseMap firstArticle = markDataService.getFirstArticle(startDate.getTime(), endDate.getTime(), map.getKey(), projectId, linkedGroupId, Constant.PRIMARY_CONTENDID);
resultJsonObject.put("content", firstArticle.getContent()); resultJsonObject.put("content", firstArticle.getContent());
resultJsonObject.put("url", firstArticle.getUrl()); resultJsonObject.put("url", firstArticle.getUrl());
resultJsonObject.put("realSource", firstArticle.getRealSource()); resultJsonObject.put("realSource", firstArticle.getRealSource());
......
package com.zhiwei.brandkbs2.controller.app;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zhiwei.brandkbs2.auth.Auth;
import com.zhiwei.brandkbs2.enmus.RoleEnum;
import com.zhiwei.brandkbs2.model.ResponseResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.Objects;
/**
* @ClassName AppSearchController
* @Description 提供前台搜索相关功能
* @author cjz
* @date 2022-08-15 16:17
*/
@RestController
@RequestMapping("/app/search")
@Api(tags = "前台搜索相关接口",description = "提供搜索相关功能")
@Auth(role = RoleEnum.CUSTOMER)
public class AppSearchController {
@Autowired
private RestTemplate restTemplate;
@Value("${trends.findHotSearchESDataInTimeByInner.url}")
private String trendsSearchUrl;
@Value("${crisis.search.url}")
private String crisisSearchUrl;
@Value("${ef.search.url}")
private String getEfSearchUrl;
@ApiOperation("搜索-查热点")
@GetMapping("/hot/list")
public ResponseResult searchHotList(@RequestParam(value = "pageSize",defaultValue ="10") Integer limit,
@RequestParam(value = "page",defaultValue ="1") Integer page,
@RequestParam(value = "type",defaultValue = "weibo") String type,
@RequestParam(value = "word") String word){
ResponseEntity<JSONObject> jsonObjectResponseEntity = restTemplate.getForEntity(trendsSearchUrl, JSONObject.class, limit, page, type, word);
JSONObject body = jsonObjectResponseEntity.getBody();
if(Objects.nonNull(body)){
return ResponseResult.success(body);
}else{
return ResponseResult.failure("响应超时");
}
}
@ApiOperation("搜索-查危机")
@GetMapping("/crisisSearch")
public ResponseResult crisisSearch(@RequestParam(value = "page",defaultValue = "1") Integer page,
@RequestParam(value = "pageSize",defaultValue = "3") Integer pageSize,
@RequestParam("keyword") String keyword){
ResponseEntity<String> responseEntity = restTemplate.getForEntity(crisisSearchUrl, String.class, page, pageSize, keyword);
Object data = JSON.parseObject(responseEntity.getBody()).get("data");
return ResponseResult.success(data);
}
@ApiOperation("搜索-全网事件库-查事件")
@GetMapping("/getWholeNetworkEvents")
public ResponseResult getWholeNetworkEvents(@RequestParam("keyword") String keyword,
@RequestParam(value = "page",defaultValue = "1") Integer page){
String name = keyword.trim();
ResponseEntity<String> responseEntity = restTemplate.getForEntity(getEfSearchUrl, String.class, name, page);
JSONObject jsonObject = JSON.parseObject(responseEntity.getBody());
return ResponseResult.success(jsonObject);
}
}
...@@ -155,4 +155,10 @@ public interface BaseMongoDao<T extends AbstractBaseMongo> { ...@@ -155,4 +155,10 @@ public interface BaseMongoDao<T extends AbstractBaseMongo> {
criteria.and("channelFid").is(channelIndex.getFid()); criteria.and("channelFid").is(channelIndex.getFid());
return criteria; return criteria;
} }
@FunctionalInterface
interface VoidSetFunction {
<T> void set(T t);
}
} }
...@@ -6,6 +6,7 @@ import com.zhiwei.brandkbs2.pojo.EventData; ...@@ -6,6 +6,7 @@ import com.zhiwei.brandkbs2.pojo.EventData;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.concurrent.CompletableFuture;
/** /**
* @ClassName: EventDataDao * @ClassName: EventDataDao
...@@ -23,6 +24,13 @@ public interface EventDataDao extends BaseMongoDao<EventData>, ShardingMongo { ...@@ -23,6 +24,13 @@ public interface EventDataDao extends BaseMongoDao<EventData>, ShardingMongo {
EventData findFirstData(String eventId, String collectionName); EventData findFirstData(String eventId, String collectionName);
/** /**
* 异步获取首发稿件并设置相关操作
*
* @return EventData
*/
CompletableFuture<EventData> findFirstDataAsync(String eventId, String collectionName);
/**
* 获取传播量 * 获取传播量
* *
* @param event 事件 * @param event 事件
......
...@@ -10,6 +10,7 @@ import org.springframework.data.mongodb.core.MongoTemplate; ...@@ -10,6 +10,7 @@ import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update; import org.springframework.data.mongodb.core.query.Update;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
...@@ -33,6 +34,9 @@ public class BaseMongoDaoImpl<T extends AbstractBaseMongo> implements BaseMongoD ...@@ -33,6 +34,9 @@ public class BaseMongoDaoImpl<T extends AbstractBaseMongo> implements BaseMongoD
@Resource(name = "primaryMongoTemplate") @Resource(name = "primaryMongoTemplate")
protected MongoTemplate mongoTemplate; protected MongoTemplate mongoTemplate;
@Resource(name = "mongoQueryExecutor")
protected ThreadPoolTaskExecutor taskExecutor;
public BaseMongoDaoImpl(String collectionName) { public BaseMongoDaoImpl(String collectionName) {
this.collectionName = collectionName; this.collectionName = collectionName;
this.clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; this.clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
......
...@@ -76,7 +76,8 @@ public class EventDaoImpl extends BaseMongoDaoImpl<Event> implements EventDao { ...@@ -76,7 +76,8 @@ public class EventDaoImpl extends BaseMongoDaoImpl<Event> implements EventDao {
String aliasName = "events"; String aliasName = "events";
Criteria lookUpCriteria = Criteria.where(aliasName + ".emotion").in(eventEmotions); Criteria lookUpCriteria = Criteria.where(aliasName + ".emotion").in(eventEmotions);
List<AggregationOperation> operations = Arrays.asList(Aggregation.match(criteria), List<AggregationOperation> operations = Arrays.asList(Aggregation.match(criteria),
Aggregation.lookup(COLLECTION_NAME, "eventId", "_id", aliasName), Aggregation.match(lookUpCriteria), Aggregation.lookup(COLLECTION_NAME, "eventId", "_id", aliasName),
Aggregation.match(lookUpCriteria),
Aggregation.project("events._id")); Aggregation.project("events._id"));
Aggregation aggregation = Aggregation.newAggregation(operations); Aggregation aggregation = Aggregation.newAggregation(operations);
AggregationResults<JSONObject> aggregate = mongoTemplate.aggregate(aggregation, primaryCollection, JSONObject.class); AggregationResults<JSONObject> aggregate = mongoTemplate.aggregate(aggregation, primaryCollection, JSONObject.class);
......
...@@ -11,6 +11,7 @@ import org.springframework.stereotype.Component; ...@@ -11,6 +11,7 @@ import org.springframework.stereotype.Component;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.concurrent.CompletableFuture;
/** /**
* @ClassName: EventDataDaoImpl * @ClassName: EventDataDaoImpl
...@@ -48,6 +49,11 @@ public class EventDataDaoImpl extends BaseMongoDaoImpl<EventData> implements Eve ...@@ -48,6 +49,11 @@ public class EventDataDaoImpl extends BaseMongoDaoImpl<EventData> implements Eve
} }
@Override @Override
public CompletableFuture<EventData> findFirstDataAsync(String eventId, String collectionName) {
return CompletableFuture.supplyAsync(() -> findFirstData(eventId, collectionName), taskExecutor);
}
@Override
public long getEventArticleCount(Event event) { public long getEventArticleCount(Event event) {
return count(Query.query(Criteria.where("eventId").is(event.getId())), event.getCollectionName()); return count(Query.query(Criteria.where("eventId").is(event.getId())), event.getCollectionName());
} }
......
...@@ -89,9 +89,7 @@ public class EventListInfoVO { ...@@ -89,9 +89,7 @@ public class EventListInfoVO {
this.totalDisseminationVolume = event.getTotalDisseminationVolume(); this.totalDisseminationVolume = event.getTotalDisseminationVolume();
this.totalChannelVolume = event.getTotalChannelVolume(); this.totalChannelVolume = event.getTotalChannelVolume();
this.emotion = event.getEmotion(); this.emotion = event.getEmotion();
this.eventTag = event.getEventTag().entrySet().stream() this.eventTag = event.getEventTag().values().stream().map(String::valueOf).collect(Collectors.joining("|"));
.map(entry-> String.valueOf(entry.getValue()))
.collect(Collectors.joining("|"));
this.negativeArticleVolume = event.getNegativeArticleVolume(); this.negativeArticleVolume = event.getNegativeArticleVolume();
this.articleEmotionProportions = event.getArticleEmotionProportions(); this.articleEmotionProportions = event.getArticleEmotionProportions();
this.articlePlatformProportions = event.getArticlePlatformProportions(); this.articlePlatformProportions = event.getArticlePlatformProportions();
......
...@@ -222,7 +222,7 @@ public interface EventService { ...@@ -222,7 +222,7 @@ public interface EventService {
/** /**
* 获取品牌事件列表信息 * 获取品牌事件列表信息
* @param linkedGroupId * @param contendId
* @param emotion * @param emotion
* @param startTime * @param startTime
* @param endTime * @param endTime
...@@ -231,7 +231,7 @@ public interface EventService { ...@@ -231,7 +231,7 @@ public interface EventService {
* @param sorter * @param sorter
* @return * @return
*/ */
PageVO<EventListInfoVO> getEventList(String linkedGroupId, String emotion, Long startTime, Long endTime, int page, int pageSize, String sorter); PageVO<EventListInfoVO> getEventList(String contendId, String emotion, Long startTime, Long endTime, int page, int pageSize, String sorter);
/** /**
* 事件详情-基础静态信息 * 事件详情-基础静态信息
......
...@@ -8,8 +8,10 @@ import com.zhiwei.brandkbs2.pojo.dto.ExportAppYuqingDTO; ...@@ -8,8 +8,10 @@ import com.zhiwei.brandkbs2.pojo.dto.ExportAppYuqingDTO;
import com.zhiwei.brandkbs2.pojo.dto.MarkSearchDTO; import com.zhiwei.brandkbs2.pojo.dto.MarkSearchDTO;
import com.zhiwei.brandkbs2.pojo.vo.PageVO; import com.zhiwei.brandkbs2.pojo.vo.PageVO;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.springframework.web.bind.annotation.RequestParam;
import java.io.IOException; import java.io.IOException;
import java.text.ParseException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -141,7 +143,7 @@ public interface MarkDataService { ...@@ -141,7 +143,7 @@ public interface MarkDataService {
* @param linkedGroupId 关联组id * @param linkedGroupId 关联组id
* @return 首发稿件 * @return 首发稿件
*/ */
BaseMap getFirstArticle(Long startTime, Long endTime, String aggTitle, String projectId, String linkedGroupId) throws IOException; BaseMap getFirstArticle(Long startTime, Long endTime, String aggTitle, String projectId, String linkedGroupId, String contendId) throws IOException;
/** /**
* 搜索标注数据通过事件 * 搜索标注数据通过事件
...@@ -163,4 +165,36 @@ public interface MarkDataService { ...@@ -163,4 +165,36 @@ public interface MarkDataService {
*/ */
List<JSONObject> searchMarkDataByTime(String projectId, String linkedGroupId, String contendId, Long startTime, Long endTime, String... fetchSource); List<JSONObject> searchMarkDataByTime(String projectId, String linkedGroupId, String contendId, Long startTime, Long endTime, String... fetchSource);
/**
* 竞品库-获取搜索条件
* @param linkedGroupId 关联组Id
* @return 搜索条件
*/
JSONObject getContendSearchCriteria(String linkedGroupId);
/**
* 竞品库-获取搜索结果列表
* @param markSearchDTO 标注数据搜索传输类
* @return 搜索结果列表
*/
PageVO<MarkFlowEntity> getContendSearchList(MarkSearchDTO markSearchDTO) throws IOException;
/**
* 竞品库-获取竞品对比舆情解读数据
*
* @param markSearchDTO 标注数据搜索传输类
* @param cache 是否启用缓存
* @return 竞品对比舆情解读数据
*/
JSONObject getContendSummary(MarkSearchDTO markSearchDTO, boolean cache) throws IOException;
/**
* 竞品库-获取竞品对比传播分析数据
* @param markSearchDTO 标注数据搜索传输类
* @param hotArticleSize 热门稿件数量
* @param cache 是否启用缓存
* @return
*/
JSONObject getContendSpreadAnalyze(MarkSearchDTO markSearchDTO, int hotArticleSize, boolean cache) throws IOException;
} }
...@@ -17,9 +17,10 @@ public interface MarkFlowService { ...@@ -17,9 +17,10 @@ public interface MarkFlowService {
* @param json * @param json
* @param projectId * @param projectId
* @param linkedGroupId * @param linkedGroupId
* @param contendId
* @return * @return
*/ */
JSONObject createMarkFlowInfo(JSONObject json, String projectId, String linkedGroupId); JSONObject createMarkFlowInfo(JSONObject json, String projectId,String linkedGroupId, String contendId);
/** /**
* 快照页信息组装 * 快照页信息组装
......
...@@ -808,6 +808,7 @@ public class ChannelServiceImpl implements ChannelService { ...@@ -808,6 +808,7 @@ public class ChannelServiceImpl implements ChannelService {
} }
channel.setEmotionIndex(index); channel.setEmotionIndex(index);
channel.setEmotion(emotion); channel.setEmotion(emotion);
channel.setEventCount(eventDao.getEventCount(new ChannelIndex(channel)).size());
} }
/** /**
......
...@@ -99,7 +99,7 @@ public class CustomEventServiceImpl implements CustomEventService { ...@@ -99,7 +99,7 @@ public class CustomEventServiceImpl implements CustomEventService {
JSONObject result = new JSONObject(); JSONObject result = new JSONObject();
String aggTitle = map.getKey(); String aggTitle = map.getKey();
try { try {
BaseMap firstArticle = markDataService.getFirstArticle(startTime, endTime, aggTitle, projectId, linkedGroupId); BaseMap firstArticle = markDataService.getFirstArticle(startTime, endTime, aggTitle, projectId, linkedGroupId, Constant.PRIMARY_CONTENDID);
result.put("title", firstArticle.getTitle()); result.put("title", firstArticle.getTitle());
result.put("time", firstArticle.getTime()); result.put("time", firstArticle.getTime());
result.put("url", firstArticle.getUrl()); result.put("url", firstArticle.getUrl());
...@@ -142,7 +142,7 @@ public class CustomEventServiceImpl implements CustomEventService { ...@@ -142,7 +142,7 @@ public class CustomEventServiceImpl implements CustomEventService {
set("endTime", customEventDTO.getEndTime()).set("keywords", customEventDTO.getKeywords()); set("endTime", customEventDTO.getEndTime()).set("keywords", customEventDTO.getKeywords());
customEventDao.updateOneByIdWithField(customEvent.getId(), update); customEventDao.updateOneByIdWithField(customEvent.getId(), update);
customEventDataDao.deleteOneByQuery(Query.query(Criteria.where("customEventId").is(customEventDTO.getId()))); customEventDataDao.deleteOneByQuery(Query.query(Criteria.where("customEventId").is(customEventDTO.getId())));
// this.saveCustomEvent(customEventDTO); analyzeCustomEventDataByCustomEventDTO(customEvent, customEventDTO);
} }
@Override @Override
...@@ -278,6 +278,13 @@ public class CustomEventServiceImpl implements CustomEventService { ...@@ -278,6 +278,13 @@ public class CustomEventServiceImpl implements CustomEventService {
return result; return result;
} }
private void analyzeCustomEventDataByCustomEventDTO(CustomEvent customEvent, CustomEventDTO customEventDTO) {
customEvent.setStartTime(customEventDTO.getStartTime());
customEvent.setEndTime(customEventDTO.getEndTime());
customEvent.setKeywords(customEventDTO.getKeywords());
analyzeCustomEventData(customEvent);
}
/** /**
* 自定义事件更新 * 自定义事件更新
* *
...@@ -285,10 +292,10 @@ public class CustomEventServiceImpl implements CustomEventService { ...@@ -285,10 +292,10 @@ public class CustomEventServiceImpl implements CustomEventService {
*/ */
private void analyzeCustomEventData(CustomEvent customEvent) { private void analyzeCustomEventData(CustomEvent customEvent) {
String eventId = customEvent.getId(); String eventId = customEvent.getId();
log.info("自定义事件:{} 更新开始", eventId);
customEventDao.updateOneByIdWithField(eventId, Update.update("status", false));
ApplicationProjectListener.getThreadPool().execute(() -> { ApplicationProjectListener.getThreadPool().execute(() -> {
try { try {
log.info("自定义事件:{} 更新开始", eventId);
customEventDao.updateOneByIdWithField(eventId, Update.update("status", false));
//查询符合该事件时间段的所有稿件信息 //查询符合该事件时间段的所有稿件信息
List<JSONObject> articles = markDataService.searchMarkDataByTime(customEvent.getProjectId(), customEvent.getLinkedGroupId(), "0", List<JSONObject> articles = markDataService.searchMarkDataByTime(customEvent.getProjectId(), customEvent.getLinkedGroupId(), "0",
customEvent.getStartTime(), customEvent.getEndTime()); customEvent.getStartTime(), customEvent.getEndTime());
......
...@@ -513,7 +513,7 @@ public class EventServiceImpl implements EventService { ...@@ -513,7 +513,7 @@ public class EventServiceImpl implements EventService {
String projectId = UserThreadLocal.getProjectId(); String projectId = UserThreadLocal.getProjectId();
JSONObject result = new JSONObject(); JSONObject result = new JSONObject();
// 品牌 // 品牌
result.put("brands", getBrands(projectId)); result.put("brands", projectService.getBrands(projectId, true));
// 事件调性 // 事件调性
result.put("emotions", getEventEmotions()); result.put("emotions", getEventEmotions());
// 事件类型 todo 后续用筛选器配置,和品牌关联 // 事件类型 todo 后续用筛选器配置,和品牌关联
...@@ -525,42 +525,39 @@ public class EventServiceImpl implements EventService { ...@@ -525,42 +525,39 @@ public class EventServiceImpl implements EventService {
} }
@Override @Override
public PageVO<EventListInfoVO> getEventList(String linkedGroupId, String emotion, Long startTime, Long endTime, int page, int pageSize, String sorter) { public PageVO<EventListInfoVO> getEventList(String contendId, String emotion, Long startTime, Long endTime, int page, int pageSize, String sorter) {
String projectId = UserThreadLocal.getProjectId(); String projectId = UserThreadLocal.getProjectId();
// 查询条件 // 查询条件
Query query = Query.query(Criteria.where("projectId").is(projectId).and("linkedGroupId").is(linkedGroupId)); Query query = Query.query(Criteria.where("projectId").is(projectId).and("contendId").is(contendId));
if (Objects.nonNull(emotion) && !"全部".equals(emotion)) { if (Objects.nonNull(emotion) && !"全部".equals(emotion)) {
query.addCriteria(Criteria.where("emotion").is(emotion)); query.addCriteria(Criteria.where("emotion").is(emotion));
} }
if (Objects.nonNull(startTime) && Objects.nonNull(endTime)) { if (Objects.nonNull(startTime) && Objects.nonNull(endTime)) {
query.addCriteria(Criteria.where("startTime").gte(new Date(startTime)).lt(new Date(endTime))); query.addCriteria(Criteria.where("startTime").gte(startTime).lt(endTime));
} }
// 排序
JSONObject sortJson = JSONObject.parseObject(sorter);
sortJson.entrySet().forEach(sortEntry -> {
String sort = String.valueOf(sortEntry.getValue()).replace("end", "");
String sortField = sortEntry.getKey();
if (Sort.Direction.ASC.name().equalsIgnoreCase(sort)) {
query.with(Sort.by(Sort.Direction.ASC, sortField));
} else {
query.with(Sort.by(Sort.Direction.DESC, sortField));
}
});
// 总数 // 总数
long total = eventDao.count(query); long total = eventDao.count(query);
int start = pageSize * (page - 1); // 排序
query.limit(pageSize).skip(start); eventDao.addSort(query, sorter);
mongoUtil.start(page, pageSize, query);
// 数据 // 数据
List<Event> eventList = eventDao.findList(query); List<Event> eventList = eventDao.findList(query);
// vo封装 // vo封装
List<EventListInfoVO> eventListInfoVOList = eventList.stream().map(event -> { // List<EventListInfoVO> eventListInfoVOList = eventList.stream().map(event -> {
EventListInfoVO vo = new EventListInfoVO(event); // EventListInfoVO vo = new EventListInfoVO(event);
// // 放入首发稿件
// vo.setFirstEventData(eventDataDao.findFirstData(event.getId(), event.getCollectionName()));
// return vo;
// }).collect(Collectors.toList());
// 未保证排序
Map<String, EventListInfoVO> sortMap = eventList.stream().collect(Collectors.toConcurrentMap(Event::getId, EventListInfoVO::new));
CompletableFuture.allOf(eventList.stream().map(event -> eventDataDao.findFirstDataAsync(event.getId(), event.getCollectionName()).thenApply((r) -> {
// 放入首发稿件 // 放入首发稿件
vo.setFirstEventData(eventDataDao.findFirstData(event.getId(), event.getCollectionName())); EventListInfoVO vo = new EventListInfoVO(event);
return vo; sortMap.get(event.getId()).setFirstEventData(r);
}).collect(Collectors.toList()); return null;
PageVO<EventListInfoVO> pageVo = PageVO.createPageVo(total, page, pageSize, eventListInfoVOList); })).toArray(CompletableFuture[]::new)).join();
return pageVo; return PageVO.createPageVo(total, page, pageSize, eventList.stream().map(event -> sortMap.get(event.getId())).collect(Collectors.toList()));
} }
@Override @Override
...@@ -683,6 +680,7 @@ public class EventServiceImpl implements EventService { ...@@ -683,6 +680,7 @@ public class EventServiceImpl implements EventService {
* @param projectId * @param projectId
* @return * @return
*/ */
@Deprecated
private List<JSONObject> getBrands(String projectId) { private List<JSONObject> getBrands(String projectId) {
ProjectVO projectVO = projectService.getProjectVOById(projectId); ProjectVO projectVO = projectService.getProjectVOById(projectId);
JSONObject priBrandResult = new JSONObject(); JSONObject priBrandResult = new JSONObject();
......
...@@ -8,6 +8,7 @@ import com.zhiwei.brandkbs2.auth.UserThreadLocal; ...@@ -8,6 +8,7 @@ import com.zhiwei.brandkbs2.auth.UserThreadLocal;
import com.zhiwei.brandkbs2.common.GenericAttribute; import com.zhiwei.brandkbs2.common.GenericAttribute;
import com.zhiwei.brandkbs2.common.GlobalPojo; import com.zhiwei.brandkbs2.common.GlobalPojo;
import com.zhiwei.brandkbs2.common.RedisKeyPrefix; import com.zhiwei.brandkbs2.common.RedisKeyPrefix;
import com.zhiwei.brandkbs2.config.Constant;
import com.zhiwei.brandkbs2.dao.AggreeResultDao; import com.zhiwei.brandkbs2.dao.AggreeResultDao;
import com.zhiwei.brandkbs2.enmus.ChannelEmotion; import com.zhiwei.brandkbs2.enmus.ChannelEmotion;
import com.zhiwei.brandkbs2.enmus.EmotionEnum; import com.zhiwei.brandkbs2.enmus.EmotionEnum;
...@@ -17,10 +18,7 @@ import com.zhiwei.brandkbs2.es.EsQueryTools; ...@@ -17,10 +18,7 @@ import com.zhiwei.brandkbs2.es.EsQueryTools;
import com.zhiwei.brandkbs2.exception.ExceptionCast; import com.zhiwei.brandkbs2.exception.ExceptionCast;
import com.zhiwei.brandkbs2.listener.ApplicationProjectListener; import com.zhiwei.brandkbs2.listener.ApplicationProjectListener;
import com.zhiwei.brandkbs2.model.CommonCodeEnum; import com.zhiwei.brandkbs2.model.CommonCodeEnum;
import com.zhiwei.brandkbs2.pojo.AggreeResult; import com.zhiwei.brandkbs2.pojo.*;
import com.zhiwei.brandkbs2.pojo.BaseMap;
import com.zhiwei.brandkbs2.pojo.Event;
import com.zhiwei.brandkbs2.pojo.MarkFlowEntity;
import com.zhiwei.brandkbs2.pojo.dto.ExportAppYuqingDTO; import com.zhiwei.brandkbs2.pojo.dto.ExportAppYuqingDTO;
import com.zhiwei.brandkbs2.pojo.dto.MarkSearchDTO; import com.zhiwei.brandkbs2.pojo.dto.MarkSearchDTO;
import com.zhiwei.brandkbs2.pojo.vo.CustomTagVo; import com.zhiwei.brandkbs2.pojo.vo.CustomTagVo;
...@@ -57,13 +55,18 @@ import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilde ...@@ -57,13 +55,18 @@ import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilde
import org.elasticsearch.search.sort.FieldSortBuilder; import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders; import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder; 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.Criteria;
import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.IOException; import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -212,7 +215,7 @@ public class MarkDataServiceImpl implements MarkDataService { ...@@ -212,7 +215,7 @@ public class MarkDataServiceImpl implements MarkDataService {
for (AggreeResult aggreeResult : fatherList) { for (AggreeResult aggreeResult : fatherList) {
List<MarkFlowEntity> markFlowEntities = new ArrayList<>(); List<MarkFlowEntity> markFlowEntities = new ArrayList<>();
MarkFlowEntity instance = new MarkFlowEntity(aggreeResult.getData()); MarkFlowEntity instance = new MarkFlowEntity(aggreeResult.getData());
instance.setInfo(markFlowService.createMarkFlowInfo(aggreeResult.getData(), dto.getProjectId(), dto.getContendId())); instance.setInfo(markFlowService.createMarkFlowInfo(aggreeResult.getData(), dto.getProjectId(), dto.getLinkedGroupId(), dto.getContendId()));
markFlowEntities.add(instance); markFlowEntities.add(instance);
// 添加父标题集下的子标题集 // 添加父标题集下的子标题集
// markFlowEntities.addAll(fatherMap.get(aggreeResult.getFatherId()).stream().map(sonResult -> new MarkFlowEntity(sonResult.getData())).collect(Collectors.toList())); // markFlowEntities.addAll(fatherMap.get(aggreeResult.getFatherId()).stream().map(sonResult -> new MarkFlowEntity(sonResult.getData())).collect(Collectors.toList()));
...@@ -355,7 +358,8 @@ public class MarkDataServiceImpl implements MarkDataService { ...@@ -355,7 +358,8 @@ public class MarkDataServiceImpl implements MarkDataService {
topTitle = negTopTitle.get(0).getKey(); topTitle = negTopTitle.get(0).getKey();
} }
result.put("negTopTitle", topTitle); result.put("negTopTitle", topTitle);
List<JSONObject> articlePlatformProportion = getMarkPlatformProportion(startTime, endTime, projectId, linkedGroupId, true); // 舆情库默认contendId为0
List<JSONObject> articlePlatformProportion = getMarkPlatformProportion(startTime, endTime, projectId, linkedGroupId, Constant.PRIMARY_CONTENDID, true);
result.put("platformRank", articlePlatformProportion.stream().filter(articlePlatform -> articlePlatform.getLongValue("count") > 0).sorted((o1, o2) -> o2.getLong("count").compareTo(o1.getLong("count"))).collect(Collectors.toList())); result.put("platformRank", articlePlatformProportion.stream().filter(articlePlatform -> articlePlatform.getLongValue("count") > 0).sorted((o1, o2) -> o2.getLong("count").compareTo(o1.getLong("count"))).collect(Collectors.toList()));
redisUtil.setExpire(redisKey, JSON.toJSONString(result)); redisUtil.setExpire(redisKey, JSON.toJSONString(result));
return result; return result;
...@@ -445,7 +449,8 @@ public class MarkDataServiceImpl implements MarkDataService { ...@@ -445,7 +449,8 @@ public class MarkDataServiceImpl implements MarkDataService {
endTime = timeRange[1]; endTime = timeRange[1];
String projectId = UserThreadLocal.getProjectId(); String projectId = UserThreadLocal.getProjectId();
String linkedGroupId = projectService.getProjectVOById(projectId).getBrandLinkedGroupId(); String linkedGroupId = projectService.getProjectVOById(projectId).getBrandLinkedGroupId();
res = getMarkPlatformProportion(startTime, endTime, projectId, linkedGroupId, cache); // 舆情库默认contendId为0
res = getMarkPlatformProportion(startTime, endTime, projectId, linkedGroupId, Constant.PRIMARY_CONTENDID, cache);
} catch (IOException e) { } catch (IOException e) {
ExceptionCast.cast(CommonCodeEnum.FAIL.message("es查询异常"), e); ExceptionCast.cast(CommonCodeEnum.FAIL.message("es查询异常"), e);
} }
...@@ -531,11 +536,13 @@ public class MarkDataServiceImpl implements MarkDataService { ...@@ -531,11 +536,13 @@ public class MarkDataServiceImpl implements MarkDataService {
private EsClientDao.SearchHelper createSearchHelperByMarkSearchDTO(MarkSearchDTO dto) { private EsClientDao.SearchHelper createSearchHelperByMarkSearchDTO(MarkSearchDTO dto) {
EsClientDao.SearchHelper helper = EsClientDao.createSearchHelper(); EsClientDao.SearchHelper helper = EsClientDao.createSearchHelper();
// linkedGroupId projectId // linkedGroupId、projectId、contendId
String projectId = dto.getProjectId(); String projectId = dto.getProjectId();
String linkedGroupId = dto.getLinkedGroupId(); String linkedGroupId = dto.getLinkedGroupId();
String contendId = dto.getContendId();
// PostFilter 后置过滤器 // PostFilter 后置过滤器
BoolQueryBuilder postFilter = projectLinkedGroupQuery(projectId, linkedGroupId); // BoolQueryBuilder postFilter = projectLinkedGroupQuery(projectId, linkedGroupId);
BoolQueryBuilder postFilter = projectLinkedGroupContendIdQuery(projectId, linkedGroupId, contendId);
// time // time
postFilter.must(QueryBuilders.rangeQuery(dto.getTimeType()).gte(dto.getStartTime()).lt(dto.getEndTime())); postFilter.must(QueryBuilders.rangeQuery(dto.getTimeType()).gte(dto.getStartTime()).lt(dto.getEndTime()));
// platform // platform
...@@ -599,7 +606,6 @@ public class MarkDataServiceImpl implements MarkDataService { ...@@ -599,7 +606,6 @@ public class MarkDataServiceImpl implements MarkDataService {
helper.setSize(0); helper.setSize(0);
// TODO 本地调试不滚动查询 // TODO 本地调试不滚动查询
// List<SearchResponse> searchResponses = esClientDao.searchScrollResponse(helper); // List<SearchResponse> searchResponses = esClientDao.searchScrollResponse(helper);
//singletonList:只能存放一个元素,多一个或者少一个都会导致异常
List<SearchResponse> searchResponses = Collections.singletonList(esClientDao.searchResponse(helper)); List<SearchResponse> searchResponses = Collections.singletonList(esClientDao.searchResponse(helper));
return Pair.of(searchResponses.stream().map(SearchResponse::getHits).toArray(SearchHits[]::new), null); return Pair.of(searchResponses.stream().map(SearchResponse::getHits).toArray(SearchHits[]::new), null);
} }
...@@ -608,7 +614,8 @@ public class MarkDataServiceImpl implements MarkDataService { ...@@ -608,7 +614,8 @@ public class MarkDataServiceImpl implements MarkDataService {
Map<String, Long> counts = new HashMap<>(); Map<String, Long> counts = new HashMap<>();
if (1 == dto.getPage() && CollectionUtils.isEmpty(dto.getPlatforms())) { if (1 == dto.getPage() && CollectionUtils.isEmpty(dto.getPlatforms())) {
for (MessagePlatform platform : GlobalPojo.PLATFORMS) { for (MessagePlatform platform : GlobalPojo.PLATFORMS) {
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery().must(helper.getPostFilter()).must(EsQueryTools.assemblePlatformQuery(Collections.singletonList(platform))); BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery().must(helper.getPostFilter())
.must(EsQueryTools.assemblePlatformQuery(Collections.singletonList(platform)));
Long count = esClientDao.count(esClientDao.getIndexes(), queryBuilder, null); Long count = esClientDao.count(esClientDao.getIndexes(), queryBuilder, null);
counts.put(platform.getName(), count); counts.put(platform.getName(), count);
} }
...@@ -800,11 +807,11 @@ public class MarkDataServiceImpl implements MarkDataService { ...@@ -800,11 +807,11 @@ public class MarkDataServiceImpl implements MarkDataService {
} }
@Override @Override
public BaseMap getFirstArticle(Long startTime, Long endTime, String aggTitle, String projectId, String linkedGroupId) throws IOException { public BaseMap getFirstArticle(Long startTime, Long endTime, String aggTitle, String projectId, String linkedGroupId, String contendId) throws IOException {
// 索引 // 索引
String[] indexes = esClientDao.getIndexes(); String[] indexes = esClientDao.getIndexes();
// postFilter // postFilter
BoolQueryBuilder postFilter = projectLinkedGroupQuery(projectId, linkedGroupId); BoolQueryBuilder postFilter = projectLinkedGroupContendIdQuery(projectId, linkedGroupId, contendId);
postFilter.must(QueryBuilders.rangeQuery("time").gte(startTime).lt(endTime)).must(QueryBuilders.termQuery("agg_title.keyword", aggTitle)); postFilter.must(QueryBuilders.rangeQuery("time").gte(startTime).lt(endTime)).must(QueryBuilders.termQuery("agg_title.keyword", aggTitle));
//sort //sort
FieldSortBuilder sort = new FieldSortBuilder("time").order(SortOrder.ASC); FieldSortBuilder sort = new FieldSortBuilder("time").order(SortOrder.ASC);
...@@ -843,6 +850,421 @@ public class MarkDataServiceImpl implements MarkDataService { ...@@ -843,6 +850,421 @@ public class MarkDataServiceImpl implements MarkDataService {
return Collections.emptyList(); return Collections.emptyList();
} }
@Override
public JSONObject getContendSearchCriteria(String linkedGroupId) {
String projectId = UserThreadLocal.getProjectId();
if (null == linkedGroupId) {
linkedGroupId = projectService.getProjectVOById(projectId).getBrandLinkedGroupId();
}
JSONObject result = new JSONObject();
// 搜索时间
result.put("times", Arrays.asList("今天", "24小时", "三天", "七天", "近30天"));
// 平台
result.put("platformList", commonService.getQbjcPlatform("id", "name"));
// 情感标签
result.put("emotionList", commonService.getEmotionTagsWithSort(projectId, linkedGroupId).stream().map(markerTag -> {
JSONObject json = new JSONObject();
json.put("uniqueId", markerTag.getUniqueId());
json.put("name", markerTag.getName());
return json;
}).collect(Collectors.toList()));
// 重要发声方
result.put("mediaTypeList", ImportantChannelEnum.getAllTagExceptSpec());
// 竞品品牌
Project project = projectService.getProjectById(projectId);
List<JSONObject> contendNameList = project.getContendList().stream().map(contend -> {
JSONObject jsonObject = new JSONObject();
jsonObject.put("contendName", contend.getBrandName());
jsonObject.put("contendId", contend.getId());
return jsonObject;
}).collect(Collectors.toList());
JSONObject allContend = new JSONObject();
allContend.put("contendName", "全部");
allContend.put("contendId", "-1");
contendNameList.add(0, allContend);
result.put("contendNameList", contendNameList);
// 其他标签组(筛选器)
result.put("tagFilterList", tagFilterService.getTagFilter());
// 自定义标签列表
List<CustomTagVo> customTagList = customTagService.findCustomTagList(1, 1).getList();
if (CollectionUtils.isNotEmpty(customTagList)) {
result.put("customTag", customTagList.get(0).generateSearchSonTagMaps());
}
return result;
}
@Override
public PageVO<MarkFlowEntity> getContendSearchList(MarkSearchDTO dto) {
try {
defaultMarkSearch(dto);
// 搜索es数据
Pair<SearchHits[], Map<String, Long>> hitsAndCounts = searchContendMarkHitsAndCount(dto, false);
// 总量
// long total = hitsAndCounts.getLeft()[0].getTotalHits().value > 10000 ? 10000 : hitsAndCounts.getLeft()[0].getTotalHits().value;
long total = hitsAndCounts.getLeft()[0].getTotalHits().value;
// 消息列表
List<MarkFlowEntity> flowEntityList = getMarkFlowEntity(dto, hitsAndCounts.getLeft()[0]);
// 返回分页结果并设置平台count
return PageVO.createPageVo(total, dto.getPage(), dto.getPageSize(), flowEntityList)
// 各平台计量
.setInfo(new JSONObject(ImmutableMap.of("platformCount", hitsAndCounts.getRight())));
} catch (IOException e) {
ExceptionCast.cast(CommonCodeEnum.FAIL.message("es检索异常"));
}
return null;
}
private Pair<SearchHits[], Map<String, Long>> searchContendMarkHitsAndCount(MarkSearchDTO dto, boolean aggree) throws IOException {
EsClientDao.SearchHelper helper = createContendSearchHelper(dto);
if (aggree) {
helper.setSize(0);
// TODO 本地调试不滚动查询
// List<SearchResponse> searchResponses = esClientDao.searchScrollResponse(helper);
List<SearchResponse> searchResponses = Collections.singletonList(esClientDao.searchResponse(helper));
return Pair.of(searchResponses.stream().map(SearchResponse::getHits).toArray(SearchHits[]::new), null);
}
SearchHits searchHits = esClientDao.searchHits(helper);
//平台计量统计 仅第一页且无平台限制
Map<String, Long> counts = new HashMap<>();
if (1 == dto.getPage() && CollectionUtils.isEmpty(dto.getPlatforms())) {
for (MessagePlatform platform : GlobalPojo.PLATFORMS) {
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery().must(helper.getPostFilter()).must(EsQueryTools.assemblePlatformQuery(Collections.singletonList(platform)));
Long count = esClientDao.count(esClientDao.getIndexes(), queryBuilder, null);
counts.put(platform.getName(), count);
}
}
return Pair.of(new SearchHits[]{searchHits}, counts);
}
private EsClientDao.SearchHelper createContendSearchHelper(MarkSearchDTO dto){
EsClientDao.SearchHelper helper = EsClientDao.createSearchHelper();
// linkedGroupId、projectId、contendId
String projectId = dto.getProjectId();
String linkedGroupId = dto.getLinkedGroupId();
String contendId = dto.getContendId();
List<String> contendIdList = projectService.getProjectById(projectId).getContendList().stream().map(AbstractBaseMongo::getId).collect(Collectors.toList());
// PostFilter 后置过滤器 time
BoolQueryBuilder postFilter;
if ("-1".equals(contendId) && CollectionUtils.isNotEmpty(contendIdList)){
postFilter = QueryBuilders.boolQuery().mustNot(QueryBuilders.termQuery("brandkbs_cache_maps.key.keyword", Tools.concat(projectId, linkedGroupId, Constant.PRIMARY_CONTENDID)));
}else {
postFilter = projectLinkedGroupContendIdQuery(projectId, linkedGroupId, contendId);
}
//time
postFilter.must(QueryBuilders.rangeQuery(dto.getTimeType()).gte(dto.getStartTime()).lt(dto.getEndTime()));
// platform
if (CollectionUtils.isNotEmpty(dto.getPlatforms())) {
postFilter.must(EsQueryTools.assemblePlatformQuery(Tools.getPlatformByIds(dto.getPlatforms())));
}
// mediaTypes
if (CollectionUtils.isNotEmpty(dto.getMediaTypes())) {
postFilter.must(EsQueryTools.assembleMediaTypeQuery(dto.getMediaTypes()));
}
// tags
if (CollectionUtils.isNotEmpty(dto.getTags())) {
postFilter.must(EsQueryTools.assembleTagQuery(dto.getTags()));
}
// customTags
if (CollectionUtils.isNotEmpty(dto.getCustomTags())) {
postFilter.must(EsQueryTools.assembleTagQuery(dto.getCustomTags()));
}
// Query 查询条件
// BoolQueryBuilder query = QueryBuilders.boolQuery();
// keyword
if (StringUtils.isNotEmpty(dto.getKeyword())) {
// Query
String[] fieldSearch = "标题".equals(dto.getSearchField()) ? new String[]{GenericAttribute.ES_IND_TITLE} : new String[]{GenericAttribute.ES_IND_FULL_TEXT};
postFilter.must(EsQueryTools.assembleNormalKeywordQuery(dto.getKeyword(), fieldSearch));
}
// sourceKeyword
if (StringUtils.isNotEmpty(dto.getSourceKeyword())) {
postFilter.must(EsQueryTools.assembleSourceQuery(dto.getSourceKeyword()));
}
helper.setPostFilter(postFilter);
// helper.setQuery(query);
// sort
FieldSortBuilder sort = null;
if (null != dto.getSorter()) {
for (Map.Entry<String, Object> entry : dto.getSorter().entrySet()) {
String key = entry.getKey();
if (key.equals("influence")) {
key = "channel_influence";
} else if (key.equals("followers")) {
key = "channel_followers";
}
if (null == entry.getValue() || entry.getValue().toString().contains("desc")) {
sort = SortBuilders.fieldSort(key).order(SortOrder.DESC);
} else {
sort = SortBuilders.fieldSort(key).order(SortOrder.ASC);
}
}
}
helper.setSort(sort);
// from size
helper.setFrom((dto.getPage() - 1) * dto.getPageSize());
helper.setSize(dto.getPageSize());
// HighlightBuilder ???
return helper;
}
@Override
public JSONObject getContendSummary(MarkSearchDTO dto, boolean cache) throws IOException {
// 为dto设置默认值
defaultContendDTO(dto);
ProjectVO project = projectService.getProjectVOById(dto.getProjectId());
// 缓存
SimpleDateFormat sdf = new SimpleDateFormat(Constant.DAY_PATTERN);
String startTimeStr = sdf.format(dto.getStartTime());
String endTimeStr = sdf.format(dto.getEndTime());
String redisKey = RedisKeyPrefix.INDEX_COMPARE_SUMMARY_PC + Tools.concat(dto.getProjectId(), dto.getContendId(), startTimeStr, endTimeStr);
if (cache){
String result = redisUtil.get(redisKey);
if (Objects.nonNull(result)) {
return JSON.parseObject(result);
}
}
JSONObject result = new JSONObject();
// 开始时间
result.put("startTime", dto.getStartTime());
// 结束时间
result.put("endTime", dto.getEndTime());
result.put("days", new Period(dto.getStartTime(), dto.getEndTime(), PeriodType.days()).getDays());
result.put("priName", project.getBrandName());
// 获取时间段主品牌在每个平台传播量占比
List<JSONObject> primaryPlatformsProportion =
getMarkPlatformProportion(dto.getStartTime(), dto.getEndTime(), dto.getProjectId(), dto.getLinkedGroupId(), Constant.PRIMARY_CONTENDID, true);
// 获取时间段主品牌总传播量
long primaryTotalCount = primaryPlatformsProportion.stream().mapToLong(platform -> platform.getLongValue("count")).sum();
result.put("priNorTotal", primaryTotalCount);
// 主品牌传播量最大的平台的数据
JSONObject primaryMaxPlatformProportion = primaryPlatformsProportion.stream().max(Comparator.comparing(o -> o.getLong("count"))).get();
result.put("priMaxPlatform", primaryMaxPlatformProportion.getString("platform"));
result.put("priMaxPlatformPro", primaryMaxPlatformProportion.getDoubleValue("proportion"));
// 竞品的名字
AbstractProject projectByContendId = projectService.getProjectByContendId(dto.getProjectId(), dto.getContendId());
String brandName = projectByContendId.getBrandName();
result.put("conName", brandName);
// 获取时间段竞品在每个平台传播量
List<JSONObject> contendPlatformsProportion =
getMarkPlatformProportion(dto.getStartTime(), dto.getEndTime(), dto.getProjectId(), dto.getLinkedGroupId(), dto.getContendId(), true);
// 获取时间段竞品总传播量
long contendTotalCount = contendPlatformsProportion.stream().mapToLong(platform -> platform.getLongValue("count")).sum();
result.put("conNorTotal", contendTotalCount);
// 竞品传播量最大的平台的数据
JSONObject contendMaxPlatformProportion = contendPlatformsProportion.stream().max(Comparator.comparing(o -> o.getLong("count"))).get();
result.put("conMaxPlatform", contendMaxPlatformProportion.getString("platform"));
result.put("conMaxPlatformPro", contendMaxPlatformProportion.getDoubleValue("proportion"));
result.put("compare", String.format("%.1f", primaryTotalCount * 1.0 / contendTotalCount));
List<JSONObject> platformPros = primaryPlatformsProportion.stream()
.peek(priJson -> {
JSONObject samePlatformJson = contendPlatformsProportion.stream()
.filter(conJson -> priJson.getString("platform").equals(conJson.getString("platform")))
.collect(Collectors.toList()).get(0);
priJson.put("conProportion", samePlatformJson.getDoubleValue("proportion"));
priJson.put("conNum", samePlatformJson.getLongValue("count"));
})
.filter(json -> json.getDoubleValue("proportion") > 0.001 || json.getDoubleValue("conProportion") > 0.001)
.collect(Collectors.toList());
result.put("platformPros", platformPros);
redisUtil.setExpire(redisKey, JSON.toJSONString(result), 1, TimeUnit.DAYS);
return result;
}
@Override
public JSONObject getContendSpreadAnalyze(MarkSearchDTO dto, int hotArticleSize, boolean cache) throws IOException {
defaultContendDTO(dto);
ProjectVO project = projectService.getProjectVOById(dto.getProjectId());
// 竞品的名字
AbstractProject projectByContendId = projectService.getProjectByContendId(dto.getProjectId(), dto.getContendId());
String brandName = projectByContendId.getBrandName();
// 缓存
SimpleDateFormat sdf = new SimpleDateFormat(Constant.DAY_PATTERN);
String startTimeStr = sdf.format(dto.getStartTime());
String endTimeStr = sdf.format(dto.getEndTime());
String redisKey = RedisKeyPrefix.INDEX_COMPARE_ANALYZE + Tools.concat(dto.getProjectId(), dto.getContendId(), startTimeStr, endTimeStr, hotArticleSize);
if (cache){
String result = redisUtil.get(redisKey);
if (Objects.nonNull(result)) {
return JSON.parseObject(result);
}
}
List<JSONObject> resList = new ArrayList<>(2);
JSONObject result = new JSONObject();
// 开始时间
result.put("startTime", dto.getStartTime());
// 结束时间
result.put("endTime", dto.getEndTime());
// 主品牌图谱
JSONObject primaryLine = new JSONObject();
primaryLine.put("id", Constant.PRIMARY_CONTENDID);
primaryLine.put("brand", project.getBrandName());
List<JSONObject> primarySpread =
getDayMarkArticleCount(dto.getStartTime(), dto.getEndTime(), dto.getProjectId(), dto.getLinkedGroupId(), Constant.PRIMARY_CONTENDID);
primaryLine.put("spread", primarySpread);
resList.add(primaryLine);
result.put("days", primarySpread.size());
// 竞品图谱
JSONObject contendLine = new JSONObject();
contendLine.put("id", dto.getContendId());
contendLine.put("brand", brandName);
List<JSONObject> contendSpread =
getDayMarkArticleCount(dto.getStartTime(), dto.getEndTime(), dto.getProjectId(), dto.getLinkedGroupId(), dto.getContendId());
contendLine.put("spread", contendSpread);
resList.add(contendLine);
result.put("spread", resList);
// 封装主品牌信息结果
result.put("priName", project.getBrandName());
// 获取主品牌稿件传播平均值
double avgPrimaryNormalCount = primarySpread.stream().mapToLong(line -> line.getLongValue("count")).average().orElse(0);
result.put("priAvg", (int) avgPrimaryNormalCount);
// 获取主品牌大于平均值的稿件天数
long priGreaterThanAvg = primarySpread.stream().filter(line -> line.getLongValue("count") > avgPrimaryNormalCount).count();
result.put("priGtAvg", priGreaterThanAvg);
// 获取主品牌传播峰值时信息
JSONObject primaryMax = primarySpread.stream().max(Comparator.comparing(line-> line.getLongValue("count"))).get();
result.put("priMaxTime", sdf.format(Long.parseLong(primaryMax.getString("date"))));
result.put("priMaxCount", primaryMax.getLongValue("count"));
long priMaxDayStartTime = Long.parseLong(primaryMax.getString("date"));
long priMaxDayEndTime = DateUtils.addDays(new Date(Long.parseLong(primaryMax.getString("date"))), 1).getTime();
// 获取时间段某情感数据最多的标题
List<Map.Entry<String, Integer>> priTopTitle =
getMarkTopTitle(priMaxDayStartTime, priMaxDayEndTime, EmotionEnum.ALL.getName(), dto.getProjectId(), dto.getLinkedGroupId(), Constant.PRIMARY_CONTENDID, 1);
if (CollectionUtils.isNotEmpty(priTopTitle)) {
// 首发稿件
BaseMap priFirstArticle =
getFirstArticle(priMaxDayStartTime, priMaxDayEndTime, priTopTitle.get(0).getKey(), dto.getProjectId(), dto.getLinkedGroupId(), Constant.PRIMARY_CONTENDID);
result.put("priTopTitle", priFirstArticle.getTitle());
result.put("priTopTitleUrl", priFirstArticle.getUrl());
}
// 获取主品牌热门媒体方向
List<Map.Entry<String, Integer>> priHotTitles =
getMarkTopTitle(priMaxDayStartTime, priMaxDayEndTime, EmotionEnum.ALL.getName(), dto.getProjectId(), dto.getLinkedGroupId(), Constant.PRIMARY_CONTENDID, hotArticleSize);
if (CollectionUtils.isNotEmpty(priHotTitles)) {
List<JSONObject> priHotArticle = priHotTitles.stream().map(map -> {
JSONObject jsonObject = new JSONObject();
try {
BaseMap priFirstArticle =
getFirstArticle(dto.getStartTime(), dto.getEndTime(), map.getKey(), dto.getProjectId(), dto.getLinkedGroupId(), Constant.PRIMARY_CONTENDID);
if (null != priFirstArticle) {
jsonObject.put("title", priFirstArticle.getTitle());
jsonObject.put("url", priFirstArticle.getUrl());
}
jsonObject.put("num", map.getValue());
} catch (IOException e) {
log.error("error getContendSpreadAnalyze-primary-getFirstArticle - ", e);
}
return jsonObject;
}).collect(Collectors.toList());
result.put("priHotArticle", priHotArticle);
}
// 封装竞品信息结果
// 竞品名
result.put("conName", brandName);
// 获取竞品稿件传播平均值
double avgContendSpreadNormalCount = contendSpread.stream().mapToLong(line -> line.getLongValue("count")).average().orElse(0);
result.put("conAvg", (int) avgContendSpreadNormalCount);
// 获取竞品大于平均值的稿件天数
long conGreaterThanAvg = contendSpread.stream().filter(line -> line.getLongValue("count") > avgContendSpreadNormalCount).count();
result.put("conGtAvg", conGreaterThanAvg);
//获取竞品传播峰值信息
JSONObject contendMax = contendSpread.stream().max(Comparator.comparing(line -> line.getLongValue("count"))).get();
result.put("conMaxTime", sdf.format(Long.parseLong(primaryMax.getString("date"))));
result.put("conMaxCount", contendMax.getLongValue("count"));
long conMaxDayStartTime = Long.parseLong(primaryMax.getString("date"));
long conMaxDayEndTime = DateUtils.addDays(new Date(Long.parseLong(primaryMax.getString("date"))), 1).getTime();
List<Map.Entry<String, Integer>> conTopTitle =
getMarkTopTitle(conMaxDayStartTime, conMaxDayEndTime, EmotionEnum.ALL.getName(), dto.getProjectId(), dto.getLinkedGroupId(), dto.getContendId(), 1);
if (CollectionUtils.isNotEmpty(conTopTitle)){
// 首发稿件
BaseMap conFirstArticle =
getFirstArticle(conMaxDayStartTime, conMaxDayEndTime, conTopTitle.get(0).getKey(), dto.getProjectId(), dto.getLinkedGroupId(), dto.getContendId());
result.put("conTopTitle", conFirstArticle.getTitle());
result.put("conTopTitleUrl", conFirstArticle.getUrl());
}
// 获取竞品热门媒体方向
List<Map.Entry<String, Integer>> conHotTitles =
getMarkTopTitle(conMaxDayStartTime, conMaxDayEndTime, EmotionEnum.ALL.getName(), dto.getProjectId(), dto.getLinkedGroupId(), dto.getContendId(), hotArticleSize);
if (CollectionUtils.isNotEmpty(conHotTitles)){
List<JSONObject> conHotArticle = conHotTitles.stream().map(map -> {
JSONObject jsonObject = new JSONObject();
try {
BaseMap conFirstArticle =
getFirstArticle(dto.getStartTime(), dto.getEndTime(), map.getKey(), dto.getProjectId(), dto.getLinkedGroupId(), dto.getContendId());
if (null != conFirstArticle) {
jsonObject.put("title", conFirstArticle.getTitle());
jsonObject.put("url", conFirstArticle.getUrl());
}
jsonObject.put("num", map.getValue());
} catch (IOException e) {
log.error("error getContendSpreadAnalyze-contend-getFirstArticle - ", e);
}
return jsonObject;
}).collect(Collectors.toList());
result.put("conHotArticle", conHotArticle);
}
redisUtil.setExpire(redisKey, JSON.toJSONString(result), 1, TimeUnit.DAYS);
return result;
}
/**
* 获取每日稿件数量
*
* @param startTime 开始时间
* @param endTime 结束时间
* @param projectId 项目ID
* @param linkedGroupId 关联组Id
* @param contendId 竞品ID
* @return 每日稿件数量
*/
private List<JSONObject> getDayMarkArticleCount(Long startTime, Long endTime, String projectId, String linkedGroupId, String contendId) throws IOException {
List<JSONObject> resultList = new ArrayList<>();
// index
String[] indexes = esClientDao.getIndexes();
// dayAgg
DateHistogramAggregationBuilder daysAggregation = AggregationBuilders.dateHistogram("dayAgg").field("time").calendarInterval(DateHistogramInterval.DAY);
BoolQueryBuilder query = projectLinkedGroupContendIdQuery(projectId, linkedGroupId, contendId);
// time range
query.must(QueryBuilders.rangeQuery("time").gte(startTime).lt(endTime));
// response
SearchResponse response = esClientDao.searchResponse(indexes, null, query, daysAggregation, null, null, 0, 0, null);
Map<String, Aggregation> aggMap = response.getAggregations().asMap();
ParsedDateHistogram dayAggTeam = (ParsedDateHistogram) aggMap.get("dayAgg");
List<? extends Histogram.Bucket> buckets = dayAggTeam.getBuckets();
buckets.forEach(bucket -> {
JSONObject result = new JSONObject();
result.put("date", bucket.getKeyAsString());
result.put("count", bucket.getDocCount());
resultList.add(result);
});
return resultList;
}
/**
* 为竞品库竞品对比 标注数据搜索传输类设置默认值
* @param dto 标注数据搜索传输类
*/
private void defaultContendDTO(MarkSearchDTO dto){
if (Objects.isNull(dto.getStartTime()) || Objects.isNull(dto.getEndTime())) {
Date now = new Date();
dto.setEndTime(now.getTime());
dto.setStartTime(DateUtils.addDays(now, -29).getTime());
}
String projectId = UserThreadLocal.getProjectId();
dto.setProjectId(projectId);
String linkedGroupId = dto.getLinkedGroupId();
if (null == linkedGroupId) {
linkedGroupId = projectService.getProjectVOById(projectId).getBrandLinkedGroupId();
dto.setLinkedGroupId(linkedGroupId);
}
}
/** /**
* 获取每日稿件倾向稿件数量信息 * 获取每日稿件倾向稿件数量信息
* *
...@@ -936,14 +1358,14 @@ public class MarkDataServiceImpl implements MarkDataService { ...@@ -936,14 +1358,14 @@ public class MarkDataServiceImpl implements MarkDataService {
}); });
} }
private List<JSONObject> getMarkPlatformProportion(Long startTime, Long endTime, String projectId, String linkedGroupId, boolean cache) throws IOException { private List<JSONObject> getMarkPlatformProportion(Long startTime, Long endTime, String projectId, String linkedGroupId, String contendId, boolean cache) throws IOException {
String redisKey = RedisKeyPrefix.MARK_PLATFORM_PROPORTION + Tools.concat(projectId, startTime, endTime); String redisKey = RedisKeyPrefix.MARK_PLATFORM_PROPORTION + Tools.concat(projectId, startTime, endTime);
String resultStr; String resultStr;
if (cache && StringUtils.isNotEmpty(resultStr = redisUtil.get(redisKey))) { if (cache && StringUtils.isNotEmpty(resultStr = redisUtil.get(redisKey))) {
return JSON.parseArray(resultStr, JSONObject.class); return JSON.parseArray(resultStr, JSONObject.class);
} }
List<JSONObject> platformList = commonService.getQbjcPlatform("id", "name"); List<JSONObject> platformList = commonService.getQbjcPlatform("id", "name");
List<JSONObject> platformsCount = getPlatformsCount(startTime, endTime, null, null, projectId, linkedGroupId, platformList); List<JSONObject> platformsCount = getPlatformsCount(startTime, endTime, null, null, projectId, linkedGroupId, contendId, platformList);
long articlesCount = platformsCount.stream().mapToLong(platform -> platform.getLongValue("count")).sum(); long articlesCount = platformsCount.stream().mapToLong(platform -> platform.getLongValue("count")).sum();
List<JSONObject> resultList = platformsCount.stream().peek(platform -> platform.put("proportion", 0 == articlesCount ? 0 : platform.getLongValue("count") * 1.0 / articlesCount)).collect(Collectors.toList()); List<JSONObject> resultList = platformsCount.stream().peek(platform -> platform.put("proportion", 0 == articlesCount ? 0 : platform.getLongValue("count") * 1.0 / articlesCount)).collect(Collectors.toList());
redisUtil.setExpire(redisKey, JSON.toJSONString(resultList)); redisUtil.setExpire(redisKey, JSON.toJSONString(resultList));
...@@ -961,13 +1383,13 @@ public class MarkDataServiceImpl implements MarkDataService { ...@@ -961,13 +1383,13 @@ public class MarkDataServiceImpl implements MarkDataService {
* @param platformList 平台集合 * @param platformList 平台集合
* @return 所有平台稿件数量信息 * @return 所有平台稿件数量信息
*/ */
private List<JSONObject> getPlatformsCount(Long startTime, Long endTime, String keyword, String searchField, String projectId, String linedGroupId, List<JSONObject> platformList) throws IOException { private List<JSONObject> getPlatformsCount(Long startTime, Long endTime, String keyword, String searchField, String projectId, String linkedGroupId, String contendId, List<JSONObject> platformList) throws IOException {
// 获取索引 // 获取索引
String[] indexes = esClientDao.getIndexes(); String[] indexes = esClientDao.getIndexes();
// 聚合请求 // 聚合请求
TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("count").field("platform_id.keyword").order(BucketOrder.count(false)).size(100); TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("count").field("platform_id.keyword").order(BucketOrder.count(false)).size(100);
// query // query
BoolQueryBuilder query = projectLinkedGroupQuery(projectId, linedGroupId); BoolQueryBuilder query = projectLinkedGroupContendIdQuery(projectId, linkedGroupId, contendId);
// keyword // keyword
if (StringUtils.isNotEmpty(keyword)) { if (StringUtils.isNotEmpty(keyword)) {
String[] fieldSearch = "标题".equals(searchField) ? new String[]{GenericAttribute.ES_IND_TITLE} : new String[]{GenericAttribute.ES_IND_FULL_TEXT}; String[] fieldSearch = "标题".equals(searchField) ? new String[]{GenericAttribute.ES_IND_TITLE} : new String[]{GenericAttribute.ES_IND_FULL_TEXT};
...@@ -1081,7 +1503,8 @@ public class MarkDataServiceImpl implements MarkDataService { ...@@ -1081,7 +1503,8 @@ public class MarkDataServiceImpl implements MarkDataService {
} }
private List<MarkFlowEntity> getMarkFlowEntity(MarkSearchDTO markSearchDTO, SearchHits searchHits) { private List<MarkFlowEntity> getMarkFlowEntity(MarkSearchDTO markSearchDTO, SearchHits searchHits) {
String projectId = UserThreadLocal.getProjectId(); String projectId = markSearchDTO.getProjectId();
String linkedGroupId = markSearchDTO.getLinkedGroupId();
String contendId = markSearchDTO.getContendId(); String contendId = markSearchDTO.getContendId();
// 重复消息折叠 // 重复消息折叠
if (markSearchDTO.isFold()) { if (markSearchDTO.isFold()) {
...@@ -1090,14 +1513,15 @@ public class MarkDataServiceImpl implements MarkDataService { ...@@ -1090,14 +1513,15 @@ public class MarkDataServiceImpl implements MarkDataService {
String title = baseMap.getTitleNullOptionalContent(); String title = baseMap.getTitleNullOptionalContent();
return Tools.filterSpecialCharacter(title) + baseMap.getTypeB().encode(); return Tools.filterSpecialCharacter(title) + baseMap.getTypeB().encode();
})); }));
return collect.values().stream().map(list -> MarkFlowEntity.getFoldInstance(list.stream().map(map -> getMarkFlowEntity(map, projectId, contendId)).collect(Collectors.toList()))).collect(Collectors.toList()); return collect.values().stream().map(list -> MarkFlowEntity.getFoldInstance(list.stream().map(map -> getMarkFlowEntity(map, projectId,
linkedGroupId, contendId)).collect(Collectors.toList()))).collect(Collectors.toList());
} }
return Arrays.stream(searchHits.getHits()).map(hit -> getMarkFlowEntity(hit.getSourceAsMap(), projectId, contendId)).collect(Collectors.toList()); return Arrays.stream(searchHits.getHits()).map(hit -> getMarkFlowEntity(hit.getSourceAsMap(), projectId, linkedGroupId, contendId)).collect(Collectors.toList());
} }
private MarkFlowEntity getMarkFlowEntity(Map<String, Object> map, String projectId, String contendId) { private MarkFlowEntity getMarkFlowEntity(Map<String, Object> map, String projectId, String linkedGroupId, String contendId) {
MarkFlowEntity instance = new MarkFlowEntity(new JSONObject(map)); MarkFlowEntity instance = new MarkFlowEntity(new JSONObject(map));
instance.setInfo(markFlowService.createMarkFlowInfo(new JSONObject(map), projectId, contendId)); instance.setInfo(markFlowService.createMarkFlowInfo(new JSONObject(map), projectId, linkedGroupId, contendId));
return instance; return instance;
} }
......
...@@ -11,8 +11,6 @@ import com.zhiwei.brandkbs2.dao.ChannelTagDao; ...@@ -11,8 +11,6 @@ import com.zhiwei.brandkbs2.dao.ChannelTagDao;
import com.zhiwei.brandkbs2.enmus.ChannelEmotion; import com.zhiwei.brandkbs2.enmus.ChannelEmotion;
import com.zhiwei.brandkbs2.exception.ExceptionCast; import com.zhiwei.brandkbs2.exception.ExceptionCast;
import com.zhiwei.brandkbs2.model.CommonCodeEnum; import com.zhiwei.brandkbs2.model.CommonCodeEnum;
import com.zhiwei.brandkbs2.pojo.Channel;
import com.zhiwei.brandkbs2.pojo.ChannelIndex;
import com.zhiwei.brandkbs2.pojo.MarkFlowEntity; import com.zhiwei.brandkbs2.pojo.MarkFlowEntity;
import com.zhiwei.brandkbs2.service.MarkFlowService; import com.zhiwei.brandkbs2.service.MarkFlowService;
import com.zhiwei.brandkbs2.util.RedisUtil; import com.zhiwei.brandkbs2.util.RedisUtil;
...@@ -22,9 +20,6 @@ import org.springframework.stereotype.Service; ...@@ -22,9 +20,6 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/** /**
* @ClassName: MarkFlowServiceImpl * @ClassName: MarkFlowServiceImpl
...@@ -45,9 +40,9 @@ public class MarkFlowServiceImpl implements MarkFlowService { ...@@ -45,9 +40,9 @@ public class MarkFlowServiceImpl implements MarkFlowService {
RedisUtil redisUtil; RedisUtil redisUtil;
@Override @Override
public JSONObject createMarkFlowInfo(JSONObject json, String projectId, String contendId) { public JSONObject createMarkFlowInfo(JSONObject json, String projectId, String linkedGroupId, String contendId) {
JSONObject resultInfo = createInfoWithEmotion(json); JSONObject resultInfo = createInfoWithEmotion(json);
resultInfo.put("sourceDetails", getSourceDetails(json, projectId, contendId)); resultInfo.put("sourceDetails", getSourceDetails(json, projectId, linkedGroupId, contendId));
return resultInfo; return resultInfo;
} }
...@@ -106,7 +101,7 @@ public class MarkFlowServiceImpl implements MarkFlowService { ...@@ -106,7 +101,7 @@ public class MarkFlowServiceImpl implements MarkFlowService {
return info; return info;
} }
private JSONObject getSourceDetails(JSONObject tJson, String projectId, String contendId) { private JSONObject getSourceDetails(JSONObject tJson, String projectId, String linkedGroupId, String contendId) {
JSONObject sourceDetails = new JSONObject(); JSONObject sourceDetails = new JSONObject();
String source = tJson.getString(GenericAttribute.ES_SOURCE); String source = tJson.getString(GenericAttribute.ES_SOURCE);
// 是否原创 // 是否原创
...@@ -123,20 +118,28 @@ public class MarkFlowServiceImpl implements MarkFlowService { ...@@ -123,20 +118,28 @@ public class MarkFlowServiceImpl implements MarkFlowService {
sourceDetails.put("followersNum", followersNum); sourceDetails.put("followersNum", followersNum);
} }
// 渠道标签 // 渠道标签
sourceDetails.put("channelTag", channelTagDao.getTagByChannelName(source));
// 渠道倾向及id String channelTag = tJson.getString("channel_tag");
Channel channel = channelDao.queryUnique(ChannelIndex.createChannelIndex(tJson, projectId, contendId)); if (null != channelTag) {
if (null != channel) { sourceDetails.put("channelTag", channelTag.replaceAll(",", "|"));
sourceDetails.put("channelId", channel.getId()); }
sourceDetails.put("channelEmotion", ChannelEmotion.getNameFromState(channel.getEmotion())); // 渠道倾向及id(调整为快照属性)
} else { // Channel channel = channelDao.queryUnique(ChannelIndex.createChannelIndex(tJson, projectId, contendId));
List<Map<String, Object>> cacheMaps = (List<Map<String, Object>>) tJson.get(GenericAttribute.ES_BRANDKBS_CACHE_MAPS); // if (null != channel) {
if (null != cacheMaps) { // sourceDetails.put("channelId", channel.getId());
Map<String, Object> hitMap = // sourceDetails.put("channelEmotion", ChannelEmotion.getNameFromState(channel.getEmotion()));
cacheMaps.stream().filter(map -> projectId.equals(map.get("project_id")) && contendId.equals(map.get("contend_id"))).findAny().orElse(Collections.emptyMap()); // } else {
sourceDetails.put("channelId", hitMap.get("channel_id")); // List<Map<String, Object>> cacheMaps = (List<Map<String, Object>>) tJson.get(GenericAttribute.ES_BRANDKBS_CACHE_MAPS);
sourceDetails.put("channelEmotion", ChannelEmotion.getNameFromState(hitMap.get("channel_emotion"))); // if (null != cacheMaps) {
} // 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")));
// }
// }
JSONObject brandkbsHitJson = Tools.getBrandkbsHitMap(tJson, Tools.concat(projectId, linkedGroupId, contendId));
if (null != brandkbsHitJson.get("channel_emotion")) {
sourceDetails.put("channelEmotion", ChannelEmotion.getNameFromState(brandkbsHitJson.getIntValue("channel_emotion")));
} }
double channelValue = tJson.getDoubleValue(GenericAttribute.ES_CHANNEL_INDEX); double channelValue = tJson.getDoubleValue(GenericAttribute.ES_CHANNEL_INDEX);
if (channelValue > 0) { if (channelValue > 0) {
......
...@@ -93,7 +93,7 @@ public class TaskServiceImpl implements TaskService { ...@@ -93,7 +93,7 @@ public class TaskServiceImpl implements TaskService {
insertList.addAll(batchHandle(batchList, newRecordMap)); insertList.addAll(batchHandle(batchList, newRecordMap));
batchList = new ArrayList<>(); batchList = new ArrayList<>();
} }
if (handleSize % 100 == 0) { if (handleSize % 10000 == 0) {
log.info("渠道统计-渠道总计-查询更新已完成{}/{}", handleSize, channelIndexRecordMap.size()); log.info("渠道统计-渠道总计-查询更新已完成{}/{}", handleSize, channelIndexRecordMap.size());
} }
} }
......
...@@ -779,14 +779,14 @@ public class Tools { ...@@ -779,14 +779,14 @@ public class Tools {
return contains; return contains;
} }
public static Map<String, Object> getBrandkbsHitMap(Map<String, Object> esMap, String hitKey) { public static JSONObject getBrandkbsHitMap(Map<String, Object> esMap, String hitKey) {
List<Map<String, Object>> cacheMaps = (List<Map<String, Object>>) esMap.get("brandkbs_cache_maps"); List<Map<String, Object>> cacheMaps = (List<Map<String, Object>>) esMap.get("brandkbs_cache_maps");
for (Map<String, Object> cacheMap : cacheMaps) { for (Map<String, Object> cacheMap : cacheMaps) {
if (hitKey.equals(cacheMap.get("key"))) { if (hitKey.equals(cacheMap.get("key"))) {
return cacheMap; return new JSONObject(cacheMap);
} }
} }
return Collections.emptyMap(); return new JSONObject();
} }
public static <T> Map<Long, T> sortTimeKeyMap(Map<Long, T> map, boolean isDesc) { public static <T> Map<Long, T> sortTimeKeyMap(Map<Long, T> map, boolean isDesc) {
......
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