0

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

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

这没有问题,但速度很慢。然后我们看到了这篇文章。与未索引的 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); 进行分页)?

欢迎任何想法。

4

1 回答 1

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,它只是为了展示基本程序)

...是的,它很浪费,但实际上大多数查询都是前几页,所以没那么重要。它的“深度”结果将特别缓慢。

于 2013-10-17T16:22:12.733 回答