NodeBB 10: 搜索很难(1)

Posted by River Yang on 2016-12-09

在 NodeBB 的官方博客上看到这篇文章: Searching is hard… Pt. 1, 嗯,这是 Part 1, Part 2 等了几年还没出来! 目前 NodeBB 搜索中文还有点残,几不可用,可见搜索真的很难! 本文不是对 Julian 那一篇文章的翻译,只是我自己的一点有感而发,以及我对于搜索的一点经验和看法,或许微不足道,看者请不吝赐教!

NodeBB 官方的搜索很难用,怎么办呢? 目前我有两种解决方案:

  1. 使用 SolrSolr 是 Java 下的开源搜索引擎,模糊搜索,支持各种数据库,企业应用多。事实上 NodeBB 已有一个集成 Solr 的插件 nodebb-plugin-solr. 但是使用 Solr 的开销太大了,需要 Java 虚拟机,少说也要几百M内存吧。
  2. 使用Google搜索。很简单,就是跳转到 Google 使用站内搜索。V2MM 就是用的这种方案,可以亲自到 V2MM 上试试搜索功能,比如搜索 “v2mm”。

那么为什么不使用百度搜索呢? 又不会被墙,不是还更懂中文吗? Naive! 且不说他的搜索质量垃圾,对新手站长也非常不友好,https 不见得支持,.tech 这种新域名可能也不待见,见Google 与百度爬虫对本站的收录对比,瞧瞧那惨不忍睹的搜索结果! 而 Google 从第一天就收录了本站,结果非常准确,严格遵守 nofollow 标签,搜索的质量非常高,想搜什么都能搜到, 比自带的搜索引擎还要好用啊!

使用 Google 搜索的插件叫 nodebb-plugin-google-search2, 我 folk 至 BenLubar 制作的 nodebb-plugin-google-search. 修复了他关于 "filter:search.query" 这个 HOOK 的问题。插件的原理很简单,就在 "static:app.load" 的时候覆盖搜索的 API 调用,重定向到 Google 的搜索。这恐怕是 NodeBB 所有插件里最简单的一个插件,但是却很有用,如果你要学习插件开发,从这个插件着手再好不过了。插件的代码和使用方法见 Github.

搜索很难,难在哪里呢?

正如 Julian 所说,在 sql 下,简单的搜索可以用一行代码:

SELECT post_id, content FROM posts WHERE content='%term%';

问题解决了吗? 解决了一半,或许80%的用户需求都能满足,而且还简洁(simplicity),但是:

  • 搜索的复杂度高,O(n) 的搜索复杂度,如果要做逻辑查询,比如搜索 “张三” 或 “李四”,时间要翻倍, 搜索复杂度为 O(2n).
  • 当然大家都会用索引,不再直接搜索原文内容,而是搜索索引的 index, 速度会快很多,索引也会随着规模增加而线性增长,规模化(Scale)问题还是存在,只是被推迟了。

无论如何,搜索都很慢,还很占资源,所以很多网站的搜索都属于高级功能,只对高级用户开放,或者限制一秒钟甚至一分钟只能搜索一次。

我同意 Julian 的说法 ,而且索引不是一件简单的事情,MySQL 的联合索引恐怕不了解原理就难以用好,不遵循最左前缀的搜索都用不到索引,当初我就被此坑过很多回。

Mongodb 下的搜索也是类似的,除了语法有一点不同:

db.posts.find({$text:{$search:"term"}})

NodeBB 对于搜索的难题有独特的解决方法,但是貌似只作用于 Redis, 其方法待我研究之后将在第二篇公布。无论如何,V2MM 现在使用 Google 的搜索结果还是很让我满意的。