880 Star 3.6K Fork 1.5K

Discuz / DiscuzX

 / 详情

Sphinx 全文搜索的相关研究

进行中
创建于  
2021-05-15 00:03
  • 这不是一个报错也不是一个需求,只是整理一下研究结果,给后人参考。

我上一次试图折腾 Sphinx 没成功,挂念了很久,前几天在首页看到有人留言询问全文搜索的事情,某 maintainer 甩了一个很容易搜到并且不好用的教程并且附带了一句“毕竟这个功能的用户量比较少”。

嗯 行吧 即使实际上每个人都需要,只要没有教程没人弄得起来,用户量都会很少的。
就像是中国人不需要用 Google 是一样的道理。

反正就下决心把这个东西研究清楚了

正文:

  1. 网上能搜到的大部分文章都是过期和不正确的,用的是很老版本的 Sphinx + Coreseek 插件。
    老版本的 Sphinx 不支持中文分词,于是有国人做了一个插件来支持,这个方案主要问题在于,coreseek 已经凉了很久了 某份fork的最后更新是 7 years ago, 至于上游是什么年代的我已经找不到了,官网也早就挂了。
    而且早期版本的 Sphinx 的 bug 和性能也不太好。
    另外,流传最广的那篇教程似乎也不正确,它的 cron 里引用了 threads_merge 和 posts_merge 的索引,但是给的配置文件里没有定义这俩。即使你搭起来了旧版本的sphinx和coreseek,他也是没办法正常工作的。

  2. Sphinx 后来的版本增加了原生的中文支持,但是做的比较一般,只支持 ngram 模式,就是单字拆分,而不是基于词典。Sphinx 新版本的配置文件区别不大。

  3. Discuz 用的驱动 Sphinx 也已经过期了,搭起来新版本 Sphinx 之后搜不到任何东西,抓包看提示发现返回了一个 Client too old。不过好在这很容易解决,把 Sphinx 服务器包里附送的 php 驱动,改名字替换进 Discuz 里面就好了。
    不过最新版本废弃掉了 SetMatchMode() 函数,好在服务器端依然支持,对照老版本驱动把 这个函数以及用到了的 _mode 变量抄过来,就能正常工作。

  4. 这样子能搭起来个能用的全文搜索,但是如之前所说,Sphinx 的中文分词做的不好,会有例如搜索 “论坛”,而出来的结果中,因为在不同的句子里分别包含了“论”字和“坛”字,而被加入搜索结果。如果你能忍这一点。到这里就已经能用了。

  5. Sphinx3 转为闭源了,有一些开发者不满而 Fork 了一份叫做 Manticore,粗看了一下这个做的比 Sphinx 好,专门为中文分词做了不少支持 https://manual.manticoresearch.com/Creating_an_index/NLP_and_tokenization/CJK
    而且因为是基于 Sphinx 改的,大致上还是兼容的,我还没部署上不过粗看了一眼 php 驱动,类名和函数名都跟原本的类似,可能只要把服务器搭建起来,对接 dz 的部分也能够丢进来直接用。

  6. 我正在研究如何搭建 Manticore,如果有成果会继续分享
    看起来跟 Sphinx 差不多

  7. Discuz 里全文搜索的调用非常集中,只有 search_forum.php:204 这几行,这意味着如果你熟悉任何其他的全文索索引擎,例如 elasticsearch 或者随便什么,把 Discuz 的调用接过来是很容易的,只需要改这一处把他对 Sphinx 的调用接过去就好了,也不一定非要撞死在 Sphinx 这一棵树上。

  8. MySQL 也自带了全文搜索功能,中文分词同样是基于 ngram 机制,跟 Sphinx 一样差。
    但是用它来做一个不需要外置依赖的默认全文搜索机制似乎总比没有好。

评论 (55)

zh99998 创建了任务
zh99998 关联仓库设置为Discuz/DiscuzX
zh99998 修改了描述
zh99998 修改了描述
zh99998 修改了描述
展开全部操作日志

某 maintainer 就是我,这里自投罗网一下。给的教程确实是看过并且感觉相对看到的几篇其他教程算坑少的,但是毕竟没有亲手验证过,而且我也知道这块儿的功能比较坑,所以教程有问题的话我也认(毕竟我自认为除了认错速度还可以之外,也没啥其他优点了)。

搜索这个问题之前探讨过,确实没有找到什么极其好的解决方案,核心问题就是es维护太费力气,sphinx等小而美的分词都半死不活。 ngram 依赖的 MySQL 版本太高,而且还要改建表语句,所以一直犹犹豫豫没上。
另外受限的一点就是 Discuz! X 也没有多少人力去整(就几个人用爱发电,外带应用中心从中协调一部分。)。也欢迎您提供更好的解决方案代码到 X3.5 版本,以继续完善这一块儿,毕竟众人拾柴火焰高。

高就高嘛,还是上次说那个,现在已经没有人真的受制于虚拟主机了,哪怕用面板的也是自己起的面板自己可控的,哪怕你要求php8+mysql8,也都能跑得起来... 趁3.5本来就要改建表升上去吧真的... 不然错过这个机会又要好多年了

在我们发现 Discuz! Q 不太成功之后不太可能继续提高对服务器的要求,尤其是前段时间接待了一些 MySQL 5.6 的用户之后。
可能要改搜索还是会选择接 ES 或者 Sphinx / Manticore ,不知道您这边测试 Sphinx / Manticore 进度如何了,如果能用了可以考虑 PR 上来。

而且 MySQL 的 ngram 在部分场景下还有反向优化,而且 ngram 类的索引还影响写性能,这就更推进我们把全文搜索功能和数据库功能拆分了。
https://www.zengjianfeng.com/2017/06/150.html

zh99998 修改了描述

很感谢DZ的陪伴我渡过快乐时光, 表示很关注 全文搜索功能,我很庆幸自己当年选择DZ 坚持走下去。。。
要不然,自己早已脱离互联网圈了 说多了都是感慨

全文检索这个功能赶紧弄起来啊。折腾了好久也没有搭起来

阶段性记录

  1. manticore 基本是可行的,有内置中文分词相关处理,虽然有些时候结果依然比较扭曲,例如搜索某个它不认识的四字中文词,有可能会因为某篇文章里在四处不同的段落里分别出现这个词而被搜出来。不如 Discuz 自带那个结果好, 但也还算能用了。

  2. manticore 官方提供的 php 客户端直接兼容 Discuz,https://github.com/manticoresoftware/manticoresearch/blob/master/api/sphinxapi.php 覆盖进 source/class/class_sphinx.php 就可以,无需任何改动。

注意官方有两个 php 客户端,还有个 manticoresearch-php,它跟 Discuz 不兼容,别下错。

