Php 优化跨多个文档的句子搜索

Php 优化跨多个文档的句子搜索,php,search,Php,Search,我在优化我用PHP创建的搜索时遇到了问题,这个搜索是一次性使用的,所以灵活性并不是那么重要 我有一系列的句子,比如: $arr = [ 'potato', 'hi my name is Ivan' .. ]; 这个数组包含大约1k个句子 我有一个硬盘,里面有200 GB的文件 我需要搜索所有文件,看看这些句子是否在文件中,如果是的话,以特定格式打印路径、校验和等 我面临的问题是搜索时间,在这样做时,这似乎效率低下: $objections = []; foreach ($f

我在优化我用PHP创建的搜索时遇到了问题,这个搜索是一次性使用的,所以灵活性并不是那么重要

我有一系列的句子,比如:

$arr = [
   'potato',
   'hi my name is Ivan'
    ..
];
这个数组包含大约1k个句子

我有一个硬盘,里面有200 GB的文件

我需要搜索所有文件,看看这些句子是否在文件中,如果是的话,以特定格式打印路径、校验和等

我面临的问题是搜索时间,在这样做时,这似乎效率低下:

$objections = [];
foreach ($files as $file) {

    if (!in_array($file->getExtension(), $allowedExt))
        continue;

    $txt = file_get_contents($file);

    foreach ($words as $word) {
        if (stripos($txt, $word) !== false ||
            stripos($file->getFilename(), $word) !== false
            ) {
            $file->c_md5 = getCMD5($file);
            $objections[] = $file;
        }
    }
}
搜索it本身花费了1个多小时,我正在使用最新i7的新MacBook。使用PHP内存等最大化

在单词数组中匹配哪个单词并不相关,因此我想知道是否有更聪明的方法来执行搜索,而不是在文件循环中循环单词。带OR的很长正则表达式字符串会更快吗


或者有没有第三种方法速度更快。

答案肯定是正则表达式。您可能应该将其分为三个阶段:

  • 将你的句子列表转换成一个大正则表达式或一个要在循环中运行的正则表达式列表。您可以将空格转换为空格
    \s
    ,并使搜索不贪婪
    /regex/U

  • 迭代文件并删除行尾,用空格替换。以防万一,一个句子被分散到多行

  • 使用
    preg_match
    查找该句子是否在文件中。如果决定使用多个正则表达式,可以在循环中执行


  • 正则表达式可以为您节省很少或什么都没有

    你可以在一次打击中突破循环

    Foreach{
        If(hit){
            Break;
        }
    }
    
    这样就省去了其他的搜索。因此,如果您进行第二次迭代,您将不再需要对该文档进行另外998次迭代

    您经常遇到的问题是打开一个文档,毫无疑问,这是您大部分性能将丢失的地方

    如果这是一个需要执行多次的操作,那么可能值得考虑将所有文件索引到为全文搜索而设计的数据库中,例如ElasticSearch。在数据库中,您可以简单地为下一个操作保留对物理文件的引用。
    所有这些文件的初始加载和索引无疑会占用大量资源和时间。但是,一旦完成搜索,您的搜索将非常快。

    您可以使用
    exec

    创建test.php文件并尝试以下代码

      <?php
        exec('grep '.escapeshellarg('end').' '."./test.php",$result);              
        print_r($result);
        /* serach for some sentences
         * keep seraching
         * end of comment */
      ?>
    
    
    

    当然,您必须先测试它的性能,然后根据您的需要定制它

    我不知道大型正则表达式是否会更快,但如果您对如何实现一个正则表达式有想法(您似乎有想法),请尝试一下并进行基准测试。有了这么多的数据,它可能会非常慢。我认为如果你使用regex,你应该有一个大的regex,否则你基本上只是实现了一种更慢的方式来完成原始代码已经完成的工作。正则表达式对于简单的字符串比较是无效的。(但如果你不需要在每个文件上循环每个句子,它会变得更有效)。@MagnusEriksson我同意,一个大的正则表达式应该更好。啊,是的,我忘了添加这个,匹配很少,但是是的,如果def能节省一些时间,那么我会认真考虑实现一个数据库,如前面提到的ElasticSearch。您已经加载了所有文件内容,在数据库中抛出它将是微不足道的,然后搜索将需要几个函数。ElasticSearch的文档很棒。即使是MySQL上的全文搜索也可能更快。很可能,是的。但是,如果您要用这么多的数据填充数据库,那么逻辑上的选择是使用专为这种操作设计的数据库,没有关系数据,很少写入数据。虽然MySQL可能更容易安装。