Elasticsearch学习——了解Lucene(一)

写在前面

大数据时代,Elasticsearch(以下简称 es ) 这一全文搜索引擎正在越来越广泛的被使用。es 底层基于 lucene 这一开源库。由于之前项目的业务涉及 elasticsearch,所以对 es 已经有了一部分基础的了解。特从头系统的学习一下这一开源全文搜索引擎。
es 学习系列文章大概有四部分,分别为:

  1. lucene 介绍及入门了解
  2. Elasticsearch 集群搭建、入门使用
  3. Elasticsearch 集群管理、Java API 的使用
  4. Elasticsearch 集群搜索学习、高级特性学习
  5. Elasticsearch 与 HDFS 联合使用
    本系列篇幅文章针对 lucene 版本为 Lucene 6.0.0,Elasticsearch 版本为 5.4.3。有其他新特性,请自行查阅相关项目主页。
    相关项目涉及网站链接如下:

走近 lucene

lucene 主要完成了两大任务:索引文档、搜索文档。

索引文档

索引文档过程中,由原始文档到构建 倒排索引的过程。这里着重需要介绍一下 倒排索引这一概念。

倒排索引

倒排索引,是常用的索引方法之一。其作用主要是用来存储 全文本搜索某个关键字(单词)在该文本中存储位置的映射

搜索文档

搜索文档这一任务用来处理用户查询。这一任务的主要过程如下:
用户输入查询关键词 -> 分词、匹配、评分、排序等过程 -> 返回用户想要的文档
使用 lucene 进行一次检索所需要的步骤大致是以下四步:

  1. 查询分析:对用户输入的查询约束进行分析,包括拼写纠错等处理。
  2. 分词:使用分词技术将用户输入的查询语句进行分词,分成关键词作为检索条件。
  3. 关键词检索:提交关键词(分词结果),在倒排索引库中进行匹配,并将不同关键词的检索结果文档进行与运算匹配。
  4. 搜索排序:将步骤3得到的文档进行相关度计算、排序,并将结果返回给用户。

lucene 分词及分词器相关介绍

lucene 分词及常用分词器相关介绍

分词是一个 lucene 中十分重要的过程。索引和查询都是以 关键词 作为基本单位来进行的。Lucene 提供的分词方法大体介绍如下:

  • StopAnalyzer 停用词分词器 :能过滤词汇中的特定字符串和词汇,且完成大写转小写的功能。
  • StandardAnalyzer 标准分词器:根据空格和符号来完成分词;此外还可完成数字、字母等的分析处理;同时支持过滤词表。
  • WhitespaceAnalyzer 空格分词:使用空格作为间隔符的词汇分割分词器;该分词器不做词汇过滤和大小写转换。
  • SimpleAnalyzer 简单分词:具备基本西文字符词汇分析的分词器;处理词汇单元时以非字母字符作为分割符号。
  • CJKAnalyzer 二分法分词:可以实现中文的多元切分和停用词过滤。
  • KeywordAnalyzer 关键词分词:把整个输入作为一个单独的词汇单元,主要作用是方便特殊类型的文本(邮政编码、地址等)进行索引和检索。

lucene 项目中已经有了这些分词方法的内置实现,下面一段代码便展示出了各种分词方式的特性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/**
* @description: 多种分词器测试
* @author: jayden
* @date: 2018/3/16
*/
public class MultipleAnalyzer {
/**
* 主方法,程序入口
* @param args
*/
public static void main(String[] args) {
String str = "苹果手机凭借其流畅的使用体验, 丰富的应用种类得到了全球人的认可";
//停用词分词器
System.out.println("停用词分词器:");
printAnalyzeResult(new StopAnalyzer().tokenStream(str, new StringReader(str)));
//标准分词器
System.out.println("标准分词器:");
printAnalyzeResult(new StandardAnalyzer().tokenStream(str, new StringReader(str)));
//空格分词器
System.out.println("空格分词器:");
printAnalyzeResult(new WhitespaceAnalyzer().tokenStream(str, new StringReader(str)));
//简单分词器
System.out.println("简单分词器:");
printAnalyzeResult(new SimpleAnalyzer().tokenStream(str, new StringReader(str)));
//二分法分词器
System.out.println("二分法分词器:");
printAnalyzeResult(new CJKAnalyzer().tokenStream(str, new StringReader(str)));
//关键词分词器
System.out.println("关键词分词器:");
printAnalyzeResult(new KeywordAnalyzer().tokenStream(str, new StringReader(str)));
}
/**
* 打印分词结果
* @param tokenStream 分词器对句子进行分词的结果Token流
*/
private static void printAnalyzeResult(TokenStream tokenStream) {
try {
tokenStream.reset();
CharTermAttribute termAttribute = tokenStream.getAttribute(CharTermAttribute.class);
while (tokenStream.incrementToken()) {
System.out.print(termAttribute.toString() + "/");
}
System.out.println("");
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行结果如下:
停用词分词器:
苹果手机凭借其流畅的使用体验/丰富的应用种类得到了全球人的认可/
标准分词器:
苹/果/手/机/凭/借/其/流/畅/的/使/用/体/验/丰/富/的/应/用/种/类/得/到/了/全/球/人/的/认/可/
空格分词器:
苹果手机凭借其流畅的使用体验,/丰富的应用种类得到了全球人的认可/
简单分词器:
苹果手机凭借其流畅的使用体验/丰富的应用种类得到了全球人的认可/
二分法分词器:
苹果/果手/手机/机凭/凭借/借其/其流/流畅/畅的/的使/使用/用体/体验/丰富/富的/的应/应用/用种/种类/类得/得到/到了/了全/全球/球人/人的/的认/认可/
关键词分词器:
苹果手机凭借其流畅的使用体验, 丰富的应用种类得到了全球人的认可/

IK 分词器介绍

ik-analyzer,项目主页:ik-analyzer 项目。有关项目介绍可以移步至项目主页。可以结合 lucene进行使用。

小结

本篇主要介绍了 lucene 相关概念,在同时介绍了 lucene 分词器相关知识。接下来对 lucene 入门了解的文章中,将会实际进行文档的索引、查询。
示例工程地址:lucene-es-demo
如有疑问和交流,欢迎email至 JaydenRansom@outlook.com