gpt4 book ai didi

php - 删除时的光标问题

转载 作者:可可西里 更新时间:2023-11-01 10:44:17 25 4
gpt4 key购买 nike

mongodb 没有 ->remove()->limit()。这就是为什么我使用我的小脚本来解决任务。

<?php
$conn = new Mongo('127.0.0.1');
$db = $conn->experimentDB;
$experimentCollection = $db->experimentCollection;
foreach($ruleset AS $ruleset_item)
{
$max_remove_loops=3;
$max_limit_per_loop=1000;
MongoCursor::$timeout = 1*60*1000;
for($remove_loops=0;$remove_loops<$max_remove_loops;$remove_loops++)
{
if(!TEST)
$cursor = $experimentCollection->find($ruleset_item)->limit($max_limit_per_loop);//->skip($remove_loops*$max_limit_per_loop);
else
$cursor = $experimentCollection->find($ruleset_item)->limit($max_limit_per_loop)->skip($remove_loops*$max_limit_per_loop);
$items=0;
foreach($cursor AS $cursor_item)
{
//print_r($cursor_item['_id']);
print('.');
if(!TEST)
$experimentCollection->remove(array('_id' => $cursor_item['_id']));
$items++;
}
if($items==0)
{
break;
print(' that was the last one. DONE ');
}
//$cursor->reset();
}
}
?>

这结束于

Fatal error: Uncaught exception 'MongoCursorTimeoutException' with message 'cursor timed out (timeout: 60000, time left: 0:0, status: 0)'

这就是为什么我尝试使用 max_remove_loops 和 max_limit_per_loop 拆分任务并将 max_limit_per_loop 更改为 1min、1h、2h 等。

但是,似乎还有另一个问题导致脚本在删除数百次后挂起。有时在 200-2000 之间的任何地方。 (通过 print('.') 计算)

这看起来像是一个随机错误,取决于 mongodb 必须管理的其他任务、RAM、CPU 负载。

只是一个猜测,但如果循环正在捕获已在队列中稍稍延迟删除的相同游标,则可能会因为删除而造成麻烦?

如何修复此脚本以容错并继续而不是挂起?

最佳答案

这里可以做一些改进。

对于初学者来说,您的脚本只访问每个文档的 _id 字段。因此,您可以在投影中显式包含 _id 字段,并隐式排除所有其他字段(即 MongoCollection::find() 的第二个参数)。 db.collection.find() 中也对此进行了描述文档。投影有助于限制从服务器发回的数据量。

此外,您应该确保您在此脚本中发出的查询已编入索引。当您使用较大的跳过偏移量时,MongoDB 首先执行查询,然后单独遍历结果,直到跳过给定的数字并开始返回结果。对于未索引的查询,遍历磁盘上的文档可能是一个非常缓慢的过程。根据跳过的大小,索引查询甚至可能很慢。使用限制/跳过进行分页的另一种方法是使用范围查询,您可以从大于或小于您上次看到的值的值中获取。如果您对这种方法感到好奇,我会引导您访问 this recent answer ,其中包含有关该主题的一些链接。

为了调试查询并确定它们是否被索引,您可以使用 MongoCursor::explain() .可以在 cursor.explain() 中找到有关其返回值的其他文档(例如如何确定查询是否已编入索引)文档。

最后,我建议重构您的脚本,以便在删除任何内容之前先收集要删除的 ID。假设您的 ID 是 12 字节的 ObjectId(PHP 中的 MongoId 对象),将它们收集到数组中应该没有问题。这将允许您在没有任何限制/跳过业务的情况下遍历查询的所有结果。之后,您可以发出一系列单文档删除,或者使用 $in 发出一个或多个删除。运算符一次匹配多个 ID。

关于php - 删除时的光标问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17745716/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com