具有大量属性的Sphinx查询

时间:2013-10-17 06:54:25

标签: php sphinx bigdata

我们有一个很大的索引,大约10亿份文件。我们的应用程序不允许用户搜索所有内容。他们有订阅,他们应该只能搜索它们。 我们的第一次索引迭代使用了属性,因此典型的查询看起来像这样(我们使用PHP API):

$cl->SetFilter('category_id', $category_ids); // array with all user subscriptions
$result = $cl->Query($term,"documents");

这没有问题,但速度很慢。然后我们看到了article。与未编入索引的MySQL查询的类比令人震惊,我们决定放弃基于属性的过滤器并尝试使用全文列。现在,我们的category_id是一个full_text列。事实上,我们的初步测试显示搜索速度要快得多,但是当我们将索引投入生产时,我们遇到了一个问题。有些用户有很多订阅,我们开始从Sphinx收到此错误:

Error: index documents: query too complex, not enough stack (thread_stack_size=337K or higher required)

我们的新查询如下所示:

user_input @category_id c545|c547|c549|c556|c568|c574|c577|c685...

如果类别太多,则会显示上述错误。我们认为只需将thread_stack增加到更高的值就可以很容易地修复,但结果却限制在2MB,我们仍然有超过这个查询。

问题是现在该怎么办?我们考虑将查询拆分为较小的查询,但是我们如何将结果与正确的限制进行汇总(我们使用$ cl-> SetLimits($ page,$ limit);用于分页)?

欢迎任何想法。

1 个答案:

答案 0 :(得分:0)

你可以在应用程序中执行'分页',这就像sphinx在查询分布式索引时的合并方式。

$upper_limit = ($page_number*$page_size)+1;
$cl->setLimits(0,$upper_limit);
foreach ($indexes as $index) {
   $cl->addQuery(...);
}
$cl->RunQueries()
$all = array;
foreach ($results) {
   foreach (result->matches) {
      $all[$id] = $match['weight'];
   }
}
asort($all);
$results = array_slice($all,$page,$page_size)

(我知道它不是完全有效的PHP,它只是为了显示基本程序)

...是的,它浪费,但实际上大多数查询都是前几页,所以这并不重要。它的“深层”结果将特别缓慢。