目前ORM线上分析数据处理流程(保存租户12张表的数据)
爬虫线上分析:对线下生成的文件分析入库
入口通过路由触发(AnalysisController--/analysis/{date})
|
|
∨
首先校验指定日期的文件是否存在,并获取所有的文件夹
|
|
∨
根据日期获取目录下所有租户id循环读取租户id,启动线程逐个分析(一个租户启动一个线程)
|
|
∨
校验文件是否缺少
|
|
∨
单个租户开始进行数据分析和入库(获取所有文件夹下的文件名)
|
|
∨
校验项目是否存在,不存在就不入库(获取所有活跃的项目和文件截取的项目id比较)
|
|
∨
截取文件名中的表名标识进行入库操作(通过use命令来切换数据库)
|
|
∨
每个租户分析完后,插入租户项目抓取日期表(tm_f_pro_crawl)
|
|
∨
入库成功之后,调用校验(对四张表的数据进行处理,关系表有但是详情表没有的 需要删除关系,关系表没有但是详情表有的 需要删除详情)
tm_b_pro_detail_relation 项目和详单数据关系表
tm_b_sentiment_detail 存储最为详细的舆情数据
tm_b_pro_detail_relation_noise 项目和详单数据关系tm_b_sentiment_detail_noise 存储最为详细的舆情数据)
|
|
∨
分析概览表数据(tm_b_dashboard)
|
|
∨
插入文章表、修改软文、修改负面、修改软文收录量、修改负面历史
|
|
∨
插入项目抓取数据记录表(wi_orm_pro_crawl_rel)
|
|
∨
所有租户数据遍历完分析入库完成(错误时短信通知)
ORM线上分析详细过程
线上分析入口:AnalysisController
路由:/analysis/{date}
执行方法:analysis(@PathVariable String date)
分析方式和数据来源:
1:每个租户分析开启一个线程,将当前日期所有租户的项目爬取的txt文件中的数据入库。
相关代码:
//读取租户id,启动线程
for (File file : files) {
if (null != file && file.isDirectory()) {
pool.execute(new Thread(() -> {
try {
joinContext(file.getName());
//校验文件是否缺少
if (checkFile(file.getAbsolutePath())) {
if (analysisData(file.getName(), fileMaping.getPath() + date + "/" + file.getName(), DateUtils.parse(date, "yyyy-MM-dd"))) {
}
}
}
}
}
}
每个租户分析逻辑:
(1) 校验文件是否缺少:
获取租户的所有文件列表,如果: crawlChannelHis、crawlKeywordHis、totalSearch项目对应生成的文件个数相等并且searchsentimentDetail、sentimentDetail、sentimentDetailRelation项目对应生成的文件个数相等,此租户才进行分析。)
(2)分析所需数据
(2.1):获取租户目录下所有txt项目数据
(2.2):根据租户id获取所有活跃的项目信息projectList(从user-center中获取)
(3)分析过程
遍历租户文件夹下所有项目的txt文件,如果当前文件的项目id在projectList中存在才进行入库。
(3.1)根据截取的文件名判断所需要保存的表名,根据statement.execute("USE " + getTenantId());切换租户库将数据保存到不同的租户库中。
保存12张表的数据:
to_b_crawl_channel_his 爬取渠道历史记录表
to_b_crawl_keywrod_his 爬取关键词历史记录表
to_b_total_search_his 爬取关键词历史总数记录表
tm_b_search_result_detail 存储在搜索渠道中所有的结果详情
tm_b_sentiment_detail 存储最为详细的舆情数据
tm_b_pro_detail_relation 项目和详单数据关系表
tm_b_sentiment_duplicate 舆情详单数据历史表--用于保存同一排名多条记录的情况
tm_b_search_result_detail_noise 存储在搜索渠道中所有的结果详情
tm_b_sentiment_detail_noise 存储最为详细的舆情数据
tm_b_pro_detail_relation_noise 项目和详单数据关系表
tm_b_softPaper 软文临时表
tm_b_sentiment_detail_origin 负面历史临时表
(3.2)每个租户的所有项目数据入库完成后,将分析的租户项目记录插入项目抓取日期表tm_f_pro_crawl
相关代码:
this.insertProjectCrawlDate(projectIds, crawlDate);
(3.3) 入库成功之后,调用校验,根据爬取日期对以下四张表的数据进行处理:
关系表有但是详情表没有的 需要删除关系
关系表没有但是详情表有的 需要删除详情
tm_b_pro_detail_relation 项目和详单数据关系表
tm_b_sentiment_detail 存储最为详细的舆情数据
tm_b_pro_detail_relation_noise 项目和详单数据关系tm_b_sentiment_detail_noise 存储最为详细的舆情数据)
相关代码:
/***
* 关系表有但是详情表没有的 需要删除关系
*/
List<Long> relIds = this.getRelIdByRelationNoDetail(date);
/***
* 关系表没有但是详情表有的 需要删除详情
*/
List<Long> detailid = this.getDetailIdByDetailNoRelation(date);
(3.4) 校验成功后进行概览表数据分析(tm_b_dashboard)
数据来源:根据租户id查询wi_orm_project表中project_state=1包括项目下的关键词和竞品数据projects。遍历projects,项目必须要有关键词,没有关键词的不进行分析。根据竞品id和项目本身id集合brandIds和项目id、爬取日期查询要分析的数据,具体过程:
(3.4.1) 查询项目的品牌词 正面、中立、负面数据。涉及到的表(tm_b_sentiment_detail、tm_b_pro_detail_relation),sentimentState 为('0','1','2')
相关代码:
List<DashboardDto> brandList = proRelDao.getDashboardDto(projectId, brandIds, CrawlDate);// 最多同一個关键词
brandList中同一条品牌词详单其实对应三条 正,负 ,中 要将 正,负 ,中合并成一条
相关代码:
List<CheckDashboard> brandDashboards = CheckCommon.getCheckDashboardByDashboardDto(brandList, projectId);
(3.4.2) 查询项目的非品牌词 其他量的数据。涉及到的表(tm_b_sentiment_detail、tm_b_pro_detail_relation),sentimentState 为('3')
相关代码:
List<DashboardDto> noBbrandList = proRelDao.getDashboardDtoByNobrand(projectId, brandIds, CrawlDate);
将非品牌词的其他量转化成实体
相关代码:
List<CheckDashboard> nobrandDashboards = CheckCommon.getCheckDashboardByNoBrandDashboardDto(noBbrandList, projectId);
合并brandDashboards和nobrandDashboards的数据为list
(3.4.3) 根据项目id和爬取日期查找当天爬取的关键词历史数据表数据和和渠道历史数据表数据,取得关键词ids和渠道ids。涉及到的表(to_b_crawl_keywrod_his、to_b_crawl_channel_his)
相关代码:
List<AidinfoExposureVo> keywordVos = aidinfoService.getKeywordHis(CrawlDate, projectId);
List<AidinfoExposureVo> chnannlVos = aidinfoService.getChannelHis(CrawlDate, projectId);
(3.4.4) 根据关键词ids、渠道ids、项目id和爬取日期获取每个关键词每个渠道每个时间的抓取条数 取自详单表(to_b_total_search_his)
相关代码:
List<DashboardTotalSearchDto> dashboardTotalSearchDtos = this.getSearchNum(keywordIds, channelIds, CrawlDate, projectId);
(3.4.5)处理关键词总搜索量,遍历数据list和dashboardTotalSearchDtos数据,设置关键词总搜索量。
相关代码:
for (CheckDashboard dto : list) {
for (DashboardTotalSearchDto tDto : dashboardTotalSearchDtos) {
if (dto.getKeywordId().longValue() == tDto.getKeywordId().longValue()) {// 相同關鍵詞
if (dto.getChannel().longValue() == tDto.getChannelId().longValue()) {// 相同渠道
if (DateUtils.isSameDate(dto.getCrawlDate(), tDto.getCrawlDate())) {// 相同時間
dto.setTotalSearch(tDto.getTotalSearch());
break;
}
}
}
}
}
(3.4.6)根据爬取日期、关键词ids和项目id计算关键词的曝光率
涉及到的表(tm_b_sentiment_detail、tm_b_pro_detail_relation)
相关代码:
// 曝光率
List<DashboardExposureDto> dashboardExposureDtos = this.getDashboardExposureDto(keywordIds, CrawlDate, projectId);
// 将 dto中的曝光率 转成实体中的曝光率
CheckCommon.getExposureByDtoToCheckDashboard(dashboardExposureDtos, list);
(3.4.7) 根据爬取日期、关键词ids和项目id计算关键词的负面曝光率,涉及到的表(tm_b_sentiment_detail、tm_b_pro_detail_relation) sentimentState=2
相关代码:
// 负面曝光率
List<DashboardExposureDto> noExposureDtos = this.getDashboardNegativeExposureDto(keywordIds, CrawlDate, projectId);
// 将 dto中的曝光率 转成实体中的曝光率 CheckCommon.getExposureByNoDtoToCheckDashboard(noExposureDtos, list);
(3.4.8) 根据爬取日期、竞品ids和项目id计算噪声搜索量,涉及到的表(tm_b_sentiment_detail_noise、tm_b_pro_detail_relation_noise)
相关代码:
// 噪声量
List<DashboardNoiseDto> DashboardNoiseDtos = proRelNoiseDao.getNoiseDashboardDtoByNobrand(projectId, brandIds, CrawlDate);
if (!ListUntils.isNull(DashboardNoiseDtos)) {
for (CheckDashboard dto : list) {
for (DashboardNoiseDto tDto : DashboardNoiseDtos) {
if (dto.getCompetitorId().intValue() == tDto.getBrandId().intValue()) {// 相同品牌
if (dto.getKeywordId().intValue() == tDto.getKeywordId().intValue()) {// 相同關鍵詞
if (dto.getChannel().intValue() == tDto.getChannelId().intValue()) {// 相同渠道
if (DateUtils.isSameDate(dto.getCrawlDate(), tDto.getCrawlDate())) {// 相同時間
dto.setNoiseValue(tDto.getNum().intValue());
break;
}
}
}
}
}
}
}
(3.5) 插入文章表数据(tm_b_article_detail_relation)具体过程:
(3.5.1)根据爬取日期获取所有品牌的文章的搜索结果数。涉及到的表(tm_b_pro_detail_relation,tm_b_search_result_detail,tm_b_sentiment_detail)
相关代码:
List<ArticleVo> articleVos = getArticleResult(crawlDate);
(3.5.2)根据爬取日期获取品牌的项目和详单关系id。涉及到的表
(tm_b_pro_detail_relation,tm_b_search_result_detail, tm_b_sentiment_detail)
相关代码:
List<ArticleRelationVo> relations = this.getArticleRelation(crawlDate);
(3.5.3) 插入文章临时表。涉及到的表(tm_b_article)
相关代码:
List<CheckArticle> checkArticles = makeCheckArticle(articleVos, crawlDate);
insert(checkArticles);
(3.5.4) 插入文章和详单关系临时表。涉及到的表(tm_b_article_detail_relation)
相关代码:
List<CheckArticleDetailRelation> checkArticleDetailRelations = makeArticleDetailRelation(articleVos, relations, crawlDate);
insert(checkArticleDetailRelations);
(3.6) 修改软文表数据(tm_b_pro_detail_relation)具体过程:
(3.6.1)根据租户id查询活跃项目。涉及到的表(wi_orm_project)
List<OutProjectBaseInfoDto> projects = projectService.getTenantProject(Long.valueOf(tenantId), "1");// 活跃的
(3.6.2) 项目和详单数据关系表的软文不包含一个排名对应多条详单。
遍历项目集合projects
(3.6.2.1)根据项目id和爬取时间查询项目的详单数据,涉及到的表(tm_b_pro_detail_relation, tm_b_sentiment_detail, tm_b_search_result_detail)
相关代码:
List<ProDetail> proDetailList = proRelDao.getproDetail(pro.getProjectId(), crawlDate);
(3.6.2.2) 根据项目id获取项目下的软文,涉及到的表(tf_b_softPaper)
相关代码:
List<CheckSoftPaper> softList = checkSoftDao.getSoftPaper(pro.getProjectId());
如果softList为空没有软文,所有详单都是非软文。设置SoftId为null, AdvertorialState为0,如果softList不为空循环所有的详单和所有的软文。如果详单的url等于软文的url,设置详单的SoftId为软文SoftId,详单的AdvertorialState为1,如果详单的url在所有软文中不存在,则设置详单的SoftId为null, AdvertorialState为0。
相关代码:
if (ListUntils.isNull(softList)) {// 没有软文
// 所有的详单都是 非软文
for (ProDetail proDetail : proDetailList) {// 循环所有的详单
proDetail.setSoftId(null);
proDetail.setAdvertorialState("0");
}
} else {
for (ProDetail proDetail : proDetailList) {// 循环所有的详单
for (CheckSoftPaper softPaper : softList) {// 所有的软文
if (proDetail.getUrl().equals(softPaper.getSoftUrl())) {// 判断
proDetail.setSoftId(softPaper.getSoftId());
proDetail.setAdvertorialState("1");
break;
} else {
proDetail.setSoftId(null);
proDetail.setAdvertorialState("0");
}
}
}
}
(3.6.2.3) 更新软文表数据(tm_b_pro_detail_relation)
proRelDao.updateProDetail(proDetailList);
(3.6.3) 一个排名对应多条详单的软文判断。
遍历项目集合projects
(3.6.3.1)根据项目id和爬取时间查询项目的详单数据, 一个详单对应多条记录。涉及到的表(tm_b_pro_detail_relation, tm_b_sentiment_detail, tm_b_sentiment_duplicate)
相关代码:
List<ProDetail> proDetailList = sentimentDuplicateDao.getproDetail(pro.getProjectId(), crawlDate);
(3.6.3.2) 根据项目id获取项目下的软文,涉及到的表(tf_b_softPaper)
相关代码:
if (ListUntils.isNull(softList)) {// 没有软文
// 所有的详单都是 非软文
for (ProDetail proDetail : proDetailList) {// 循环所有的详单
proDetail.setSoftId(null);
proDetail.setAdvertorialState("0");
}
} else {
for (ProDetail proDetail : proDetailList) {// 循环所有的详单
for (CheckSoftPaper softPaper : softList) {// 所有的软文
if (proDetail.getUrl().equals(softPaper.getSoftUrl())) {// 判断
// 是软文
proDetail.setSoftId(softPaper.getSoftId());
proDetail.setAdvertorialState("1");
break;
} else {
proDetail.setSoftId(null);
proDetail.setAdvertorialState("0");
}
}
}
}
proDetailList = ListUntils.deWeight(proDetailList, "RelationId");
(3.6.3.3) 更新软文表数据(tm_b_pro_detail_relation)
proRelDao.updateProDetail(proDetailList);
(3.7) 修改负面(tm_b_pro_detail_relation, tm_b_dashboard)
(3.7.1)根据租户id查询活跃项目, 遍历项目集合projects。涉及到的表(wi_orm_project)
相关代码:
/** 查询租户下的有效项目 **/
List<OutProjectBaseInfoDto> projects = projectService.getTenantProject(Long.valueOf(tenantId), "1");// 活跃的
(3.7.2)获取项目竞品brandIds包含项目id,通过项目id,爬取时间和brandIds查询项目以及其下的竞品的详单。涉及到的表(tm_b_pro_detail_relation,tm_b_sentiment_detail, tm_b_search_result_detail)
相关代码:
List<OriginProDetail> origins = proRelDao.getOriginProDetail(dto.getProjectId(), crawlDate, brandIds);
(3.7.3)根据项目id查询项目以及其下的竞品的负面历史详单。涉及到的表(tf_b_sentiment_detail_origin)
相关代码:
List<CheckSentimentDetailOrigin> sentimentDetailOriginList = sentimentDetailOriginDao.getCheckSentimentDetailOrigin(dto.getProjectId());
遍历详单数据和负面历史详单数据,如果详单数据的竞品id、渠道、关键词id、url在历史详单数据中存在有相同的,设置详单的负面历史id为负面历史详单数据的SentimentId值、原始正负面为负面历史详单数据的SentimentState值、正负面值为0。
(3.7.4)修改负面历史(tm_b_pro_detail_relation),修改项目概览负面量(tm_b_dashboard)
相关代码:
int num = proRelDao.updateOrigin(origins);
//修改项目概览表的 量
this.updateDashbord(origins, dto.getProjectId(), crawlDate);
(3.8) 修改软文收录量(tf_b_softPaper)
更新软文表中include_baidu和include_sougou和值
相关代码:
dataCheckApp.softInclude(string, crawlDate);
(3.9) 修改负面历史(tf_b_sentiment_detail_origin)
更新负面历史表中state字段的值
相关代码:
dataCheckApp.sentimentDetailOrigin404();
(3.10) 插入项目抓取数据记录表(tf_b_pro_crawl_rel)
通过爬取日期查询tf_b_pro_detail_relation表中的数据list,
遍历list组装项目抓取数据记录表数据。
相关代码:
pinDatabaseApp.insertProCrawlRel(res, crawlDate);
所有租户遍历完分析入库完成