当前位置:网站首页>MongoDB - 千万级数据脚本过滤笔记
MongoDB - 千万级数据脚本过滤笔记
2022-07-30 07:08:00 【stark张宇】
概述
根据业务部分的需要,有一部分用户对进行刷评论来获取成就的行为,所以对全量评论对不合格的运算,进行标记,全量评论大概有2450w左右,之前的评论使用Mysql进行分表处理,后台使用MongoDB进行数据聚合,大概情况是这样。
1.使用分页处理
$where['status'] = 1;
$page = 1;
$limit = 1000;
while (true) {
$listData = Nosql_Comment_NovelMongoDB::getInstance()
->getCommentListByConditionAndPage($where, $page, $limit);
if (!$listData) {
echo '执行结束';
break;
}
foreach ($listData as $item) {
$flag = 0;
$bool = Service_Comment_Tools::checkRepeatContents($item['content']);
if($bool === false){
$flag = 1;
}
$nid = intval($item['nid']);
$id = intval($item['id']);
Nosql_Comment_NovelMongoDB::getInstance()->updateFilter($nid, $id, $flag);
}
$page++;
}

每次处理1000条,时间倒序处理,结果不理想,当跳过292万的时候,需要8秒,时间太长了,后来找到原因是这样的,skip 跳过少量数据没有问题,但是跳过100万,意味着要先找到100万条数据然后扔掉,越到后面跳过越多,数据库计算量越大,需要想办法优化。
2.精确mongo条件,使用主键对数据进行更新
添加了时间区间、状态、礼物等条件尽量的去掉不合适的数据。
$where['status'] = 1;
$where['begDate'] = strtotime('2018-01-02 12:17:03');
$where['endDate'] = strtotime('2017-07-20 11:24:05');
$limit = 1000;
while (true) {
$listData = ChangpeiNosql_Comment_NovelMongoDB::getInstance()
->getHistoryComment($where, $limit);
if (!$listData) {
echo '执行结束';
break;
}
foreach ($listData as $item) {
$flag = 0;
$bool = ChangpeiService_Comment_Tools::checkRepeatContents($item['content']);
if ($bool === false) {
$flag = 1;
}
$_id = $item['_id'];
ChangpeiNosql_Comment_NovelMongoDB::getInstance()->updateFilter($_id, $flag);
}
$lastData = end($listData);
$where['endDate'] = (int)$lastData['create_time'] + 1 ;
}
在更新MongoDB时,查询日志一切都ok,可以判断,应该就是更新消耗时间了,下一步,对更新进行优化。更新慢的原因是 update 是包含 select 的 先要找到再改,使用主键最快,可以进行批量修改
public function updateFilter($_id, int $flag)
{
$update['filter_status'] = intval($flag);
$count = 0;
if ($update) {
$query = [
'_id' => $_id
];
$res = $this->_client->updateOne($query, [
'$set' => $update
]);
$count = $res->getModifiedCount();
}
return $count;
}
一波三折,2450w的数据终于跑完了,任务也算圆满结束了,对Mongo操作的类库进行了脱敏处理,有需要的同学可以点击查看 https://github.com/stark0824/php7_mongo
边栏推荐
猜你喜欢

MySql Detailed Basics

How to calculate the daily cumulative capital flow one by one in real time

MagicDraw二次开发过程

ipset restore命令维护set,但原已存在的条目未删除掉

Limit injection record of mysql injection in No. 5 dark area shooting range

SQL窗口函数

潜心打磨,主动求变——这群技术排头兵,如何做好底层开发这件事?

Alibaba Cloud Cloud Server Firewall Settings

42.【vector简单列题】

SwiftUI SQLite 教程之 构建App本地数据库实现创建、读取、更新和删除(教程含完成项目源码)
随机推荐
General Lei's personal blog to see
Keil compile size and storage instructions
【day5】数组
如何实时计算日累计逐单资金流
taro package compilation error
go : delete database data using grom
MySql Detailed Basics
动态规划专栏
sql 引用变量时第一位的0被去除掉如何处理
【Kotlin 中的类和继承】
The blockbuster IP that has been popular in the world for 25 years, the new work has become a script paradise
tabindex attribute of input tag & tabindex attribute of a tag
【防作弊】Unity防本地调时间作弊
LSF提交作业命令--bsub
stack containing min function (js)
mysql URL链接
申请内存,std::transform和AVX256指令集用例和执行速度比较
Mybitatis related configuration files
Limit injection record of mysql injection in No. 5 dark area shooting range
redis的内存淘汰策略