【问题标题】:Searching string for multiple keywords efficiently PHP有效地搜索多个关键字的字符串 PHP
【发布时间】:2013-09-14 23:19:46
【问题描述】:

我目前正在尝试使用 1000 个关键字每秒搜索多个字符串。直到最近,使用一些我可以发布的正则表达式一切都很好,但可能非常糟糕。我可以使用哪些方法?我读过一些关于 trie's 的文章,但不确定这些是否适合我的需要?

// 100 strings per second
// 100 characters long average
foreach ($stringSet as $haystack) {
    // 10000 keywords
    // 10 characters long average and can be multiple words
    $matches = stringContains($needles, $haystack)
    // Do stuff with matches
}

正则表达式(不太适合以前的代码,因为那是一种伪):

function stringContains($needles, $haystack) {
    $matchingTerms = array();
    $matches = array();
    foreach ($needles as $needle) {
        $needle = preg_split('/([^[:alnum:]])+/u',$needle);
        $needle = implode('',$needle);
        $needle  = preg_split('/(?<!^)(?!$)/u', $needle);
        $pattern = implode('[^[:alnum:]]*', $needle);
        $pattern = '/\b'.$pattern.'\b/iu';

        preg_match_all($pattern, $haystack, $matches);
        foreach ($matches as $match) {
            $matchingTerms = array_merge($matchingTerms, $match);
        }
    }
    return $matchingTerms;
}

【问题讨论】:

  • 了解更多问题参数会有所帮助。干草堆经常更换吗?它们总是一样吗?为什么有这么多关键词?如果蛮力全文搜索太慢,那么您需要进行优化,而优化就是您可以处理哪些妥协。
  • @NickC 是的,我每秒收到大约 100 个干草堆,每个大约有 100 个字符,需要与 1000 个关键字进行比较。
  • 也许你可以尝试使用数据库来实现这一点,因为数据库搜索比 PHP 快一点
  • @MichaelMitch 我目前使用 redis 作为我的主数据库,所以你知道任何现有的解决方案吗?
  • 我会用管道分隔符分解和分隔你的单词边界。

标签: php regex


【解决方案1】:

可能类似于以下内容。

function stringContains($needles, $haystack) {    
   $matchingTerms = array();
   $matches = array();

   foreach ($needles as $needle) {
      $pattern = "/\b(" . implode('|', $needle) . ")\b/i";
      $found   = preg_match_all($pattern, $haystack, $matches);

      if ($found) {
        $keys = array_unique($matches[0]);
        foreach ($keys as $key) {
           $matchingTerms = array_merge($matchingTerms, $key);
        }
      }
}

【讨论】:

  • 谢谢,我会尽快尝试。你的意思是,但该 for 循环中的所有内容。不确定它是否能提供我需要的性能提升,因为这个函数需要每秒调用 100 次,至少有 1000 个关键字。
  • 试试看会发生什么。这是你的循环应该包括的所有内容。
  • 感谢 hwnd,这带来了一点点不同,所以现在队列的增长速度没有那么快,但它仍在增长。我需要一个非常聪明的解决方案,比如树搜索之类的
  • 另一种方式是把数据库上的集合变成字段类型的文本,实现全文搜索,速度更快,结果也更准确。
猜你喜欢
  • 2020-12-21
  • 1970-01-01
  • 2011-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-28
  • 1970-01-01
相关资源
最近更新 更多