Skip to content

Commit 264ac85

Browse files
author
yangjingjing
committed
init blog
1 parent f43e434 commit 264ac85

File tree

44 files changed

+11882
-12
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+11882
-12
lines changed

_posts/2015-09-23-Linux下C实战.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
---
22
layout: post
3-
categories: [Linux,C]
3+
categories: [C]
44
description: none
5-
keywords: Linux,C
5+
keywords: C
66
---
77
# Linux下C编程实战
88
传统的UNIX下的程序开发语言是C语言,C语言是一种平台适应性强、易于移植的语言。

_posts/2016-04-01-Netty 简介.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
layout: post
3-
categories: Netty
3+
categories: [Netty]
44
description: none
55
keywords: Netty
66
---

_posts/2018-04-01-Lucene入门简介.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,4 +172,9 @@ Maven依赖
172172
</dependencies>
173173
```
174174

175+
## 参考资料
176+
刘超觉先的博客
175177

178+
Lucene Java DOC [https://lucene.apache.org/core/7_5_0/core/org/apache/lucene/codecs/lucene70/package-summary.html]
179+
180+
Lucene in Action [https://www.manning.com/books/lucene-in-action-second-edition]

_posts/2018-04-01-Lucene全文检索原理.md

Lines changed: 325 additions & 0 deletions
Large diffs are not rendered by default.

_posts/2018-04-02-Lucene源码分析.md

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -290,13 +290,38 @@ IndexSearcher是与IndexWriter遥相呼应的一个重要的类,方法非常
290290
- TopDocs
291291
TopDocs是一个前N个搜索结果的集合,每个结果用一个docId来标识,TopDocs可以得到几个重要的查询结果,比如,总的查询数量,查询结果对象数组以及最大评分。
292292

293-
294-
295-
296-
297-
298-
299-
293+
## Lucene组件
294+
- 被索引的文档用Document对象表示。
295+
- IndexWriter通过函数addDocument将文档添加到索引中,实现创建索引的过程。
296+
- Lucene的索引是应用反向索引。
297+
- 当用户有请求时,Query代表用户的查询语句。
298+
- IndexSearcher通过函数search搜索Lucene Index。
299+
- IndexSearcher计算term weight和score并且将结果返回给用户。
300+
- 返回给用户的文档集合用TopDocsCollector表示。
301+
302+
## 流程
303+
304+
### 索引过程如下:
305+
创建一个IndexWriter用来写索引文件,它有几个参数,INDEX_DIR就是索引文件所存放的位置,Analyzer便是用来对文档进行词法分析和语言处理的。
306+
创建一个Document代表我们要索引的文档。
307+
将不同的Field加入到文档中。我们知道,一篇文档有多种信息,如题目,作者,修改时间,内容等。不同类型的信息用不同的Field来表示,在本例子中,一共有两类信息进行了索引,一个是文件路径,一个是文件内容。其中FileReader的SRC_FILE就表示要索引的源文件。
308+
IndexWriter调用函数addDocument将索引写到索引文件夹中。
309+
310+
### 搜索过程如下:
311+
IndexReader将磁盘上的索引信息读入到内存,INDEX_DIR就是索引文件存放的位置。
312+
创建IndexSearcher准备进行搜索。
313+
创建Analyer用来对查询语句进行词法分析和语言处理。
314+
创建QueryParser用来对查询语句进行语法分析。
315+
QueryParser调用parser进行语法分析,形成查询语法树,放到Query中。
316+
IndexSearcher调用search对查询语法树Query进行搜索,得到结果TopScoreDocCollector。
317+
318+
## Lucene实现的包结构
319+
Lucene的analysis模块主要负责词法分析及语言处理而形成Term。
320+
Lucene的index模块主要负责索引的创建,里面有IndexWriter。
321+
Lucene的store模块主要负责索引的读写。
322+
Lucene的QueryParser主要负责语法分析。
323+
Lucene的search模块主要负责对索引的搜索。
324+
Lucene的similarity模块主要负责对相关性打分的实现。
300325

301326

302327

_posts/2018-04-03-Lucene源码IndexWriter.md

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,44 @@ keywords: Lucene
77
# Lucene源码IndexWriter
88
我们将深入IndexWriter内部,来探索其内核实现。
99

10+
## 创建IndexWriter对象
11+
```
12+
IndexWriter indexWriter = new IndexWriter(directory, config);
13+
```
14+
IndexWriter对象主要包含以下几方面的信息:
15+
16+
### 用于索引文档
17+
- Directory directory; 指向索引文件夹
18+
- SegmentInfos segmentInfos = new SegmentInfos(); 保存段信息,大家会发现,和segments_N中的信息几乎一一对应。
19+
- IndexFileDeleter deleter; 此对象不是用来删除文档的,而是用来管理索引文件的。
20+
- Lock writeLock; 每一个索引文件夹只能打开一个IndexWriter,所以需要锁。
21+
22+
### 用于合并段,在合并段的文章中将详细描述
23+
```
24+
// Holds all SegmentInfo instances currently involved in
25+
// merges
26+
private final HashSet<SegmentCommitInfo> mergingSegments = new HashSet<>();
27+
private final MergeScheduler mergeScheduler;
28+
private final Set<SegmentMerger> runningAddIndexesMerges = new HashSet<>();
29+
private final LinkedList<MergePolicy.OneMerge> pendingMerges = new LinkedList<>();
30+
private final Set<MergePolicy.OneMerge> runningMerges = new HashSet<>();
31+
private final List<MergePolicy.OneMerge> mergeExceptions = new ArrayList<>();
32+
private long mergeGen;
33+
private Merges merges = new Merges();
34+
```
35+
36+
### 为保持索引完整性,一致性和事务性
37+
```
38+
当IndexWriter对索引进行了添加,删除文档操作后,可以调用commit将修改提交到文件中去,也可以调用rollback取消从上次commit到此时的修改。
39+
private List<SegmentCommitInfo> rollbackSegments; // list of segmentInfo we will fallback to if the commit fails
40+
41+
private volatile SegmentInfos pendingCommit; // set when a commit is pending (after prepareCommit() & before commit())
42+
```
43+
44+
45+
46+
47+
1048
### 并发模型
1149
IndexWriter提供的核心接口都是线程安全的,并且内部做了特殊的并发优化来优化多线程写入的性能。IndexWriter内部为每个线程都会单独开辟一个空间来写入,这块空间由DocumentsWriterPerThread来控制。
1250

@@ -26,7 +64,7 @@ IndexWriter提供的核心接口都是线程安全的,并且内部做了特殊
2664
## add & update
2765
add接口用于新增文档,update接口用于更新文档。但Lucene的update和数据库的update不太一样。数据库的更新是查询后更新,Lucene的更新是查询后删除再新增,不支持更新文档内部分列。流程是先delete by term,后add document。
2866

29-
IndexWriter提供的add和update接口,都会映射到DocumentsWriter的udpate接口,看下接口定义:
67+
IndexWriter提供的add和update接口,都会映射到DocumentsWriter的update接口,看下接口定义:
3068
```
3169
long updateDocument(final Iterable<? extends IndexableField> doc, final Analyzer analyzer,
3270
final Term delTerm) throws IOException, AbortingException

