0

搜索是怎么回事——Lucene

 2 years ago
source link: https://zhuanlan.zhihu.com/p/433645014
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

搜索最主要的解决下面的两个问题——

  • 跟查询比配的文档是哪些?
  • 比配的文档顺序什么,哪一个应该排在最前面,哪一个排在后面?

并且以高效的方式来解决这两个问题。

如果你花个一个小时来解决这个问题,估计就没什么人喜欢用你的搜索功能了。

很多人听过Solor或Elastic Search,而它们建立在Lucene的基础上。所以本系列文章探索探索这个基础的原理和实现。

接下来分几篇文章讲讲搜索的原理,主要围绕Lucene 搜索库源码,可能的话去看看Lucene对应的Rust实现。

网上已经有许多文章介绍搜索和Lucene,我写这些文章主要是使用可以运行和调试的例子,用来加深自己对Lucene的理解。

(目前写了两个系列,一、CrackingOysters:如何debug crash 系列, 二、Rust 系列:正确编程的思考模型)

Talk is cheap, let's start with code.

debug Lucene的开发环境

我有时候喜欢以调试的方式去研究源码,这样可以专注某一块,而且看着代码运行,更有感觉。

所以要先搭建一个可以debug Lucene代码的环境。后续代码会上传到这个github repo

使用的工具是Docker + VSCode + Lucene 8.10 版本 + Java 11.

这个开发环境是根据CrackingOysters:被VSCode圈粉了!创建Ubuntu bionic的image

注意:这个脚本安装的Java是带源码和debug symbol,这样有兴趣的时候还可以debug JVM看看(我有一篇debug Java jhsdb来调试JVM的core dump的文章在草稿箱中)

通过VScode进入container以后,我们就可以开始按F5 debug了,

比如下面这个简单的代码,

public class App {
    public static void main(String[] args) throws Exception {
        System.out.println("Hello, World!");

		Searcher searcher = new Searcher();
		searcher.AddDocuments();
		searcher.Search();
		//searcher.Query();
       // testAnalyzer();
    }
}

我们可以一步一步的调试代码,下面是Field Type设置的调用栈,

下面是score计算的调用栈

如果你希望修改Lucene的源码,可以通过下面的命令来编译生成Lucene的jar,

ant jar 
ant jar-src 

High Level的概念梳理

正如前言所说,搜索要高效地解决那两个问题,那么背后是什么数据结构和算法支撑呢?

这里简短地,以通俗地语言梳理一下,更详细和准确地讲解后续再结合代码补充。

以Lucene为例,一个文档会不会匹配是看这个文档有没有我们要搜索的字符,而Lucene将这个字符的概念进行了更详细和细致的定义。

这个定义就是term。

一个文档会不会匹配,是看它没有我们要搜索的terms。我们搜索的字符串会被当成一个term或者拆分成好多个terms。

当我们添加一个文档的时候,Lucene会先把文档变成好多个terms,然后标记这些terms存在这个文档中。

这个就是我们常说的inverted index(倒排索引)。(我们这里会假设这个文档只有一个field,field后续会提)。

terms,决定了文档是否匹配,解决了第一个问题。第二个问题,哪个文档排在前面,又是怎么实现的呢?

Lucene的方法是,根据某个算法对每个文档计算一个匹配值,匹配值高的排在前面。

算法我们后续会再详细地分析。

后续也会涉及排序怎么排,boost field怎么boost,模糊匹配是怎么模糊匹配,高亮的实现,删除一个文档的具体过程等等。

这是第一篇,后续文章会慢慢整理发出,每篇文章会经过多次整理,修正一些错误(我可以预料到随着学习的深入,一开始可能会有理解不到位的地方),并整理发布到我自己的号里。

What is term vector in Lucene

https://archive.apache.org/dist/lucene/java/8.10.0/lucene-8.10.0-src.tgz


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK