php - 这是从 PHP 使用 Sphinx 的正确方法吗?

标签 php mysql search full-text-search sphinx

我刚开始使用 Sphinx。到目前为止,我已经成功安装了它,得到了一个名为 profiles 的表在我的 MySQL 数据库上建立索引,并且能够使用 PHP API 获得正确的结果。我使用的是 CodeIgniter,所以我将默认的 PHP API 封装为 CodeIgniter 库。

无论如何,这就是我的代码的样子:

$query = $_GET['q'];
$this->load->library('sphinxclient');
$this->sphinxclient->setMatchMode(SPH_MATCH_ANY);
$result = $this->sphinxclient->query($query);

$to_fetch = array();
foreach($result['matches'] as $key => $match) {
  array_push($to_fetch, $key);
}

数组$to_fetch包含匹配表行的 ID。现在我可以使用典型的 MySQL 查询来让所有相关用户显示在搜索页面上,如下所示:

$query = 'SELECT * FROM profiles WHERE id IN('. join(',', $to_fetch) . ')';

我的问题是:

  1. 这样做正确吗?或者是否有默认的“Sphinx 方式”可以提高性能。

  2. 其次,我现在得到的只是匹配表行的 ID。我还想要匹配的列中的文本部分。例如,如果某人搜索关键字 dogprofiles 上的用户表在他们的 about列以下文本:

    I like dogs. I also like ice cream.

我希望 Sphinx 返回:

I like <strong>dogs</strong>. I also like ice cream.

我该怎么做?我试着玩弄 buildExcerpts()功能,但无法使其正常工作。

编辑

这就是我现在获取摘录的方式:

// get matched user ids
$to_fetch = array();
foreach($result['matches'] as $key => $match) {
  array_push($to_fetch, $key);
}

// get user details of matched ids
$members = $this->search_m->get_users_by_id($to_fetch);

// build excerpts
$excerpts = array();
foreach($members as $member) {

    $fields = array(
        $member['about'],
        $member['likes'],
        $member['dislikes'],
        $member['occupation']
    );

    $options = array(
        'before_match'      => '<strong class="match">',
        'after_match'       => '</strong>',
        'chunk_separator'   => ' ... ',
        'limit'             => 60,
        'around'            => 3,
    );

    $excerpt_result = $this->sphinxclient->BuildExcerpts($fields, 'profiles', $query, $options);
    $excerpts[$member['user_id']] = $excerpt_result;
}

$excerpts_to_return = array();
foreach($excerpts as $key => $excerpt) {
    foreach($excerpt as $v) {
        if(strpos($v, '<strong class="match">') !== false) {
            $excerpts_to_return[$key] = $v;
        }
    }
}

如您所见,我正在 4 个不同的 mysql 列中搜索每个查询:

about
likes
dislikes
occupation

因此我不知道 4 列中的哪一列包含匹配的关键字。它可以是其中任何一个,甚至可以是多个。所以我别无选择,只能通过 BuildExcerpts() 运行所有 4 列的内容。功能。

即便如此,我也不知道 BuildExcerpts() 是哪一个返回 <strong class="match">标签。所以我运行了一个 stpos检查 BuildExcerpts() 返回的所有值最终获得正确的摘录并将其映射到其所属个人资料的用户。

考虑到我需要匹配 4 个不同列的内容的情况,您认为有比这更好的方法吗?

最佳答案

是的,这看起来不错。要记住从 Mysql 返回的行可能不会按照 sphinx 的顺序排列。

有关如何使用 FIELD() 的信息,请参阅 sphinx 网站上的常见问题解答,但我个人喜欢将 sphinx 中的行放入关联数组,然后循环遍历我列出的 sphinx 并从数组中获取行。以内存为代价完全避免排序阶段!

至于突出显示,是的,请坚持使用 buildExcerpts - 这就是做到这一点的方法。


编辑补充,这个demo http://nearby.org.uk/sphinx/search-example5-withcomments.phps 演示了从 mysql 获取行和在应用程序中“排序”。并建立摘录。

关于php - 这是从 PHP 使用 Sphinx 的正确方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11067537/

相关文章:

MySql、Postgres、Oracle 和 SQLServer 忽略 IS NOT NULL 过滤器

performance - 快速在大型数字矩阵中找到第 n 个最大的产品

php - 使用 SUDZC 的 Objective C 网络服务(带有 php 服务器)

mysql - Sum 列,当满足特定值时,在不同的计数上

php - 无法连接到我的 mysql 数据库

php - 如何从mysql显示平均值

search - 如何使用minimum_should_match 进行多字段搜索?

c - 搜索哈希表不起作用,for 循环不在 c 中执行

javascript - 使用 javascript 将 php 变量发布到移动网站 - 空白变量

php - Laravel 5.2 中的正则表达式验证