# 信息检索

## 前言

<em>碰到问题，记住第一件事是 **翻阅文档** ，不要一开始就直接搜索或者找人问，翻阅FAQ可能会快速找到答案。</em>

信息检索，我的理解来说，实际上就是灵活运用搜索引擎中，方便快捷的搜到需要的信息，包括但不限于编程。

编程最重要的，就是 STFW(search the fucking web) 和 RTFM(read the fucking Manual) ，首先要读文档，第二要学会搜索，网上那么多资源，怎么用，就需要信息检索。

要搜索，我们首先要搞清楚搜索引擎是如何工作的：

## 搜索引擎工作原理

搜索引擎的工作过程大体可以分成三阶段：[^1]

1. 爬行和抓取：搜索引擎蜘蛛通过跟踪链接访问网页，获取网页 HTML 代码存入数据库。
1. 预处理：索引程序对抓取来的网页数据进行文字提取，中文分词，索引等处理，以备排名程序调用。
1. 排名：用户输入关键词后，排名程序调用索引库数据，计算相关性，然后按一定格式生成搜索结果页面。

第一步，就是大家经常听说的网络爬虫，一般 Python 卖课的都会吹这个东西。简单可以理解为，我用一个自动的程序，下载网站中的所有文本、图片等相关信息，然后存入本地的磁盘。

第二步是搜索引擎的核心，但是对于我们使用来说，并不是特别关键，大致可以理解为洗干净数据，然后入库页面，每个页面加入关键字等信息方便我们查询。

第三步跟我们息息相关，不管是什么搜索网站， google 、百度、 Bing ，都一样，输入关键字或者需要查询的内容，搜索引擎会给你返回结果。本文就是教你如何获取更好的结果。

## 基础搜索技巧

根据上述的工作原理，我们大致就能明白，其实可以把搜索引擎当作一个比较聪明的数据库，更好的使用查询条件就能更快速的找到你想要的信息，下面介绍一些搜索的技巧：

### 使用英文

首先我们要知道一件事，编程中，最好使用英文搜索。原因主要有几点：

1. 编程和各种软件操作中，英文资料质量比中文资料和其他语言资料高，英文通用性还是更好些
2. 因为翻译问题，英文的名词比中文准确通用
3. 中文搜索中，分词系统不准会导致歧义，比如 Google 搜中文可能会搜不出几条有用结果

如果你英文不好，用百度翻译或者搜狗翻译，足够了。

当然下面的文档为了举例方便，都还是用中文例子。

### 提炼关键词

搜索时不要搜索整句话，虽然搜索引擎会自动帮助我们分词检索，但是整句和关键字搜索出来的结果再准确度和顺序上会有很大差别。搜索引擎是机器，并不是你的老师或者同事，看上面的流程，搜索实际上是去检索搜索引擎爬出来的数据库，你可以理解为关键字比模糊检索要快而且准确。

我们需要提炼问题，确定我们到底需要解决什么问题。

例如，我想知道 vcpkg 如何集成到工程上而不是全局中，那么搜索 `vcpkg如何集成到工程上而不是全局中`  这种长句可能无法找到相关的结果，最好是拆分成单词，`vcpkg 集成到 工程 全局`  这样的搜索。其实这里只是举个例子，针对本条其实都能搜索出相关信息，但是越具体的问题，机器分词越可能出问题，所以最好是拆分关键字，使用词组或者断句来进行搜索。

### 替换关键字

还是上面那个例子，如果搜不出来，可以试试把工程换成项目，或者移出集成，如果不行，试一下高级搜索。

### 高级搜索

普通搜索引擎一般都支持高级搜索，包括 google ， bing ，百度， ecosia ，等等，大部分都支持，不过可能语法不同，一般通用的表示：

* 精准匹配： 精准匹配能保证搜索关键词完全被匹配上，一般是用双引号括起来
  * 比如搜索线性代数，可以在输入框内输入 "线性代数"，搜索引擎将只匹配完整包含 “线性代数” 的页面，而不会搜索拆分成线性和代数两个词的页面
* 不包含关键字： 用 -  减号连接关键字，用于排除某些干扰词
* 包含关键字：  用 + 加号连接关键字
* 搜索特定文件类型：  `filetype:pdf` 直接搜索 pdf 文件
* 搜索特定网址： `site:stackoverflow.com` 只搜索特定网站内的页面