另外,这个驱动是 LGPL 许可证的,我不清楚它是否适合打包进 Discuz 一起分发。以前的老版本驱动应该也是,但是流氓公司直接打包来并且删了版权信息,换成了 (C)2001-2099 Comsenz Inc.

  1. source/module/search/search_forum.php 中,if($srchtype == 'fulltext' && $_G['setting']['sphinxon']) { 这句是bug,https://www.discuz.net/thread-3495437-1-1.html 这篇文里第 7 条描述的改法是对的。这个改动适合直接合并进上游。

  2. 如果你的论坛是GBK的:
    https://www.discuz.net/thread-3495437-1-1.html 这篇文里提到的 SET NAMES gbk 不正确,这里必须用 utf8,即使你的站点是 GBK 的。我之前浪费了大量时间没折腾成主要是因为这个 (我的站因为在等 X3.5 一直没升级 UTF-8 ,升 UTF-8 丢一次用户安全提问,3.5 来了再升 utf8mb4 又丢一次) 这句话不是指数据库本身的编码,而是 mysql 发给客户端 (sphinx indexer) 的编码。而不管你论坛什么编码 sphinx 总是期望一个 UTF-8 编码的文本来解析的。查询地方在 search_forum.php 里面,也需要转换成 UTF-8 再去查询,这部分那篇文章里写的是对的。这个改动也适合直接合并进上游,不过考虑到 3.5 不打算支持 GBK 了那就也无所谓。

  3. 其他的配置论坛上那篇文里大多是对的
    然后一个值得留意的事是,manticore 官方的 main+delta 模式中,推荐有一个 updated_at 字段和 deleted 字段,用于追踪编辑和删除,这样索引是能完美同步的,updated_at 时间在上次构建索引之后的,会被列入 killlist 把原本的结果去掉。然而,Discuz 并没有提供帖子编辑时间这样的功能,在论坛中看到的 本帖最后由 xxx 于 yyy 编辑 是真的插入了一段文本在正文里。。。。 所以我不推荐使用那个帖子计划任务的章节里写的 merge 的方式,而是周期性的去重做索引,不然编辑和删除就永远同步不过去了。
    参考:
    https://manual.manticoresearch.com/Adding_data_from_external_storages/Main_delta
    https://play.manticoresearch.com/maindelta/
    要是 Discuz 有真正的trace编辑和删除功能就好了,那样就可以正常用回去main + delta + merge 模式,性能会高很多,准确率也好。
    记得高中时候折腾两个站点之间共享某个板块的帖子,也是受限于这一点没办法完美同步。

  4. 这是我写的 conf 文件,跟论坛上那篇大同小异,原理一样,除了中文分词改用 manticore 自带的。
    参考:https://manual.manticoresearch.com/Creating_an_index/NLP_and_tokenization/Supported_languages

searchd {
    binlog_path =
    listen = 9312
    log = /var/log/manticore/searchd.log
    max_packet_size = 128M
    pid_file = /var/run/manticore/searchd.pid
    query_log_format = sphinxql
    query_log = /var/log/manticore/query.log
}

common {
}

source shared {
    type             = mysql
    sql_host         = 
    sql_user         = 
    sql_pass         = 
    sql_db           = 
    sql_query_pre    = SET NAMES utf8
    sql_query_pre    = CREATE TABLE IF NOT EXISTS sph_counter (counter_id INTEGER PRIMARY KEY NOT NULL, max_doc_id INTEGER NOT NULL)
    sql_attr_uint    = tid
    sql_attr_uint    = digest
    sql_attr_uint    = displayorder
    sql_attr_uint    = authorid
    sql_attr_uint    = special
    sql_attr_timestamp = lastpost
}

source threads : shared {
    sql_query_range  = SELECT MIN(tid),MAX(tid) FROM pre_forum_thread
    sql_query        = SELECT tid AS id,tid,subject,digest,displayorder,authorid,lastpost,special FROM pre_forum_thread \
                       WHERE tid>=$start AND tid<=$end
    sql_query_post_index = REPLACE INTO sph_counter set counter_id = 1, max_doc_id = $maxid
}

source threads_minute : shared
{
    sql_query        = SELECT tid AS id,tid,subject,digest,displayorder,authorid,lastpost,special FROM pre_forum_thread \
                       WHERE tid > (SELECT max_doc_id FROM sph_counter WHERE counter_id = 1)
}

source posts: shared {
    sql_query_range  = SELECT MIN(pid),MAX(pid) FROM pre_forum_post
    sql_query        = SELECT p.pid AS id, p.tid, p.subject, p.message, t.digest, t.displayorder, t.authorid, t.lastpost, t.special \
                       FROM pre_forum_post AS p LEFT JOIN pre_forum_thread AS t USING(tid) \
                       WHERE pid>=$start AND pid<=$end
    sql_query_post_index = REPLACE INTO sph_counter set counter_id = 2, max_doc_id = $maxid
}

source posts_minute : shared
{
    sql_query        = SELECT p.pid AS id, p.tid, p.subject, p.message, t.digest, t.displayorder, t.authorid, t.lastpost, t.special \
                       FROM pre_forum_post AS p LEFT JOIN pre_forum_thread AS t USING(tid) \
                       WHERE pid > (SELECT max_doc_id FROM sph_counter WHERE counter_id = 2)
}

index threads {
    type   = plain
    source = threads
    path   = threads

    charset_table    = chinese
    morphology       = icu_chinese
    stopwords        = zh
}

index threads_minute : threads
{
    source = threads_minute
    path   = threads_minute
}

index posts : threads
{
    source = posts
    path   = posts
}

index posts_minute : threads
{
    source = posts_minute
    path   = posts_minute
}
  1. 计划任务
    需要最初和每天执行 indexer --rotate threads posts, 每分钟执行 indexer --rotate threads_minute posts_minute
    我是用脚本跑的,用 crontab 应该也行
    我的脚本:
while :
do
    if (( $(date +%s) >= next )); then
        indexer --rotate threads posts
        next=$(date -d "tomorrow 04:00" +%s)
    fi
    indexer --rotate threads_minute posts_minute
    sleep $(( 60 - $(date +%-S) ))
done
  1. 总结,一共需要做的事:
    8.1 起一个 manticore 服务,我用的官方 docker 镜像。
    8.2 配置文件 manticore.conf
    8.3 计划任务每天和每分钟运行 indexer。初次索引后重启 manticore 服务。
    8.4 下载客户端 https://github.com/manticoresoftware/manticoresearch/blob/master/api/sphinxapi.php 覆盖进 source/class/class_sphinx.php
    8.5 修改 source/module/search/search_forum.php, 对应原帖第7步。这个改动适合直接合并进上游。GBK要额外加个转码。
    8.6 后台配置 sphinx 开启、主机名、端口、最大时间、最大数量。用户组开启全文搜索权限。
    前三步可以打包成一个配置好的docker镜像,4、5步可以合并到上游,这样就只是后台开一下的事了。

刚才仔细找了一下,还有个 post_message 的钩子,感觉如果插件化的话可以和这个钩子融合解决更新索引的问题,当然还是要配合定期重新刷新避免回调失败的情况。

感谢反馈,我们按照这个优化下试试看。

  1. 文件 License 的问题要辛苦 @popcorner 确认一下,感觉 LGPL 的话是不是得走类似 QQ 互联的插件模式发布了,插件 LGPL 开源完了主体要维持康盛授权。
  2. trace编辑和删除 @popcorner 在搞,不过还没完全做完,正在赶进度,不过这是个可选且一般用户不会开的功能。感觉 !902:添加一个钩子可获取编辑前后主题内容与设置可编辑用户 如果能推动合并应该能解决编辑没有响应的问题,在这个钩子上面加一个索引更新的指令给 manticore 感觉也行(见下方),不知道 manticore 能否支持单个主题或者帖子更新。
  3. 多问一句, UTF8 到 UTF8MB4 不会丢安全问题吧,毕竟只是编码扩容,升级程序对于 UTF8 到 UTF8MB4 也是默认不清理安全提问的,当然都现在了也别折腾 GBK->UTF-8 了,等正式版本吧。
  1. 历史文件不方便考据的话可能就维持现状了吧,但是要新加入的话可能确实需要维持原license。
    关于许可证问题我查证了一下,LGPL并不是GPL,它是允许非自由软件动态链接到上面去的。
    问题在于PHP语言没有这种概念。继续查证GNU方面的官方解释发现,他们认为当LGPL库可以被用户自行替换成新版本并且可以修改调试(保证库部分的自由),就符合要求。按这个标准来看内嵌应该是没有问题的。
  2. 编辑时间戳是一个全量开放的功能,不会有开关,只是不会对历史数据生效。加开关的是历史记录功能。
  3. 我感觉也是,不过x3.4上折腾编码确实是不方便。

顺便备注一下曾经讨论过的其他已知全文搜索方案:

  1. elastic search,应用广泛方案成熟,已有案例,缺点是比较吃资源,一般的站点玩不起来
  2. xunsearch,国产项目,资源占用不大,中文支持不错,已有插件及案例:
    https://addon.dismall.com/plugins/twpx_xunsearch.html
    https://www.dismall.com/thread-3171-1-1.html
    但此软件高级功能付费才能获得,对大站点来说有局限
  3. sonic,此方案由oldhu提出
    https://github.com/valeriansaliou/sonic
    rust语言编写,非常省内存资源,轻量级搜索,性能很好
    提出时(2020/6/10)对中文的支持并不够好(没有分词),但最新版本已加入jieba分词
    https://github.com/valeriansaliou/sonic/blob/master/CHANGELOG.md
    但目前尚未发现实际案例,且从历史记录来看此软件的更新频率不怎么样

那看来内嵌新版本的库并改 Manticore 问题不大。可以考虑先替换了库保证 X3.5 可以跑起来,另外找点测试网站看看 Manticore 运行的效果,后续版本再考虑接入 ES 之类的,甚至可以改成插件扩展方便第三方接入其他库。

但是需要考虑一个问题就是,之前已经在用sphinx老体系的用户该如何处理的问题。
毕竟原来的体系虽然老了点但并不是不能跑,而且这块是有现存用户的。

您看下 https://gitee.com/laozhoubuluo/DiscuzX/commits/fix/v3.5/sphinx_search

我感觉替换这个库相当于升级了客户端(因为 Manticore 相当于是从 Sphinx v2 的 Fork 版本,详见 https://github.com/sphinxsearch/sphinx 仓库),感觉问题不大(当然 FID 的 filter 是个问题,如果完全按照老教程走的用户需要调整索引脚本添加 FID 的索引)。如果不放心的话就 fork 一个 Manticore 或者 sphinxnew ,完了给个 option 可以切换版本就行。

看了下这个变更,好像确实应该不会有兼容方面的问题?那直接改应该就行

感觉也是,反正这个也确认放 X3.5 这个允许 BC 的版本了,万一极个别站点不行就指导他们把文件改回去或者换 Manticore 呗。

换 Manticore 倒是不能做备选项存在,当年的 sphinx 中文相关插件基本都没有维护了,指望能原样迁移过来几乎不可能。

全文搜索倒是不怕,ICU dictionary based / ngram-based 倒也能承担大部分需求了。
就怕有一些比较特殊的用法,要不让 @湖中沉 帮忙放个问卷在后台做下用户调研,约谈一下用户了解下他们是怎么搞的?

不行吧?我印象里好像自定义词库都是个问题

也是,这个需求在折腾 Sphinx 的站长这个级别里面可能这种优化也不算太小众,感觉还是后台发问下稳妥,或者直接留下老版本的库并且老版本也不查询 TID 索引保证老配置能完美继承。

很方便考据,manticore 是 sphinx 的 fork,repo 里维持了旧 sphinx 的完整 commit 记录,只要翻一下就知道了。那个api文件自古以来是 GPL 的,2015年的时候切到了 LGPL 至今。
切换的时候的那一个 commit
https://github.com/manticoresoftware/manticoresearch/commit/8c3df903f594288cd17e7475e43af63087d0e46e#diff-8d37cd1805f5224d4b7ce2153250b36e127002f352bbbc0353b44fb6ce46c95e

关于编辑时间戳的问题昨天没看到,补充下。

那就太好了,等编辑时间戳正式上线之后就可以让楼主看看怎么对接 sphinx 了,免得重复索引。
这个调整应该对老版本不影响,老版本还是可以定期重做索引解决。

不方便考据的指的不是manticore,而是Discuz历史上作为一个商业产品,曾经的相关授权情况比较难以查证。

这个倒是不用考虑,Comsenz 没有可能买 Sphinx 的库授权。

这可不好说,毕竟以前有的flash就是用的商业版组件打包的

商业版组件也不敢说是正版吧,不过确实难以说清楚就是了。

发现一个坑,Discuz 走 sphinx 的那个分支代码,没设置板块的filter,无论搜索选项里板块选哪些,实际总会搜所有。

post 导入的 filter 里面好像也没有加入 FID ,我 PR 草稿里面加了 FID 查询,您这边测试一下看看能否用吧。
另外吐槽一句,这库写的真是不修边幅,TAB 错乱的我强迫症都犯了,考虑到 LGPL 还不太好下手改(其实是我懒)。
https://gitee.com/laozhoubuluo/DiscuzX/commits/fix/v3.5/sphinx_search

似乎不行,我这边报 invalid attribute '(null)' set length 0 (should be in 0..4096 range)

改了一下,昨天忘记把字符串转换成数组了,辛苦再试一次。

输入图片说明
不行,并且变得奇怪了。

配置 https://code.mycard.moe/mycard/docker-manticore/-/blob/55f5daf259e70ca27ef8bc7e4b1e5959b8a9da8f/manticore.conf
输入图片说明

论坛那边的修改,没直接起3.5,就改了这一句
输入图片说明

看着没问题,想确认一下改完重建索引了么?
不行我拉个docker下来试试吧,感觉有点玄学了。

push 到 github 和 dockerhub 了。

mycard/discuz-sphinx,参考下面的 docker-compose.yml 直接起就好了

留个 github id 给你加 collaborator 吧

确实是代码问题,传给 sphinx 的参数多了引号,去掉就正常了,我测试站数据太少了,您再试试。

https://code.mycard.moe/mycard/docker-manticore

我做好了一个 dockerfile,配置文件和 cron 都打包进去了
推荐的 docker-compose.yml 如下

  sphinx:
    restart: always
    image: 
    ulimits:
      nproc: 65535
      nofile:
         soft: 65535
         hard: 65535
      memlock:
        soft: -1
        hard: -1
    volumes:
      - /etc/localtime:/etc/localtime
    environment:
      sql_host:
      sql_user:
      sql_pass:
      sql_db:

之后后台填主机名 sphinx 端口 9313 就可以

然后我要确认一下,如果我把这套整理到标准的 github -> dockerhub 流程,并且写好 README,官方是否会在推荐的安装流程下直接引用我的 repo 和镜像。如果会的话我就整理过去。如果我无论怎么做官方都一定要自己维护 repo 而不引荐任何三方东西的话那我就懒得整理了。

这份配置跟之前的相同,还没有包括 fid 的部分,我去起个带 fid 的 dz 试一下。

关于引用第三方 repo 、镜像的问题,需要让 @湖中沉 帮忙确认一下能否做,这个我说了不算的,毕竟我也只是个开发者。

个人感觉如果是免费的第三方内容(不绑定或者引荐收费服务)是可以引用的。

收到,回头试试
备注一份测试环境启动脚本(测试环境无 Docker Compose),免得忘了。

docker run \
  --detach \
  --name discuz-sphinx \
  --publish 9312:9312 \
  --restart unless-stopped \
  -e sql_host=10.6.1.21 \
  -e sql_user=root \
  -e sql_pass=123 \
  -e sql_db=20220130 \
  mycard/discuz-sphinx:latest

我们和 @湖中沉 讨论了一下,可以在后续上线的文档站的相关章节提供文档的放置位置(现阶段放在 https://gitee.com/Discuz/DiscuzX/wikis/ 的技术文档章节以及 www.dismall.com 论坛教程版,后续新文档站上线之后迁移),技术文档可以按照 Docker Compose -> Docker -> 手动安装(可以只提供配置文件和大概流程)组织,可以引用您的 Docker 和 GitHub 仓库,但是我们也有几个注意事项。

  1. 镜像和文章不带任何收费推广(例如推荐或提供收费产品或服务)且链接的插件或者镜像以及其附加资源本身不能收费(包括免费版镜像捆绑推销商业版付费镜像)。
  2. 文章的授权协议与新文档站文档协议一致,镜像需要明确指定一个开源协议(MIT / Apache2 / GPL 类都可以)。
  3. 我们保留下架或替换链接的可能性(包括但不限于未来出现了更好的技术方案,出现安全问题等)。

这东西搜索结果还是 有点糟糕,开了几天用户反馈不好,搜不到想找的东西了。就只好又关掉了............

好像 MCBBS 那边的 ES 反馈也一般,不知道为啥,这个搜索确实是挺奇怪的,莫非 Sphinx 和 ES 还不如 MySQL ......

大概猜一个原因,原始的mysql是like,我搜abcd就必须有abcd才会进入结果,而那些全文搜索引擎不是这样。
如果它认为 ab 是一个词,c是一个词,d是一个词。那么只要包含他们其中之一的就都会进结果,(也可能是全部都有才会进,但是至少一定是不要求连续的abcd)。

然后它又有个评分模式,我不知道这个确切是什么行为,是不是说连续abcd评分最高,然后分别有ab,c,d的评分就低一些,然后只有ab,c没有d的就更低。如果是这样的话,按评分做个排序就还ok的,但是discuz自己有排序功能,按最后时间排序了。导致搜出来第一屏里发现若干只有c的。但是我搜的是abcd。

然后猜两个解决方案

  1. 默认按评分排序
  2. 要求sphinx包含所有关键字才返回结果

或者后台切换为 BM25 模式

还是不对,我仔细检查了一下结果,它里面确实包含每一个关键字,但是是分散的.... 就是我搜 abcd 结果里面,ab,c,d,全都有了。但是 abcd 的并不会排到前面所以还是搜不到。
要怎么精确的搜必须连续的 abcd 呢,排除分开的。或者把连续的排在分开的前面

我查了一下按照 weight 排序,更复杂点感觉可以把 lastmod 字段也放进去,不过感觉这么写也够用了

$s->setSortMode(SPH_SORT_EXTENDED, "@weight DESC, @id DESC");

这个没有用的吧,他后面被discuz重排过,搜索的时候有个排序选项,默认是按回复时间

尝试改了一下 强制让走 sphinx 返回的顺序了 不过不知道成不成

详细聊一下外面教程上那个 search_forum.php 的改动,我可能猜到当年那么写的意图了。

首先基于这样一个假设:
sphinx 搜索结果它是比 mysql 直接查要烂的。mysql like 查询能保证结果是正确的,有的就一定在里面,没有的就一定不在。而 sphinx 不能。

于是最追求质量的解决方案可能是不上 sphinx 直接用 mysql 抗全文搜索。
其次是把非全文的搜索用 mysql,全文的给 sphinx。
最性能的是全文和非全文都给 sphinx。

按照现行 discuz 的代码,可以看出它是想做最后一种,sphinx 里分别建立了全文和非全文的两种索引,凡是开了 sphinx 就所有搜索都走 sphinx 了。

我前面根据论坛上建议的修改,也建议说直接改成那这样子,这是欠缺思考的。

看了 sphinx 的结果比 mysql 差之后,我认为那个改动可能是个补丁,就是通过一个错误的判断,把标题搜索丢回给了 mysql,这样会降低一些性能,换取非全文搜索的质量。

但是这种简单粗暴的改法显然是,不太合适的,他并没有在后台提供相应的解释,还是要求用户分别建立全文和非全文两套索引,然后非全文索引永远不会使用。代码里也有很多垃圾的部分来混淆。

可能的解决方案:
上策 正面刚 sphinx 搜索质量,调到不比 mysql 差,然后像最初设计的一样把所有搜索丢给 sphinx,性能最好。
中策 给用户解释这件事,让用户自己选择配置两个索引还是一个,然后根据后台用户有没有填上对应的索引名字来决定丢给 sphinx 还是 mysql。
下策 设计成 sphinx 就只负责全文,非全文的代码和索引配置正式删掉。

是的,不过优化搜索质量感觉是个很头痛的问题。

其实我觉得,只要把搜索的一句话拆分成多个断句,用php实现空格自动分开的话,效果也不比全文搜索差了。。。标题多打上关键词就好

什么时间,discuz全文搜索功能可以上线就好了,虽然现在有全文搜索,但只能搜索到标题,帖子内容和文章内容是搜不到的,比较鸡肋蛋疼。快点上线啊,这个做不好吗?

老周部落 任务状态待办的 修改为进行中

登录 后才可以发表评论

状态
负责人
里程碑
Pull Requests
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
开始日期   -   截止日期
-
置顶选项
优先级
参与者(7)
1773794 laozhoubuluo 1594507411 372317 zh99998 1594435903 73465 cc12655 admin 1578916332
PHP
1
https://gitee.com/Discuz/DiscuzX.git
git@gitee.com:Discuz/DiscuzX.git
Discuz
DiscuzX
DiscuzX

搜索帮助