千家信息网

sphinx怎么实现多表查询

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,这篇文章主要讲解了"sphinx怎么实现多表查询",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"sphinx怎么实现多表查询"吧!sql_query =
千家信息网最后更新 2026年11月03日sphinx怎么实现多表查询

这篇文章主要讲解了"sphinx怎么实现多表查询",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"sphinx怎么实现多表查询"吧!

sql_query = SELECT `id`, 2 AS table_id, `username`, `password`, `email`, `salt`, `from` FROM table_2

  1. ["matches"]=>

  2. array(16) {

  3. [0]=>

  4. array(3) {

  5. ["id"]=>

  6. string(2) "68"

  7. ["weight"]=>

  8. string(1) "2"

  9. ["attrs"]=>

  10. array(1) {

  11. ["table_id"]=>

  12. string(1) "2"

好吧,我又无聊了 Orz

之前搭建的裤子库是单表的,建索引的时候也没考虑什么后续扩展,有小伙伴表示要玩多表查询,于是研究了下……

为嘛不用增量索引呢?本来一个表就10G多够大了,而且增量索引还得不时添加&合并索引……只是本机搭着玩玩,还是算了吧。

翻到一篇文章,里面说到了配置文件里的继承和重载,对于添加多个数据源还是挺有帮助的,摘抄下:

定义父类email

source email {     ....}

定义子类subemail继承email类的所有设置:

source subemail : email { #除了source,index也可以使用继承    ....}

子类中可以重载email中的设置

source subemail : email {    sql_host      = www.ibos.com.cn    #重载主机    sql_query    = SELECT * FROM subemail    #重载sql_query语句}

其实继承很少被使用到,但有一个很实用的例子就是有很多数据源使用同一数据库的时候,继承就派上用场了

source setdb {     #setdb类只实现连接数据库    sql_host                  =     localhost    sql_user                  =     root    sql_pass                  =     root    sql_db                     =     ibos    sql_port                   =     3306}souce email : setdb{    #继承setdb类    sql_query = ...        #直接写查询语句,而不用再写数据库信息}souce diary : setdb {    sql_query = ...  } souce article : setdb {    sql_query = ...  }souce forum : setdb {    sql_query = ...  }

然后我在上一次的配置文件基础上改了改,加上了另一个表做数据源。
但是在改 php 文件时发现个问题:之前的源码里用的是 $sql = "select * from table_1 where id in($ids)" ,现在加了另一个表以后就不好搞了。

因为两个表的 ID 字段都是从 1 开始自增的,如果用多表 Union 的话可能把两个表中的同一个 ID 的行取出来。有个解决办法就是把第二个表 ID 的自增起始数值改成第一个表 ID 的结束数值-- 不过这个方法只适用极少的情况……

接着百度了很久无果,谷歌也搜不到…… 后来把搜索关键词换为 coreseek indexes in different tables 就搜到一大堆了 Orz

根据这个 Using Sphinx with PHP with multiple indexes 的回答,把配置文件重新改了下:

#源定义source table_1{    type                    = mysql    sql_host                = localhost    sql_user                = test    sql_pass                = test    sql_db                    = sed    sql_port                = 3306    sql_query_pre            = SET NAMES utf8    sql_query                = SELECT `id`, 1 AS table_id, `username`, `password`, `email`, `salt`, `from` FROM table_1    sql_attr_uint            = table_id         #从SQL读取到的值必须为整数    #sql_attr_timestamp        = date_added  #从SQL读取到的值必须为整数,作为时间属性    sql_query_info_pre      = SET NAMES utf8                                        #命令行查询时,设置正确的字符集    sql_query_info            = SELECT * WHERE ID=$id #命令行查询时,从数据库读取原始数据信息}source table_2 : table_1{    sql_query = SELECT `id`, 2 AS table_id, `username`, `password`, `email`, `salt`, `from` FROM table_2}#index定义index table_1{    source            = table_1    #对应的source名称    path            = E:/SQL_DATA/coreseek/var/data/table_1 #请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...    docinfo            = extern    mlock            = 0    morphology        = none    min_word_len        = 1    ondisk_dict     = 1    html_strip                = 0    #中文分词配置,详情请查看:http://www.coreseek.cn/products-install/coreseek_mmseg/    #charset_dictpath = /usr/local/mmseg3/etc/ #BSD、Linux环境下设置,/符号结尾    charset_dictpath = E:/SQL_DATA/coreseek/etc/ #Windows环境下设置,/符号结尾,最好给出绝对路径,例如:C:/usr/local/coreseek/etc/...    charset_type        = zh_cn.utf-8}index table_2 : table_1{    source = table_2    path =  E:/SQL_DATA/coreseek/var/data/table_2}#全局index定义indexer{    mem_limit            = 1024M}#searchd服务定义searchd{    listen                  =   9000    read_timeout        = 5    max_children        = 30    max_matches            = 1000    seamless_rotate        = 0    preopen_indexes        = 0    unlink_old            = 1    pid_file = E:/SQL_DATA/coreseek/var/log/searchd_mysql.pid  #请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...    log = E:/SQL_DATA/coreseek/var/log/searchd_mysql.log        #请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...    query_log = E:/SQL_DATA/coreseek/var/log/query_mysql.log #请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...    binlog_path =                                #关闭binlog日志}

所以给返回的 matches 加个 table_id 的属性就好了,建好索引后查询时 matches 返回值类似这样:

["matches"]=>  array(16) {    [0]=>    array(3) {      ["id"]=>      string(2) "68"      ["weight"]=>      string(1) "2"      ["attrs"]=>      array(1) {        ["table_id"]=>        string(1) "2"      }    }    [1]=>    array(3) {      ["id"]=>      string(3) "350"      ["weight"]=>      string(1) "2"      ["attrs"]=>      array(1) {        ["table_id"]=>        string(1) "1"      }    }

需要注意的是如果之前有把 searchd 注册成服务的话要记得换个端口……

最后改一下用于搜索的 PHP 文件(渣代码勿怪…):

SetServer('127.0.0.1', 9000);    $cl->SetConnectTimeout(3);    $cl->SetArrayResult(true);    // 设置是否全文匹配    if (!empty($_GET) && !empty($_GET['f'])) {        $cl->SetMatchMode(SPH_MATCH_ALL);    } else {        $cl->SetMatchMode(SPH_MATCH_ANY);    }    if (!empty($_GET) && !empty($_GET['p'])) {        $p = !intval(trim($_GET['p'])) == 0 ? intval(trim($_GET['p'])) - 1 : 0;        $p = $p * 20;        // 我在sed.conf 设置了最大返回结果数1000。但是我在生成页码的时候最多生成20页,我想能满足大部分搜索需求了。        // 以下语句表示从P参数偏移开始每次返回20条。        $cl->setLimits($p, 20);    } else {        $cl->setLimits(0, 20);    }    $res = $cl->Query("$Keywords", "*");    //var_dump($res);    @mysql_connect("localhost", "test", "test"); //数据库账号密码    mysql_select_db("sed"); //数据库库名名    mysql_query("set names utf8");    $tables = ['table_1', 'table_2'];  //把表名放入数组    function getResult($id, $table)    {            $sql    = "select * from {$table} where id = " . $id;            $result = mysql_query($sql);            while ($row = mysql_fetch_array($result)) {                echo "" . $row['username'] . "";                echo "" . $row['email'] . "";                echo "" . $row['password'] . "";                echo "" . $row['salt'] . "";                echo "" . $row['from'] . "";            }    }    if ($res["total_found"]) {        $num = $res["total_found"];    } else {        $num = 0;    }}?>   The Web of Answers                         

找到与 {$Keywords} 相关的结果 {$num} 个。用时 {$res['time']} 秒。
"; echo "
"; if (is_array($res["matches"])) { foreach ($res["matches"] as $docinfo) { $table_id = $docinfo['attrs']['table_id']; getResult($docinfo['id'], $tables[$table_id - 1]); } } echo "
Username Email Password Salt From
"; } else { if (!empty($_GET) && !empty($_GET['q'])) { echo "
找不到与 {$Keywords} 相关的结果。请更换其他关键词试试。
"; }}?>

感谢各位的阅读,以上就是"sphinx怎么实现多表查询"的内容了,经过本文的学习后,相信大家对sphinx怎么实现多表查询这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

数据 查询 数据库 文件 索引 路径 实际 配置 就是 数据源 时候 结果 语句 学习 搜索 不用 两个 信息 关键 关键词 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 上海挚品互联网科技有限公司 重生之互联网科技帝国 港股互联网科技股 没上市的科技互联网公司 互联网科技论文 猫创互联网科技 无锡溥仪互联网科技有限公司 互联网科技公司招聘 卫星互联网科技股票 西藏七维空间互联网科技有限公司 互联网科技寓意 随着互联网科技发展 金融科技与互联网金融相同和不同 乌苏新华互联网科技做什么的 上海京穆互联网科技有限公司 智帮互联网科技公司最近动向 城市宝互联网科技有限公司 领航科技大厦互联网公司 广州互联网高科技取餐柜 互联网科技自媒体灵感 万易互联网科技有限公司 广州紫鲸互联网科技 互联网科技公司名称 人人互联网科技是培训 互联网金融中的现代科技 崇明区互联网教育科技诚信经营 崇明区互联网教育科技售后服务 无锡工业互联网科技有限公司 云鲸互联网络科技有限公司 互联网领先科技活动
0