一般可以参照网站说明，比如百度可以参照 [高级搜索](https://baike.baidu.com/item/高级搜索/1743887?fr=aladdin) ，Bing 可以参照 [高级搜索关键字](https://help.bing.microsoft.com/#apex/bing/zh-CHS/10001/-1) 和 [高级搜索选项](https://help.bing.microsoft.com/apex/index/18/zh-CHS/10002)。


#### GitHub 的高级搜索

可以直接用 [高级搜索页面](https://github.com/search/advanced) 进行搜索，也可以参照 [Github查询语法](https://zhuanlan.zhihu.com/p/273766377) 进行查找，简单说几个:

* `in:name <关键字>` 仓库名称带关键字查询
* `in:description <关键字>` 仓库描述带关键字查询
* `in:readme <关键字>` README 文件带关键字查询
* `stars(fork): >(=) <数字> <关键字>` star 或 fork 数大于(或等于)指定数字的带关键字查询
* `stars(fork): 10..20 <关键词>` star 或 fork 数在 10 到 20 之间的带关键字查询
* `size:>=5000 <关键词>` 限定仓库大于等于 5000K 的带关键字查询
* `pushed(created):>2019-11-15 <关键字>` 更新 或 创建 日期在 2019 年 11 月 16 日之后的带关键字查询
* `license:apache-2.0 <关键字>` LICENSE 为 apache-2.0 的带关键字查询
* `language:java <关键词>` 仓库语言为 Java 的带关键字查询
* `user:<用户名>` 查询某个用户的项目
* `org:<组织名>` 查询某个组织的项目
  这些可以混合使用，也可以先查找某一类的 awesome 仓库，然后从 awesome 库里找相关的资源，github 里有很多归纳仓库，可以先看看已有的收集，有时候会节省很多时间

### 更多技巧

使用中，实际上我会去特定网站找一些问题：

* 如果是语言本身相关，比如 c++/Qt/OpenGL 如何实现什么功能，可以直接加上 `site:stackoverflow.com`
* 如果是具体的业务/开发环境或者软件相关，可以先在 BugList 、IssueList ，或者相关论坛里先找一下，比如 Qt 的问题就可以直接去 Qt 论坛，QGis 或者 GDAL 相关问题可以在 stackExchange 里去搜
* QQ 群也是一个提问的地方，但是需要你提的问题有意义，否则大部分人不会回你，而且 QQ 群回复并不及时。
* 知乎专栏、简书、博客园、 CSDN 中有大量中文笔记，这些都是别人嚼烂了的东西，基本是别人踩坑的经验

### 关于百度

大部分编程人都会告诉你别用百度，用 Google 或者 Bing 国际版，但是 Bing 中文搜索的准确率并不高， Google 需要科学上网，如果真的需要，可以使用 Ecosia 、 Yandex 之类的搜索引擎。而且中文搜索来说，百度可能还真是最好的。

百度的问题主要在于排序算法，可能两页都没啥对的内容，但是收录比 Bing 还是好一些的（百度以前并不遵守 robots.txt ，会抓取所有页面，所以有些个人网站甚至专门对百度做了屏蔽），甚至有时候比 Google 好。从数据库来说，百度比 Google 和 Bing 收录的中文内容要多，如果你碰到的时中文相关的问题而且确实找不到相关内容，那么就用百度，搜索引擎是工具，能用好用才是王道。

## 代码搜索

我们除了搜索引擎查找问题，还有可能会搜一些代码，可能是自己写的，也可能是项目中的，下面推荐一些工具：

代码检索有两种，第一是本地的代码检索，第二是要写个啥算法，需要在网上搜索

### 本地代码搜索

* ACK 或者 ACK2，老牌搜索工具，perl 写的
* The Silver Searcher c 实现的
* The Platinum Searcher go 实现的
* FreeCommander 自带的搜索，如果是固态硬盘速度还不错
* IDE 自带的，搜索有些时候并不太好用

### 开源代码搜索

* [Searchcode](https://searchcode.com) 搜索开源代码，速度比较快
* [一行代码](https://www.alinecode.com) 国产的，有些国产工具很好用



[^ 1]: [搜索引擎工作原理简介 - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/301641935)