_posts/2018-04-03-Lucene源码索引流程.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ IndexWriterConfig内提供了一些供高级玩家做性能调优和功能定制
4848
Lucene开放对commit point的管理,通过对commit point的管理可以实现例如snapshot等功能。Lucene默认配置的DeletionPolicy,只会保留最新的一个commit point。
4949
- Similarity
5050
搜索的核心是相关性,Similarity是相关性算法的抽象接口,Lucene默认实现了TF-IDF和BM25算法。相关性计算在数据写入和搜索时都会发生,数据写入时的相关性计算称为Index-time boosting,计算Normalizaiton并写入索引,搜索时的相关性计算称为query-time boosting。
51+
Similarity similarity = Similarity.getDefault(); 影响打分的标准化因子(normalization factor)部分,对文档的打分分两个部分,一部分是索引阶段计算的,与查询语句无关,一部分是搜索阶段计算的,与查询语句相关。
5152
- MergePolicy
5253
Lucene内部数据写入会产生很多Segment,查询时会对多个Segment查询并合并结果。所以Segment的数量一定程度上会影响查询的效率,所以需要对Segment进行合并,合并的过程就称为Merge,而何时触发Merge由MergePolicy决定。
5354
- MergeScheduler
@@ -394,8 +395,8 @@ IndexWriter::updateDocuments->DocumentsWriter::updateDocuments
394395
return postUpdate(flushingDWPT, hasEvents);
395396
}
396397
```
397-
398398
updateDocuments首先调用preUpdate函数处理没有写入硬盘的数据,代码如下。
399+
399400
IndexWriter::updateDocuments->DocumentsWriter::updateDocuments->preUpdate
400401
```
401402
private boolean preUpdate() throws IOException, AbortingException {
@@ -418,6 +419,7 @@ IndexWriter::updateDocuments->DocumentsWriter::updateDocuments->preUpdate
418419
flushControl是在DocumentsWriter构造函数中创建的DocumentsWriterFlushControl。preUpdate函数从DocumentsWriterFlushControl中逐个取出DocumentsWriterPerThread,因为在lucene中只能有一个IndexWriter获得文件锁并操作索引文件,但是实际中对文档的索引需要多线程进行,DocumentsWriterPerThread就代表一个索引文档的线程。获取到DocumentsWriterPerThread之后,就通过doFlush将DocumentsWriterPerThread内存中的索引数据写入硬盘文件里。关于doFlush函数的分析,留在后面的章节。
419420

420421
回到DocumentsWriter的updateDocuments函数中,接下来通过DocumentsWriterFlushControl的obtainAndLock函数获得一个DocumentsWriterPerThread,DocumentsWriterPerThread被封装在ThreadState中,obtainAndLock函数的代码如下,
422+
421423
IndexWriter::updateDocuments->DocumentsWriter::updateDocuments->DocumentsWriterFlushControl::obtainAndLock
422424
```
423425
ThreadState obtainAndLock() {
@@ -534,6 +536,7 @@ DocumentsWriterPerThread的updateDocuments函数首先调用reserveOneDoc查看
534536

535537
DefaultIndexingChain的processDocument函数
536538
DefaultIndexingChain是一个默认的索引处理链,下面来看它的processDocument函数。
539+
537540
IndexWriter::updateDocuments->DocumentsWriter::updateDocuments->DocumentsWriterPerThread::updateDocuments->DefaultIndexingChain::processDocument
538541
```
539542
public void processDocument() throws IOException, AbortingException {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
layout: post
3+
categories: [Lucene]
4+
description: none
5+
keywords: Lucene
6+
---
7+
# Lucene源码索引文件Terms
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
layout: post
3+
categories: [Lucene]
4+
description: none
5+
keywords: Lucene
6+
---
7+
# Lucene源码索引文件Document
8+
9+
## 创建文档Document对象,并加入域(Field)
10+
```
11+
Document doc = new Document();
12+
doc.add(new Field("title", text, TextField.TYPE_STORED));
13+
```
14+
Document对象主要包括以下部分:
15+
- 一个ArrayList保存此文档所有的域
16+
- 每一个域包括域名,域值,和一些标志位,和fnm,fdx,fdt中的描述相对应。
17+
18+
## Filed
19+
字段,一个Document会由一个或多个Field组成,数据库中可以对应一列,当然一列可以有多个field,每个Field有其对应的属性。比如 - 全文对应的TextField - 文本对应的StringField - 数值类型int对应的IntPoint,long对应的longPoint等等。且可以根据属性定制Field。较早版本中数值类型都是一种Field,而使用BKD-Tree之后,不同类型数值 分别对应一种Field,如IntPoint,对应为点的概念。
20+
21+
往document添加field,field有很多选项,是否分词是否添加存储等,根据实际情况选择。
22+
23+
## Field.Store.*
24+
Field类是文档索引期间很重要的类,控制着被索引的域值。Field.Store.* 域存储选项通过倒排序索引来控制文本是否可以搜索
25+
```
26+
Field.Store.YES//表示会把这个域中的内容完全存储到文件中,方便进行还原[对于主键,标题可以是这种方式存储]
27+
Field.Store.NO//表示把这个域的内容不存储到文件中,但是可以被索引,此时内容无法完全还原(doc.get())[对于内容而言,没有必要进行存储,可以设置为No]
28+
```

0 commit comments

Comments
 (0)