检查段落中的单词与DB的有效方法是什么?

时间:2010-09-21 13:59:30

标签: php mysql

我有一个名为keywords的表。它很简单,有两列--id和关键字。此表总是在增长,我们总是会向其中添加其他内容。

现在,我们有一个用户提交的2-3句话段落。我们想要检查关键字表中所有关键字在本段中的单词。

最有效的方法是什么?我的初始逻辑在

之下
// explode $paragraph into $words[]

// cycle through $words -- in each loops, SQL statement where $word = keyword

// output any matched keywords

这会是最有效的吗?请记住,关键字表可以是几千行。我应该使用Sphinx搜索解决方案吗?

5 个答案:

答案 0 :(得分:4)

  1. 将用户输入分解为单词。
  2. 查询:

    SELECT id, keyword FROM tbl_name WHERE keyword IN ('word1', 'word2', 'word3', 'wordN');
    
  3. 必须插入尚未返回的单词。

  4. 将检索到的ID与新插入的ID合并,可以为您提供一整套已使用的ID。

答案 1 :(得分:1)

有一系列被排除的单词。 (或者从数据库中提取它,或者其他什么。)

$excludeThis = array(
  'a',
  'the',
  'for',
);

剥去所有的点,斜线等。

$text = preg_replace('/[^A-Za-z0-9]/', ' ', $text);
$text = str_replace('  ', ' ', $text);

分解文字

$words = explode(' ', $text);

根据您的关键字构建您想要匹配的所有字词的数组。

$array = array();
if ( ! empty($words)) {
  foreach ($words as $word) {
    if (in_array(strtolower(trim($word)), $excludeThis))
      continue;

    $array[] = strtolower(trim($word));
  }
}

从数据库中提取您的关键字(您可能实际上想要缓存此...)并且只需使用array_intersect()来匹配您的两个数组。

不知道这是否是最快的方式,但也许有帮助。

答案 2 :(得分:0)

我认为这是正确的方法。但我更喜欢第二张桌子(小得多),你的段落中常常有排除的词语(例如'和','或',''等等......)。从$ words中消除所有这些单词,你可以节省几毫秒。

答案 3 :(得分:0)

这是使用存储过程的绝佳机会。 Crozin的反应会起作用,但我更喜欢在数据库中保留这种逻辑。

理由:

  • 如果您决定在以后添加/删除/重命名列 - 或者如果您有幸在项目中拥有DBA - 那么维护起来会更容易。

  • 如果您是从用户输入生成单词列表,它将有助于防止SQL注入。我将站点的db用户帐户的权限限制为执行存储过程的能力。

在任何一种情况下,逻辑都保持不变。将段落Split换成单词,并使用“in”将关键字列与该列表进行比较。

或者,如果您正在处理大量文本,将结果单词列表拆分并转换为行(可能在临时表中)并从连接中选择可能更有效:

select *
from keywords
join #paragraph_words
on keywords.keyword=#paragraph_words.keyword;

(你必须检查语法,因为我现在没时间验证它。)

集合运算符(如IN)可能不会像连接一样好,但正如我所说,如果你只处理一个短单词列表,那就太过分了。

答案 4 :(得分:0)

多次查询数据库不是最有效的方法。

我猜您可以使用MySQL Full-text search功能来解决您的问题。它不会在高负载下扩展,但对于大多数站点,它将快速完成工作。

如果你想要最优化的解决方案,你应该学习像elasticsearch,solr,sphinx,lucene等产品。因为它们是为了解决这个问题而写的。

相关问题